From 32e87cfdb5e44a2e4e5f3f1dea86cf00d06cc245 Mon Sep 17 00:00:00 2001 From: gitea Date: Tue, 18 Nov 2025 21:53:33 +0000 Subject: [PATCH] Initial commit --- .gitignore | 46 + README.md | 71 + backend/Dockerfile | 25 + backend/Dockerfile.celery | 20 + backend/accounts/__init__.py | 0 backend/accounts/admin.py | 34 + backend/accounts/apps.py | 6 + backend/accounts/emails.py | 81 + backend/accounts/migrations/0001_initial.py | 45 + .../migrations/0002_customuser_role.py | 18 + backend/accounts/migrations/__init__.py | 0 backend/accounts/models.py | 19 + backend/accounts/serializers.py | 59 + backend/accounts/tests.py | 3 + backend/accounts/views.py | 5 + backend/api/__init__.py | 0 backend/api/admin.py | 3 + backend/api/apps.py | 6 + backend/api/migrations/0001_initial.py | 36 + backend/api/migrations/__init__.py | 0 backend/api/models.py | 26 + backend/api/serializers/__init__.py | 0 backend/api/serializers/audit_serializer.py | 17 + backend/api/services/__init__.py | 0 backend/api/services/health_service.py | 102 + backend/api/tests.py | 3 + backend/api/views.py | 3 + backend/api/views/__init__.py | 0 backend/api/views/audit_viewset.py | 62 + backend/api/views/health_check_view.py | 36 + backend/core/__init__.py | 0 backend/core/asgi.py | 16 + backend/core/celery.py | 16 + backend/core/settings.py | 354 + backend/core/spectacular_hooks.py | 13 + backend/core/urls.py | 64 + backend/core/wsgi.py | 16 + backend/create_db.py | 34 + backend/docker-entrypoint.sh | 51 + backend/manage.py | 22 + backend/permissions/__init__.py | 0 backend/permissions/admin.py | 3 + backend/permissions/apps.py | 6 + backend/permissions/migrations/__init__.py | 0 backend/permissions/models.py | 3 + backend/permissions/permission_classes.py | 56 + backend/permissions/tests.py | 3 + backend/permissions/views.py | 3 + backend/requirements.txt | 19 + backend/user_profile/__init__.py | 0 backend/user_profile/admin.py | 3 + backend/user_profile/apps.py | 6 + backend/user_profile/migrations/__init__.py | 0 backend/user_profile/models.py | 3 + backend/user_profile/tests.py | 3 + backend/user_profile/views.py | 3 + infra/docker-compose.yml | 157 + mobile/.gitignore | 41 + mobile/App.js | 20 + mobile/app.json | 29 + mobile/assets/adaptive-icon.png | Bin 0 -> 17547 bytes mobile/assets/favicon.png | Bin 0 -> 1466 bytes mobile/assets/icon.png | Bin 0 -> 22380 bytes mobile/assets/splash-icon.png | Bin 0 -> 17547 bytes mobile/index.js | 8 + mobile/package-lock.json | 9308 +++++++++++++++++ mobile/package.json | 20 + web/.gitignore | 24 + web/README.md | 109 + web/eslint.config.js | 29 + web/index.html | 13 + web/package-lock.json | 3984 +++++++ web/package.json | 42 + web/public/favicon-32x32.svg | 16 + web/public/intro.png | Bin 0 -> 189330 bytes web/public/logo192.png | Bin 0 -> 8260 bytes web/public/vite.svg | 1 + web/src/App.jsx | 23 + web/src/app/store.js | 25 + web/src/assets/react.svg | 1 + web/src/components/ConfirmModal.jsx | 50 + web/src/components/ErrorText.jsx | 17 + web/src/components/FileUploadAndSubmit.jsx | 34 + web/src/components/Health/InfraStatusCard.jsx | 36 + .../components/Health/ModelEndpointList.jsx | 34 + web/src/components/InputText.jsx | 28 + web/src/components/LandingIntro.jsx | 31 + web/src/components/LoginForm.jsx | 139 + web/src/components/ModalForm.jsx | 189 + .../components/ModelRegistry/ModelTable.jsx | 92 + .../components/ModelRegistry/ModelTopBar.jsx | 26 + web/src/components/ModelSelector.jsx | 28 + .../PasswordReset/ResetInfoCard.jsx | 47 + .../PasswordReset/ResetPasswordForm.jsx | 63 + .../components/Profile/PasswordChangeForm.jsx | 78 + .../components/Profile/ProfileEditForm.jsx | 52 + .../Registration/RegisterInfoCard.jsx | 37 + web/src/components/ResultDisplay.jsx | 25 + web/src/components/SelectInput.jsx | 48 + web/src/components/ServiceStatus.jsx | 47 + web/src/components/SidebarSubmenu.jsx | 87 + web/src/components/Subtitle.jsx | 12 + web/src/components/TemplatePointers.jsx | 34 + web/src/components/TitleCard.jsx | 33 + web/src/components/ToastNotification.jsx | 137 + web/src/config/sidebarRoutes.jsx | 57 + web/src/features/auth/authSlice.js | 79 + web/src/features/toast/toastSlice.js | 31 + web/src/index.css | 4 + web/src/layouts/AuthLayout.jsx | 16 + web/src/layouts/MainLayout.jsx | 176 + web/src/main.jsx | 22 + web/src/pages/BlankPage.jsx | 41 + web/src/pages/Dashboard.jsx | 144 + web/src/pages/Profile.jsx | 37 + web/src/pages/auth/ForgotPasswordPage.jsx | 93 + web/src/pages/auth/RegisterPage.jsx | 83 + web/src/pages/auth/ResetConfirmPage.jsx | 49 + web/src/pages/data/InferenceRun.jsx | 64 + web/src/pages/data/ModelRegistry.jsx | 29 + web/src/pages/system/Health.jsx | 52 + web/src/pages/system/UserGuide.jsx | 77 + web/src/routes/AuthRoutes.jsx | 27 + web/src/routes/PrivateRoutes.jsx | 30 + web/src/routes/ProtectedRoute.jsx | 17 + web/src/routes/pageRoutes.jsx | 52 + web/src/schemas/authSchema.js | 42 + web/src/schemas/modelSchema.js | 11 + web/src/services/auditApi.js | 21 + web/src/services/authApi.js | 340 + web/src/services/axiosClient.js | 107 + web/src/services/healthApi.js | 35 + web/src/services/inferenceApi.js | 38 + web/src/styles.css | 5 + web/vite.config.js | 8 + 135 files changed, 18464 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 backend/Dockerfile create mode 100644 backend/Dockerfile.celery create mode 100644 backend/accounts/__init__.py create mode 100644 backend/accounts/admin.py create mode 100644 backend/accounts/apps.py create mode 100644 backend/accounts/emails.py create mode 100644 backend/accounts/migrations/0001_initial.py create mode 100644 backend/accounts/migrations/0002_customuser_role.py create mode 100644 backend/accounts/migrations/__init__.py create mode 100644 backend/accounts/models.py create mode 100644 backend/accounts/serializers.py create mode 100644 backend/accounts/tests.py create mode 100644 backend/accounts/views.py create mode 100644 backend/api/__init__.py create mode 100644 backend/api/admin.py create mode 100644 backend/api/apps.py create mode 100644 backend/api/migrations/0001_initial.py create mode 100644 backend/api/migrations/__init__.py create mode 100644 backend/api/models.py create mode 100644 backend/api/serializers/__init__.py create mode 100644 backend/api/serializers/audit_serializer.py create mode 100644 backend/api/services/__init__.py create mode 100644 backend/api/services/health_service.py create mode 100644 backend/api/tests.py create mode 100644 backend/api/views.py create mode 100644 backend/api/views/__init__.py create mode 100644 backend/api/views/audit_viewset.py create mode 100644 backend/api/views/health_check_view.py create mode 100644 backend/core/__init__.py create mode 100644 backend/core/asgi.py create mode 100644 backend/core/celery.py create mode 100644 backend/core/settings.py create mode 100644 backend/core/spectacular_hooks.py create mode 100644 backend/core/urls.py create mode 100644 backend/core/wsgi.py create mode 100644 backend/create_db.py create mode 100644 backend/docker-entrypoint.sh create mode 100644 backend/manage.py create mode 100644 backend/permissions/__init__.py create mode 100644 backend/permissions/admin.py create mode 100644 backend/permissions/apps.py create mode 100644 backend/permissions/migrations/__init__.py create mode 100644 backend/permissions/models.py create mode 100644 backend/permissions/permission_classes.py create mode 100644 backend/permissions/tests.py create mode 100644 backend/permissions/views.py create mode 100644 backend/requirements.txt create mode 100644 backend/user_profile/__init__.py create mode 100644 backend/user_profile/admin.py create mode 100644 backend/user_profile/apps.py create mode 100644 backend/user_profile/migrations/__init__.py create mode 100644 backend/user_profile/models.py create mode 100644 backend/user_profile/tests.py create mode 100644 backend/user_profile/views.py create mode 100644 infra/docker-compose.yml create mode 100644 mobile/.gitignore create mode 100644 mobile/App.js create mode 100644 mobile/app.json create mode 100644 mobile/assets/adaptive-icon.png create mode 100644 mobile/assets/favicon.png create mode 100644 mobile/assets/icon.png create mode 100644 mobile/assets/splash-icon.png create mode 100644 mobile/index.js create mode 100644 mobile/package-lock.json create mode 100644 mobile/package.json create mode 100644 web/.gitignore create mode 100644 web/README.md create mode 100644 web/eslint.config.js create mode 100644 web/index.html create mode 100644 web/package-lock.json create mode 100644 web/package.json create mode 100644 web/public/favicon-32x32.svg create mode 100644 web/public/intro.png create mode 100644 web/public/logo192.png create mode 100644 web/public/vite.svg create mode 100644 web/src/App.jsx create mode 100644 web/src/app/store.js create mode 100644 web/src/assets/react.svg create mode 100644 web/src/components/ConfirmModal.jsx create mode 100644 web/src/components/ErrorText.jsx create mode 100644 web/src/components/FileUploadAndSubmit.jsx create mode 100644 web/src/components/Health/InfraStatusCard.jsx create mode 100644 web/src/components/Health/ModelEndpointList.jsx create mode 100644 web/src/components/InputText.jsx create mode 100644 web/src/components/LandingIntro.jsx create mode 100644 web/src/components/LoginForm.jsx create mode 100644 web/src/components/ModalForm.jsx create mode 100644 web/src/components/ModelRegistry/ModelTable.jsx create mode 100644 web/src/components/ModelRegistry/ModelTopBar.jsx create mode 100644 web/src/components/ModelSelector.jsx create mode 100644 web/src/components/PasswordReset/ResetInfoCard.jsx create mode 100644 web/src/components/PasswordReset/ResetPasswordForm.jsx create mode 100644 web/src/components/Profile/PasswordChangeForm.jsx create mode 100644 web/src/components/Profile/ProfileEditForm.jsx create mode 100644 web/src/components/Registration/RegisterInfoCard.jsx create mode 100644 web/src/components/ResultDisplay.jsx create mode 100644 web/src/components/SelectInput.jsx create mode 100644 web/src/components/ServiceStatus.jsx create mode 100644 web/src/components/SidebarSubmenu.jsx create mode 100644 web/src/components/Subtitle.jsx create mode 100644 web/src/components/TemplatePointers.jsx create mode 100644 web/src/components/TitleCard.jsx create mode 100644 web/src/components/ToastNotification.jsx create mode 100644 web/src/config/sidebarRoutes.jsx create mode 100644 web/src/features/auth/authSlice.js create mode 100644 web/src/features/toast/toastSlice.js create mode 100644 web/src/index.css create mode 100644 web/src/layouts/AuthLayout.jsx create mode 100644 web/src/layouts/MainLayout.jsx create mode 100644 web/src/main.jsx create mode 100644 web/src/pages/BlankPage.jsx create mode 100644 web/src/pages/Dashboard.jsx create mode 100644 web/src/pages/Profile.jsx create mode 100644 web/src/pages/auth/ForgotPasswordPage.jsx create mode 100644 web/src/pages/auth/RegisterPage.jsx create mode 100644 web/src/pages/auth/ResetConfirmPage.jsx create mode 100644 web/src/pages/data/InferenceRun.jsx create mode 100644 web/src/pages/data/ModelRegistry.jsx create mode 100644 web/src/pages/system/Health.jsx create mode 100644 web/src/pages/system/UserGuide.jsx create mode 100644 web/src/routes/AuthRoutes.jsx create mode 100644 web/src/routes/PrivateRoutes.jsx create mode 100644 web/src/routes/ProtectedRoute.jsx create mode 100644 web/src/routes/pageRoutes.jsx create mode 100644 web/src/schemas/authSchema.js create mode 100644 web/src/schemas/modelSchema.js create mode 100644 web/src/services/auditApi.js create mode 100644 web/src/services/authApi.js create mode 100644 web/src/services/axiosClient.js create mode 100644 web/src/services/healthApi.js create mode 100644 web/src/services/inferenceApi.js create mode 100644 web/src/styles.css create mode 100644 web/vite.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0f64979 --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# ======================================================= +# 1. PYTHON / DJANGO BACKEND +# ======================================================= +# Virtual Environments (ไม่ว่าจะชื่อ venv, env, หรือ .venv) +*venv/ +*.env +env/ +.venv/ + +# Python Cache +__pycache__/ +*.pyc +*.pyd +*.pyo + +# Django & Database Files +/backend/*.sqlite3 +/backend/staticfiles/ +/backend/media/ +/backend/local_settings.py + +# ======================================================= +# 2. NODE.JS / REACT FRONTEND (Web & Mobile) +# ======================================================= +/web/node_modules/ +/mobile/node_modules/ +/web/dist/ # Build output for web (Vite) +/mobile/.expo/ # Expo cache files +/mobile/web-build/ # Expo web build output +/mobile/android/ # Native build folder +/mobile/ios/ # Native build folder + +# IDE Files (IntelliJ / VS Code) +.idea/ # IntelliJ/WebStorm specific folder +.vscode/ + +# ======================================================= +# 3. DOCKER / INFRASTRUCTURE +# ======================================================= +# ห้าม Commit Volumes และ Secrets +# Docker Volumes ถูกสร้างขึ้นในโฟลเดอร์นี้ +/infra/volumes/ +*.log + +# Secrets (ถ้าใช้ไฟล์ .env ในอนาคต) +.env \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..9c916d6 --- /dev/null +++ b/README.md @@ -0,0 +1,71 @@ +# 🏗️ Monorepo Web App Starter Template Version 1.0 +**Version 1.0.0 — Internal Use Only** + +Template นี้ถูกออกแบบมาเพื่อเป็นพื้นฐาน (Boilerplate) สำหรับทุกโปรเจกต์ในองค์กร +ช่วยลดเวลา Setup, เพิ่มมาตรฐาน และรองรับการขยายระบบในระยะยาว + +--- + +## 🎯 เป้าหมายของ Template นี้ + +โปรเจกต์นี้เป็น **Monorepo Web App Starter Template** ที่มีฟีเจอร์พื้นฐานครบพร้อมใช้งาน ได้แก่: + +✔ Authentication + JWT + Refresh Token +✔ Remember-Me Token Logic +✔ Celery Task Queue + Redis Broker +✔ API Gateway (Django DRF) +✔ React (Vite) + TanStack Query + Redux Toolkit +✔ Docker Compose (Minio + Celery + Flower + Redis + CockroachDB) + +สามารถ Clone เพื่อสร้างโปรเจกต์ใหม่ได้ทันทีผ่าน Gitea *Make this Template* + +--- + +## 🚀 เหตุผลที่องค์กรควรใช้ Template นี้ + +### 1️⃣ ลดเวลาในการ Setup (Time to Market) +ไม่ต้องติดตั้งซ้ำทุกครั้ง เช่น: + +- Django + JWT + Djoser +- Token Refresh + Remember-Me Logic +- Celery Worker + Redis Queue +- Vite + React + TanStack Query +- Docker Compose รองรับ Backend/Frontend/Database + +โคลนแล้วเริ่มพัฒนาได้ทันที! + +--- + +### 2️⃣ มาตรฐานเดียวกันทั้งองค์กร (Standardization) +Template นี้รวม Best Practices เช่น: + +- DRF Custom Permission, Auth Middleware +- React Service Layer + Axios Interceptors +- Redux Slice สำหรับ Auth +- Database Structure มาตรฐาน +- Docker Directory Structure + +ทำให้ทุกทีมโค้ดไปในทิศทางเดียวกัน + +--- + +### 3️⃣ ผ่านการทดสอบมาแล้ว (Quality & Stability) +Template นี้ถูกสร้างจากโปรเจกต์จริง +แก้ปัญหาเช่น: + +- Connection Refused (Celery) +- Token Refresh ไม่ทำงาน +- CORS/CSRF ปัญหาใน Dev +- Docker Volume Lost + +จึงมั่นใจได้ว่าใช้แล้วเสถียร + +--- + +### 4️⃣ ง่ายในการบำรุงรักษา (Maintenance Friendly) +เมื่อมีการอัปเดต security หรือ dependency เวอร์ชันใหม่: + +- ทีมสามารถ Pull จาก Template +- หรือ Sync ผ่าน Git Subtree/Gitea Mirror + +ช่วยลด Tech Debt ระยะยาว \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..58b02e9 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,25 @@ +# 1. BASE IMAGE +FROM python:3.11-slim +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONUNBUFFERED 1 # เพื่อให้ Log แสดงผลทันที + +# 2. WORK DIRECTORY +WORKDIR /app + +# 3. DEPENDENCIES: Copy และติดตั้ง (ใช้ประโยชน์จาก Docker Layer Caching) +COPY requirements.txt /app/ +RUN pip install --no-cache-dir -r requirements.txt + +# 4. ENTRYPOINT SCRIPT: Copy และกำหนดสิทธิ์รัน (ใช้สำหรับ Startup Automation) +COPY docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh + +# 5. CODE: คัดลอกโค้ดโปรเจกต์ที่เหลือทั้งหมดมาไว้ใน /app +COPY . /app/ + +# 6. EXPOSE: +EXPOSE 8000 + +# 7. ENTRYPOINT/CMD: กำหนด Entrypoint หลัก +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] \ No newline at end of file diff --git a/backend/Dockerfile.celery b/backend/Dockerfile.celery new file mode 100644 index 0000000..9f50a5d --- /dev/null +++ b/backend/Dockerfile.celery @@ -0,0 +1,20 @@ +FROM python:3.11-slim + +WORKDIR /app + +# Install system dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + gcc \ + libpq-dev \ + libffi-dev \ + libjpeg62-turbo-dev \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +CMD ["celery", "-A", "core", "worker", "-l", "info"] diff --git a/backend/accounts/__init__.py b/backend/accounts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/accounts/admin.py b/backend/accounts/admin.py new file mode 100644 index 0000000..0e23c57 --- /dev/null +++ b/backend/accounts/admin.py @@ -0,0 +1,34 @@ +# users/admin.py + +from django.contrib import admin +from django.contrib.auth.admin import UserAdmin as BaseUserAdmin # เปลี่ยนชื่อเป็น BaseUserAdmin เพื่อป้องกันการซ้ำซ้อน +from .models import CustomUser + +# สร้าง Custom User Admin เพื่อจัดการฟิลด์เพิ่มเติม +class CustomUserAdmin(BaseUserAdmin): + # 1. กำหนดฟิลด์ที่จะแสดงในหน้าลิสต์ผู้ใช้ + list_display = ( + 'username', + 'email', + 'first_name', + 'last_name', + 'is_staff', + 'is_superuser', + 'role' + ) + + # 2. กำหนดโครงสร้างและการจัดกลุ่มฟิลด์ในหน้าแก้ไขผู้ใช้ + fieldsets = ( + (None, {'fields': ('username', 'password')}), + ('Personal info', {'fields': ('first_name', 'last_name', 'email', 'phone_number')}), # 🔑 เพิ่ม phone_number + ('Role and Permissions', { # สร้างกลุ่มใหม่เพื่อจัดระเบียบ + 'fields': ('role', 'is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'), + }), + ('Important dates', {'fields': ('last_login', 'date_joined')}), + ) + + # 3. กำหนดฟิลด์ที่ใช้ในการค้นหาในหน้าลิสต์ผู้ใช้ + search_fields = ('username', 'email', 'phone_number') + +# ลงทะเบียน CustomUser ด้วย CustomUserAdmin ที่ถูกปรับแต่ง +admin.site.register(CustomUser, CustomUserAdmin) \ No newline at end of file diff --git a/backend/accounts/apps.py b/backend/accounts/apps.py new file mode 100644 index 0000000..3e3c765 --- /dev/null +++ b/backend/accounts/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class AccountsConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'accounts' diff --git a/backend/accounts/emails.py b/backend/accounts/emails.py new file mode 100644 index 0000000..9f2142e --- /dev/null +++ b/backend/accounts/emails.py @@ -0,0 +1,81 @@ +from djoser import email +from django.conf import settings +from django.core.mail import EmailMultiAlternatives + +class CustomPasswordResetEmail(email.PasswordResetEmail): + + template_name = None + + def render(self, context=None): + + context = self.get_context_data() + url = context['url'] + user = context['user'] + + self.html_content = self.create_email_html(url, user) + self.plain_content = self.create_email_plain(url, user) + + def get_context_data(self): + return super().get_context_data() + + def get_subject(self): + """ + subject ถูกสร้างโดย Djoser ใน context['subject'] + """ + context = self.get_context_data() + return context.get("subject", "Password Reset") + + def send(self, to, *args, **kwargs): + + self.render() + + msg = EmailMultiAlternatives( + subject=self.get_subject(), + body=self.plain_content, + from_email=self.from_email, + to=to + ) + if self.html_content: + msg.attach_alternative(self.html_content, "text/html") + + # djcelery_email จะ Intercep เมธอด send() ของ EmailMultiAlternatives โดยอัตโนมัติ + return msg.send() + + def create_email_html(self, url, user): + # ดึง context data อีกครั้งเพื่อเข้าถึง protocol และ domain + context = self.get_context_data() + full_reset_url = f"{context['protocol']}://{context['domain']}{url}" # สร้าง Full URL + + return f""" + + + +

สวัสดีคุณ {user.username},

+

คุณได้ร้องขอการรีเซ็ตรหัสผ่าน โปรดคลิกลิงก์ด้านล่างเพื่อตั้งรหัสผ่านใหม่:

+ +

รีเซ็ตรหัสผ่าน (คลิกที่นี่)

+ +

หากลิงก์ไม่สามารถคลิกได้ กรุณาคัดลอกลิงก์นี้ไปวางในเบราว์เซอร์: {full_reset_url}

+

หากคุณไม่ได้ร้องขอ โปรดเพิกเฉยต่ออีเมลนี้

+

ขอบคุณครับ,
ทีม DDO Console

+ + + """ + + def create_email_plain(self, url, user): + # ดึง context data อีกครั้งเพื่อเข้าถึง protocol และ domain + context = self.get_context_data() + full_reset_url = f"{context['protocol']}://{context['domain']}{url}" # ⬅️ สร้าง Full URL + + return f""" + สวัสดี {user.username}, + + คุณได้ร้องขอการรีเซ็ตรหัสผ่าน กรุณาใช้ลิงก์ด้านล่างเพื่อตั้งรหัสผ่านใหม่: + + {full_reset_url} + + หากคุณไม่ได้ร้องขอ โปรดเพิกเฉยต่ออีเมลนี้ + + ขอบคุณครับ, + ทีม DDO Console + """ diff --git a/backend/accounts/migrations/0001_initial.py b/backend/accounts/migrations/0001_initial.py new file mode 100644 index 0000000..65e2d55 --- /dev/null +++ b/backend/accounts/migrations/0001_initial.py @@ -0,0 +1,45 @@ +# Generated by Django 5.2.7 on 2025-10-29 22:54 + +import django.contrib.auth.models +import django.contrib.auth.validators +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='CustomUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), + ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('phone_number', models.CharField(blank=True, max_length=20, null=True, unique=True)), + ('email', models.EmailField(max_length=254, unique=True)), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), + ], + options={ + 'verbose_name': 'user', + 'verbose_name_plural': 'users', + 'abstract': False, + }, + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + ] diff --git a/backend/accounts/migrations/0002_customuser_role.py b/backend/accounts/migrations/0002_customuser_role.py new file mode 100644 index 0000000..eea7bda --- /dev/null +++ b/backend/accounts/migrations/0002_customuser_role.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.7 on 2025-11-08 22:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='customuser', + name='role', + field=models.CharField(choices=[('ADMIN', 'Administrator'), ('OPERATOR', 'Operator'), ('VIEWER', 'Viewer')], default='VIEWER', max_length=20), + ), + ] diff --git a/backend/accounts/migrations/__init__.py b/backend/accounts/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/accounts/models.py b/backend/accounts/models.py new file mode 100644 index 0000000..a4262ea --- /dev/null +++ b/backend/accounts/models.py @@ -0,0 +1,19 @@ +from django.db import models + +from django.contrib.auth.models import AbstractUser + +class CustomUser(AbstractUser): + # เพิ่มฟิลด์ที่ต้องการ เช่น phone_number + phone_number = models.CharField(max_length=20, blank=True, null=True, unique=True) + email = models.EmailField(unique=True) + + # เพิ่มฟิลด์ Role สำหรับ RBAC ที่กำหนดเอง + ROLE_CHOICES = [ + ('ADMIN', 'Administrator'), + ('OPERATOR', 'Operator'), + ('VIEWER', 'Viewer'), + ] + role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='VIEWER') + + # ไม่ต้องเปลี่ยนส่วนอื่นๆ ถ้าสืบทอดจาก AbstractUser + pass diff --git a/backend/accounts/serializers.py b/backend/accounts/serializers.py new file mode 100644 index 0000000..e0af2bc --- /dev/null +++ b/backend/accounts/serializers.py @@ -0,0 +1,59 @@ +from djoser.serializers import UserCreateSerializer as BaseUserCreateSerializer +from rest_framework import serializers +from .models import CustomUser + +from rest_framework_simplejwt.serializers import TokenObtainPairSerializer +from rest_framework_simplejwt.tokens import RefreshToken +from django.conf import settings + +class UserCreateSerializer(BaseUserCreateSerializer): + # Serializer สำหรับการลงทะเบียน (Djoser จะใช้ตัวนี้) + class Meta(BaseUserCreateSerializer.Meta): + model = CustomUser + fields = ('id', 'username', 'email', 'phone_number', 'password') # เพิ่ม phone_number + +class UserSerializer(serializers.ModelSerializer): + # Serializer สำหรับการดึงข้อมูล (ใช้แสดงข้อมูลผู้ใช้ปัจจุบัน) + class Meta: + model = CustomUser + fields = ( + 'id', 'username', 'email', 'phone_number', 'first_name', 'last_name', + # เพิ่มฟิลด์สถานะสิทธิ์/Role สำหรับ RBAC + 'is_active', 'is_staff', 'is_superuser', + # เพิ่ม 'role' ใน model + 'role', + ) + # ตั้งค่า is_active, is_staff, is_superuser เป็น read_only + read_only_fields = ('id', 'username', 'is_active', 'is_staff', 'is_superuser', 'role') + +# Serializer สำหรับ Login JWT ที่รับค่า remember_me +class CustomTokenObtainPairSerializer(TokenObtainPairSerializer): + + def validate(self, attrs): + # print("CustomTokenObtainPairSerializer called") + data = super().validate(attrs) + + # รับ remember_me จาก request (รองรับ true/false ทั้ง bool และ string) + remember_raw = self.context['request'].data.get('remember_me', False) + + remember_me = ( + remember_raw is True or + str(remember_raw).lower() == "true" or + remember_raw == "1" + ) + + refresh = self.get_token(self.user) + + # ฝัง remember_me ลงใน payload + refresh['remember_me'] = remember_me + + # ถ้า remember_me=True → อายุ Refresh Token เป็น 30 วัน + if remember_me: + refresh.set_exp( + from_time=refresh.current_time, + lifetime=settings.SIMPLE_JWT['REFRESH_TOKEN_LIFETIME_REMEMBER_ME'] + ) + + data['refresh'] = str(refresh) + data['access'] = str(refresh.access_token) + return data diff --git a/backend/accounts/tests.py b/backend/accounts/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/backend/accounts/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/backend/accounts/views.py b/backend/accounts/views.py new file mode 100644 index 0000000..d726ef7 --- /dev/null +++ b/backend/accounts/views.py @@ -0,0 +1,5 @@ +from rest_framework_simplejwt.views import TokenObtainPairView +from .serializers import CustomTokenObtainPairSerializer + +class CustomTokenObtainPairView(TokenObtainPairView): + serializer_class = CustomTokenObtainPairSerializer diff --git a/backend/api/__init__.py b/backend/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/api/admin.py b/backend/api/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/backend/api/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/backend/api/apps.py b/backend/api/apps.py new file mode 100644 index 0000000..66656fd --- /dev/null +++ b/backend/api/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'api' diff --git a/backend/api/migrations/0001_initial.py b/backend/api/migrations/0001_initial.py new file mode 100644 index 0000000..7e62002 --- /dev/null +++ b/backend/api/migrations/0001_initial.py @@ -0,0 +1,36 @@ +# Generated by Django 5.2.7 on 2025-11-14 23:02 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + #('model_registry', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='InferenceAuditLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('timestamp', models.DateTimeField(auto_now_add=True, verbose_name='เวลาเรียกใช้')), + ('endpoint_url', models.CharField(max_length=500, verbose_name='FastAPI Endpoint')), + ('http_status', models.IntegerField(verbose_name='HTTP Status Code')), + ('latency_ms', models.FloatField(verbose_name='Latency (ms)')), + ('is_success', models.BooleanField(default=False, verbose_name='สำเร็จหรือไม่')), + ('response_summary', models.TextField(blank=True, null=True, verbose_name='ผลลัพธ์สรุป/ข้อความ error')), + ('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='ผู้ใช้งาน')), + ], + options={ + 'verbose_name': 'Inference Audit Log', + 'verbose_name_plural': 'Inference Audit Logs', + 'ordering': ['-timestamp'], + }, + ), + ] diff --git a/backend/api/migrations/__init__.py b/backend/api/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/api/models.py b/backend/api/models.py new file mode 100644 index 0000000..48d6129 --- /dev/null +++ b/backend/api/models.py @@ -0,0 +1,26 @@ +from django.db import models +from django.conf import settings +#from model_registry.models import AiModel + +class InferenceAuditLog(models.Model): + """บันทึกทุกคำสั่งรัน Inference ที่เข้ามาใน Gateway""" + + # ข้อมูลผู้ใช้/โมเดล + # ใช้ ForeignKey ไปยัง CustomUser และ AiModel + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, verbose_name="ผู้ใช้งาน") + #model = models.ForeignKey(AiModel, on_delete=models.SET_NULL, null=True, verbose_name="Model ที่ถูกเรียก") + + # ข้อมูลการประมวลผล + timestamp = models.DateTimeField(auto_now_add=True, verbose_name="เวลาเรียกใช้") + endpoint_url = models.CharField(max_length=500, verbose_name="FastAPI Endpoint") + http_status = models.IntegerField(verbose_name="HTTP Status Code") + latency_ms = models.FloatField(verbose_name="Latency (ms)") + is_success = models.BooleanField(default=False, verbose_name="สำเร็จหรือไม่") + + # ผลลัพธ์ + response_summary = models.TextField(blank=True, null=True, verbose_name="ผลลัพธ์สรุป/ข้อความ error") + + class Meta: + ordering = ['-timestamp'] + verbose_name = "Inference Audit Log" + verbose_name_plural = "Inference Audit Logs" diff --git a/backend/api/serializers/__init__.py b/backend/api/serializers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/api/serializers/audit_serializer.py b/backend/api/serializers/audit_serializer.py new file mode 100644 index 0000000..d713963 --- /dev/null +++ b/backend/api/serializers/audit_serializer.py @@ -0,0 +1,17 @@ +from rest_framework import serializers +from api.models import InferenceAuditLog + +class InferenceAuditLogSerializer(serializers.ModelSerializer): + # แสดงข้อมูล Model และ User ที่เกี่ยวข้อง + #model_name = serializers.CharField(source='model.name', read_only=True) + username = serializers.CharField(source='user.username', read_only=True) + + class Meta: + model = InferenceAuditLog + fields = ( + 'id', 'user', 'username', + #'model', 'model_name', + 'timestamp', 'http_status', 'latency_ms', + 'is_success', 'response_summary' + ) + read_only_fields = fields \ No newline at end of file diff --git a/backend/api/services/__init__.py b/backend/api/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/api/services/health_service.py b/backend/api/services/health_service.py new file mode 100644 index 0000000..586709e --- /dev/null +++ b/backend/api/services/health_service.py @@ -0,0 +1,102 @@ +import os +import time +from django.db import connection, Error as DjangoDBError +from django.core.cache import cache +from django.conf import settings +import boto3 +from botocore.client import Config +from botocore.exceptions import ClientError +from datetime import datetime, timezone + +# สร้าง Exception ขึ้นมาใหม่แทนการใช้ของ model_registry +class HealthCheckError(Exception): + """Custom exception raised for health check errors.""" + pass + + +class HealthService: + def __init__(self): + pass + + def _check_database(self): + # Logic ตรวจสอบ CockroachDB + start_time = time.time() + try: + with connection.cursor() as cursor: + cursor.execute("SELECT 1") + # ใช้ round() ปกติ + latency = round((time.time() - start_time) * 1000, 2) + return "UP", f"Query executed successfully. Latency: {latency}ms" + except DjangoDBError as e: + return "DOWN", f"DB Connection Error: {e}" + except Exception as e: + return "DOWN", f"Unknown DB Error: {e}" + + def _check_cache(self): + # Logic ตรวจสอบ Redis + start_time = time.time() + test_key = 'health_test_key' + try: + cache.set(test_key, 'ok', timeout=1) + result = cache.get(test_key) + latency = round((time.time() - start_time) * 1000, 2) + if result == 'ok': + return "UP", f"Read/Write successful. Latency: {latency}ms" + return "DOWN", "Failed to retrieve test key." + except Exception as e: + return "DOWN", f"Redis Error: {e}" + + def _check_minio(self): + """Logic ตรวจสอบ Object Storage (MinIO) โดยใช้ boto3""" + try: + # 1. สร้าง S3 Client ด้วย boto3 + s3_client = boto3.client( + "s3", + endpoint_url=os.getenv("MINIO_ENDPOINT", "http://localhost:9000"), + aws_access_key_id=os.getenv("MINIO_ACCESS_KEY", "minio_admin"), + aws_secret_access_key=os.getenv("MINIO_SECRET_KEY", "minio_p@ssw0rd!"), + # ใช้ Config เพื่อจัดการ timeout/signature version + config=Config(signature_version="s3v4", connect_timeout=5, read_timeout=10) + ) + + # ควรเปลี่ยนชื่อ MODEL_BUCKET เป็นชื่อที่สื่อถึงการใช้งานอื่น (แผนอนาคต) + bucket_name = os.getenv("MODEL_BUCKET", "models") + + # 2. ทดสอบการเข้าถึง Bucket + s3_client.head_bucket(Bucket=bucket_name) + + return "UP", f"Bucket '{bucket_name}' accessible via boto3." + + except ClientError as e: + error_code = e.response['Error']['Code'] + if error_code == '404': + return "DOWN", f"Bucket '{bucket_name}' not found." + elif error_code == '403': + return "DOWN", f"MinIO S3 Access Denied. Check Key/Secret." + return "DOWN", f"MinIO S3 Error (Code {error_code}): {e}" + except Exception as e: + return "DOWN", f"MinIO Connection Error: {e}" + + def get_system_health(self): + """เมธอดหลักที่รวมผลลัพธ์ทั้งหมด""" + results = {} + overall_status = "Healthy" + + # รัน Check ทั้งหมด + db_status, db_details = self._check_database() + results['database'] = {"name": "CockroachDB", "status": db_status, "details": db_details} + if db_status != 'UP': overall_status = "Degraded" + + cache_status, cache_details = self._check_cache() + results['cache'] = {"name": "Redis Cache", "status": cache_status, "details": cache_details} + if cache_status != 'UP': overall_status = "Degraded" + + minio_status, minio_details = self._check_minio() + results['storage'] = {"name": "MinIO S3", "status": minio_status, "details": minio_details} + if minio_status != 'UP': overall_status = "Degraded" + + return { + "status": overall_status, + "services": results, + "last_checked": datetime.now(timezone.utc).isoformat() + } \ No newline at end of file diff --git a/backend/api/tests.py b/backend/api/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/backend/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/backend/api/views.py b/backend/api/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/backend/api/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/backend/api/views/__init__.py b/backend/api/views/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/api/views/audit_viewset.py b/backend/api/views/audit_viewset.py new file mode 100644 index 0000000..48bb8ac --- /dev/null +++ b/backend/api/views/audit_viewset.py @@ -0,0 +1,62 @@ +from rest_framework import viewsets, permissions, status +from rest_framework.response import Response +from rest_framework.decorators import action +from django.db.models import Avg, Count, Q +from django.utils import timezone +from datetime import timedelta + +from api.models import InferenceAuditLog +from api.serializers.audit_serializer import InferenceAuditLogSerializer +from permissions.permission_classes import IsAdminOrManager # ใช้สิทธิ์เดียวกันกับ Model Registry + +class AuditLogViewSet(viewsets.ReadOnlyModelViewSet): + """ + API สำหรับการเข้าถึง Inference Audit Log และสถิติรวม + """ + queryset = InferenceAuditLog.objects.all() + serializer_class = InferenceAuditLogSerializer + permission_classes = [permissions.IsAuthenticated] # อนุญาตให้เข้าถึงเมื่อล็อกอินแล้ว + + # ใช้ 'id' เป็นฟิลด์ค้นหา + lookup_field = 'id' + + # ใช้ 'id' เป็นชื่อพารามิเตอร์ใน URL + lookup_url_kwarg = 'id' + + def retrieve(self, request, *args, **kwargs): + # บังคับให้ Lookup Key (pk) เป็น String + kwargs[self.lookup_url_kwarg] = str(kwargs[self.lookup_url_kwarg]) + + return super().retrieve(request, *args, **kwargs) + + def get_queryset(self): + # คืน Log ล่าสุด 10 รายการ (สำหรับ Recent Events ใน Dashboard) + return self.queryset.select_related('user')[:10] + + # ----------------------------------------------- + # Custom Action: ดึงสถิติรวมสำหรับ Dashboard + # Endpoint: GET /api/v1/audit/inference-summary/ + # ----------------------------------------------- + @action(detail=False, methods=['get'], url_path='inference-summary') + def get_summary(self, request): + one_day_ago = timezone.now() - timedelta(hours=24) + + # 1. คำนวณสถิติรวม (Global Metrics) + metrics = self.queryset.filter(timestamp__gte=one_day_ago).aggregate( + total_runs=Count('id'), + success_count=Count('id', filter=Q(is_success=True)), + avg_latency_ms=Avg('latency_ms') + ) + + # 2. คำนวณ Success Rate + total = metrics.get('total_runs', 0) + success = metrics.get('success_count', 0) + success_rate = (success / total) * 100 if total > 0 else 0 + + return Response({ + "time_window": "24 hours", + "total_runs": total, + "success_rate": round(success_rate, 2), + "avg_latency_ms": round(metrics.get('avg_latency_ms', 0) or 0, 2), + "last_logs": InferenceAuditLogSerializer(self.get_queryset(), many=True).data + }) \ No newline at end of file diff --git a/backend/api/views/health_check_view.py b/backend/api/views/health_check_view.py new file mode 100644 index 0000000..fc5a255 --- /dev/null +++ b/backend/api/views/health_check_view.py @@ -0,0 +1,36 @@ +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status, permissions +from datetime import datetime, timezone + +# Import Service Layer +from api.services.health_service import HealthService + +# Dependency Injection: สร้าง Instance ของ Service +health_service = HealthService() + +class SystemHealthCheck(APIView): + """ + GET /api/v1/health/ + Controller สำหรับดึงสถานะ Health Check ของระบบ + """ + permission_classes = [permissions.AllowAny] + + def get(self, request): + try: + # เรียกใช้ Service Layer + response_data = health_service.get_system_health() + + # กำหนด HTTP Status ตามสถานะรวม + http_status = status.HTTP_200_OK + if response_data['status'] != "Healthy": + http_status = status.HTTP_503_SERVICE_UNAVAILABLE + + return Response(response_data, status=http_status) + + except Exception as e: + # จัดการข้อผิดพลาดที่ไม่คาดคิดในระดับ View + return Response( + {"status": "Error", "detail": f"Internal Server Error during health check: {e}"}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR + ) \ No newline at end of file diff --git a/backend/core/__init__.py b/backend/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/core/asgi.py b/backend/core/asgi.py new file mode 100644 index 0000000..e36e2c8 --- /dev/null +++ b/backend/core/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for core project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') + +application = get_asgi_application() diff --git a/backend/core/celery.py b/backend/core/celery.py new file mode 100644 index 0000000..c421e06 --- /dev/null +++ b/backend/core/celery.py @@ -0,0 +1,16 @@ +import os +from celery import Celery + +# กำหนดค่า Django settings module ให้ Celery +# 'core.settings' คือ path ของ settings.py ของโปรเจกต์ Django +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') + +# สร้าง Celery application instance +app = Celery('core') # ชื่อตรงนี้ต้องตรงกับ -A core และ CELERY_APP: core + +# โหลด configuration จากไฟล์ settings.py ของ Django +# โดย Celery จะใช้ prefix CELERY_ (เช่น CELERY_BROKER_URL) +app.config_from_object('django.conf:settings', namespace='CELERY') + +# ค้นหา tasks ทั้งหมดใน INSTALLED_APPS ของ Django โดยอัตโนมัติ +app.autodiscover_tasks() \ No newline at end of file diff --git a/backend/core/settings.py b/backend/core/settings.py new file mode 100644 index 0000000..7c809e5 --- /dev/null +++ b/backend/core/settings.py @@ -0,0 +1,354 @@ +""" +Django settings for core project. + +Generated by 'django-admin startproject' using Django 5.2.7. + +For more information on this file, see +https://docs.djangoproject.com/en/5.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/5.2/ref/settings/ +""" + +from pathlib import Path +import os + +from datetime import timedelta + +try: + from dotenv import load_dotenv + load_dotenv() # โหลดตัวแปรจาก .env ใน Local Dev +except ImportError: + pass # ไม่ทำอะไรถ้า Module ไม่พบ (หมายความว่ารันอยู่ใน Docker) + +DB_HOST = os.getenv("DB_HOST", "cockroach-1") + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-a1c7+vs57v77ywrtrdrgg58utw5p1a4t2tq9!=w09y@nq-ig0q' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +DJANGO_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', +] + +THIRD_PARTY_APPS = [ + 'django_bolt', + 'rest_framework', + 'corsheaders', + 'drf_spectacular', + 'drf_spectacular_sidecar', + 'djcelery_email', +] + +LOCAL_APPS = [ + 'api', + 'accounts', + 'user_profile', + 'permissions', + #'model_registry' +] + +INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS + + +MIDDLEWARE = [ + 'corsheaders.middleware.CorsMiddleware', # สำคัญมากสำหรับ Frontend + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +# ตั้งค่า CORS: อนุญาตให้ Frontend เข้าถึง API ได้ (ใน Dev Mode) +CORS_ALLOWED_ORIGINS = [ + "http://localhost:5173", # Vite/React Default Port + "http://127.0.0.1:5173", +] +CORS_ALLOW_ALL_ORIGINS = True # ควรเป็น False ใน Production + +ROOT_URLCONF = 'core.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'core.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/5.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django_cockroachdb', + 'NAME': os.environ.get('DB_NAME', 'my_db'), + 'HOST': os.environ.get('DB_HOST', 'cockroach-1'), + 'PORT': os.environ.get('DB_PORT', '26257'), + 'USER': os.environ.get('DB_USER', 'root'), + 'PASSWORD': os.environ.get('DB_PASSWORD', ''), + + # อยู่ระดับเดียวกับ 'ENGINE' และ 'OPTIONS' + 'support_check_by_version': False, + + 'OPTIONS': { + # ใช้ 'options' เพื่อส่งค่า config ไปยัง CockroachDB/PostgreSQL + 'options': '-c default_transaction_read_only=off' + }, + 'ATOMIC_REQUESTS': False, + }, +} + + + +# Password validation +# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/5.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/5.2/howto/static-files/ + +STATIC_URL = 'static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +# 1. กำหนด Custom User Model +AUTH_USER_MODEL = 'accounts.CustomUser' # ต้องชี้ไปที่ Model ใน App accounts/models.py + +# 2. ตั้งค่า REST Framework +REST_FRAMEWORK = { + 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema', + + 'DEFAULT_AUTHENTICATION_CLASSES': ( + # ใช้ JWT เป็นวิธีการยืนยันตัวตนหลัก + 'rest_framework_simplejwt.authentication.JWTAuthentication', + ), + 'DEFAULT_PERMISSION_CLASSES': ( + 'rest_framework.permissions.IsAuthenticated', + ), + 'DEFAULT_RENDERER_CLASSES': ( + # ใช้ DRF Renderer ที่รับประกันว่าตัวเลขขนาดใหญ่จะถูกแปลงเป็น String + # (นี่คือวิธีแก้ปัญหา BigInt Truncation ที่ถูกต้องที่สุด) + 'rest_framework.renderers.JSONRenderer', + 'rest_framework.renderers.BrowsableAPIRenderer', + ), + # เพิ่มการตั้งค่าเพื่อรองรับตัวเลขขนาดใหญ่ใน JSON + 'COERCE_DECIMAL_TO_STRING': False, # ตั้งค่านี้ไว้เผื่อ + # ตัวเลขขนาดใหญ่ (เช่น BigIntegerField) ต้องถูก Serialize เป็น String + 'DATETIME_FORMAT': "%Y-%m-%d %H:%M:%S", + + 'DEFAULT_THROTTLE_CLASSES': [ + 'rest_framework.throttling.AnonRateThrottle', + 'rest_framework.throttling.UserRateThrottle', + ], + 'DEFAULT_THROTTLE_RATES': { + 'anon': '100/day', + 'user': '50/minute', + 'inference_burst': '20/minute', # Rate Limit สำหรับงานหนัก + } +} + +SIMPLE_JWT = { + # ชี้ไปที่ Custom Serializer ที่อยู่ใน accounts.serializers + 'TOKEN_OBTAIN_PAIR_SERIALIZER': 'accounts.serializers.CustomTokenObtainPairSerializer', + + 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15), + 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), + 'REFRESH_TOKEN_LIFETIME_REMEMBER_ME': timedelta(days=30), + + # การตั้งค่าอื่น ๆ ของ SIMPLE_JWT ในอนาคต +} + +# 3. ตั้งค่า DJOSER (เพื่อจัดการ Auth Endpoints) +DOMAIN = "localhost:5173" +SITE_NAME = 'localhost:5173' # หรือชื่อ Domain จริง +DJOSER = { + # ใช้งาน JWT โดยตรง + 'USER_ID_FIELD': 'id', # ใช้ ID ของ User Model + 'EMAIL': { + # ชี้ไปยัง Custom Email Class ที่เราสร้าง + 'password_reset': 'accounts.emails.CustomPasswordResetEmail', + }, + 'PASSWORD_RESET_CONFIRM_URL': '/password/reset/confirm/{uid}/{token}', # URL ที่ Djoser จะใช้สร้างลิงก์ในอีเมล (ชี้ไปยัง Frontend Route) + 'USERNAME_RESET_CONFIRM_URL': '/username/reset/confirm/{uid}/{token}', + 'ACTIVATION_URL': '/activate/{uid}/{token}', # หากต้องการยืนยันอีเมล + 'SERIALIZERS': { + 'user_create': 'accounts.serializers.UserCreateSerializer', # จะสร้างในขั้นตอนถัดไป + 'user': 'accounts.serializers.UserSerializer', # ใช้ UserSerializer เดิม + 'current_user': 'accounts.serializers.UserSerializer', + }, + 'TOKEN_MODEL': None, # ไม่ใช้ TokenAuth แบบเก่า + 'PERMISSIONS': { + 'user_create': ['rest_framework.permissions.AllowAny'], + }, + "DOMAIN": "localhost:5173", + "SITE_NAME": "localhost:5173", + "PROTOCOL": "http", +} + +REDIS_HOST = os.getenv("REDIS_HOST", "redis") +REDIS_PORT = os.getenv("REDIS_PORT", "6379") + +# 1. ตั้งค่า Redis Cache +CACHES = { + "default": { + "BACKEND": "django_redis.cache.RedisCache", + # ใช้ตัวแปร REDIS_HOST ที่ดึงมาจาก .env (localhost) หรือ Docker (redis) + "LOCATION": f"redis://{REDIS_HOST}:{REDIS_PORT}/1", + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient", + "IGNORE_EXCEPTIONS": True + } + } +} + +# 2. บังคับให้ Django ใช้ Cache (Redis) ในการเก็บ Session +SESSION_ENGINE = "django.contrib.sessions.backends.cache" +SESSION_CACHE_ALIAS = "default" + +# 3. ใช้ Redis สำหรับเก็บ Token Cache (สำหรับ DRF/JWT ถ้าจำเป็น) +# CACHE_MIDDLEWARE_SECONDS = 60 * 5 # 5 นาที +# CACHE_MIDDLEWARE_KEY_PREFIX = 'auth_cache' + +# CELERY CONFIGURATION +CELERY_BROKER_URL = os.getenv('CELERY_BROKER_URL', 'redis://redis:6379/0') +CELERY_RESULT_BACKEND = os.getenv('CELERY_RESULT_BACKEND', 'redis://redis:6379/0') +CELERY_ACCEPT_CONTENT = ['json'] +CELERY_TASK_SERIALIZER = 'json' +CELERY_RESULT_SERIALIZER = 'json' +CELERY_TIMEZONE = 'Asia/Bangkok' + +# ---------------------------------------------------------------------- +# SPECTACULAR CONFIGURATION +# ---------------------------------------------------------------------- + +SPECTACULAR_SETTINGS = { + # ชื่อโครงการ + 'TITLE': 'Unified Inbox Service API', + + # คำอธิบายสั้นๆ ของโครงการ + 'DESCRIPTION': 'API Gateway for Unified Inbox Service (Django DRF).', + + # เวอร์ชัน API + 'VERSION': 'v1', + + # กำหนด URL ที่ใช้ในการสร้าง Schema (เพื่อให้รวมทุก Endpoints) + 'SERVE_URLCONF': 'core.urls', + + # กำหนดให้ใช้ Sidecar เพื่อการแสดงผลแบบออฟไลน์ + 'SWAGGER_UI_DIST': 'SIDECAR', + 'SWAGGER_UI_FAVICON_HREF': 'SIDECAR', + 'REDOC_DIST': 'SIDECAR', + + # กำหนด Authentication สำหรับ Doc (แสดงช่องใส่ JWT Token ใน Swagger) + 'SECURITY': [ + { + 'BearerAuth': { # ชื่อนี้จะใช้ใน Components/SecuritySchemes + 'type': 'http', + 'scheme': 'bearer', + 'bearerFormat': 'JWT', + } + } + ], + # ----------------------------------------------------------- + # การจัดเรียงและกำหนดชื่อ Tags + # ----------------------------------------------------------- + 'TAGS': [ + { + 'name': '1. Authentication & User Management', + 'description': 'Endpoints for JWT token management, login, and user profile operations (Djoser).', + }, + { + 'name': '2. Application Service', + 'description': 'Endpoints for Application Service.', + }, + ], + 'POSTPROCESSING_HOOKS': [ + 'core.spectacular_hooks.rename_djoser_tags', + ], + # ตั้งค่าอื่น ๆ (ถ้าจำเป็น) +} + +# ---------------------------------------------------------------------- +# CELERY EMAIL CONFIGURATION (Transactional Emails) +# ---------------------------------------------------------------------- + +# 1. EMAIL_BACKEND หลัก ใช้ Celery Email Backend +# Django จะส่งอีเมลทั้งหมดไปเข้าคิว Celery +EMAIL_BACKEND = 'djcelery_email.backends.CeleryEmailBackend' + +# 2. CELERY_EMAIL_BACKEND: กำหนด SMTP ที่ Celery Worker จะใช้ +# Celery Worker จะใช้ตัวนี้ในการส่งอีเมลออกจริง ๆ +CELERY_EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' + +# Mailjet SMTP Configuration (ใช้ Env Vars) +#EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_HOST = os.getenv('MAILJET_SMTP_HOST') +EMAIL_PORT = os.getenv('MAILJET_SMTP_PORT') +EMAIL_USE_TLS = os.getenv('MAILJET_SMTP_TLS', 'True') == 'True' +EMAIL_HOST_USER = os.getenv('MAILJET_API_KEY') # API Key เป็น Username +EMAIL_HOST_PASSWORD = os.getenv('MAILJET_SECRET_KEY') # Secret Key เป็น Password +DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL') # อีเมลผู้ส่ง +SERVER_EMAIL = DEFAULT_FROM_EMAIL # อีเมลสำหรับแจ้งเตือน Server \ No newline at end of file diff --git a/backend/core/spectacular_hooks.py b/backend/core/spectacular_hooks.py new file mode 100644 index 0000000..5a992e4 --- /dev/null +++ b/backend/core/spectacular_hooks.py @@ -0,0 +1,13 @@ +# core/spectacular_hooks.py +def rename_djoser_tags(result, generator, request, public): + """ + เปลี่ยน Tag 'v1' ของ Djoser ให้เป็นชื่อ Tag ที่ต้องการ + """ + # result คือ OpenAPI spec เป็น dict + paths = result.get('paths', {}) + for path, path_item in paths.items(): + for method, operation in path_item.items(): + tags = operation.get('tags', []) + if 'v1' in tags: + operation['tags'] = ['1. Authentication & User Management'] + return result diff --git a/backend/core/urls.py b/backend/core/urls.py new file mode 100644 index 0000000..fef37d9 --- /dev/null +++ b/backend/core/urls.py @@ -0,0 +1,64 @@ +""" +URL configuration for cremation_backend project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/5.2/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include +from rest_framework.routers import DefaultRouter + +#from model_registry.views.ai_model_viewset import AiModelRegistryViewSet +from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView, SpectacularRedocView + +# Import View ในแอพ /api +from api.views.health_check_view import SystemHealthCheck +from api.views.audit_viewset import AuditLogViewSet + +from accounts.views import CustomTokenObtainPairView + +# 1. กำหนดตัวแปร router ก่อนใช้งาน +router = DefaultRouter() + +# 2. ลงทะเบียน API ViewSets (Project-Level Routing) +# URL: /api/v1/audit/ (AuditLogViewSet) +router.register( + r'audit', + AuditLogViewSet, + basename='auditlog', +) + +# 3. ลงทะเบียน ViewSet อื่น ๆ +urlpatterns = [ + path('admin/', admin.site.urls), + + # Schema OpenAPI + path('api/schema/', SpectacularAPIView.as_view(), name='schema'), + + # Swagger UI + path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), + + # Redoc UI + path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), + + # Endpoints สำหรับการยืนยันตัวตน (Login, Logout, Register) + path("api/v1/auth/jwt/create/", CustomTokenObtainPairView.as_view(), name="jwt-create"), + path('api/v1/auth/', include('djoser.urls')), # /users/ (Register/Update/Me), /users/set_password + path('api/v1/auth/', include('djoser.urls.jwt')), # /jwt/create (Login), /jwt/refresh (Refresh Token) + + # Health Check Endpoint URL: /api/v1/health/ + path('api/v1/health/', SystemHealthCheck.as_view(), name='system-health'), + + # 3. รวม Router API + path('api/v1/', include(router.urls)), +] diff --git a/backend/core/wsgi.py b/backend/core/wsgi.py new file mode 100644 index 0000000..050d8bc --- /dev/null +++ b/backend/core/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for core project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') + +application = get_wsgi_application() diff --git a/backend/create_db.py b/backend/create_db.py new file mode 100644 index 0000000..6bd7b78 --- /dev/null +++ b/backend/create_db.py @@ -0,0 +1,34 @@ +import psycopg +import os + +# --- ตั้งค่าการเชื่อมต่อ (สำคัญ: ต้องตรงกับค่าใน .env) --- +DB_HOST = os.environ.get("DB_HOST", "localhost") # ใช้ localhost +DB_PORT = os.environ.get("DB_PORT", 26257) +DB_NAME = os.environ.get("DB_NAME", "my_db") +DB_USER = os.environ.get("DB_USER", "root") +DB_PASSWORD = os.environ.get("DB_PASSWORD", "") + +print(f"Attempting to connect to CockroachDB at {DB_HOST}:{DB_PORT} to create database '{DB_NAME}'...") + +try: + # ต้องเชื่อมต่อไปยัง Database มาตรฐาน (defaultdb) ก่อน เพื่อให้มีสิทธิ์สร้าง Database ใหม่ + conn = psycopg.connect( + host=DB_HOST, + port=DB_PORT, + dbname="defaultdb", # ใช้ defaultdb เพื่อสร้าง my_db + user=DB_USER, + password=DB_PASSWORD + ) + conn.autocommit = True + cur = conn.cursor() + + # คำสั่งสร้าง Database + cur.execute(f"CREATE DATABASE IF NOT EXISTS {DB_NAME};") + + cur.close() + conn.close() + print(f"Database '{DB_NAME}' created or already exists successfully.") + +except Exception as e: + print(f"ERROR: Failed to connect to or create database: {e}") + print("Ensure Docker Compose is running and environment variables (DB_HOST, DB_PORT) are set correctly.") \ No newline at end of file diff --git a/backend/docker-entrypoint.sh b/backend/docker-entrypoint.sh new file mode 100644 index 0000000..76c4ba3 --- /dev/null +++ b/backend/docker-entrypoint.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +echo "Waiting for CockroachDB cluster to be ready..." + +# ใช้ Python แทน client cockroach +until python - < + Open up App.js to start working on your app! + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#fff', + alignItems: 'center', + justifyContent: 'center', + }, +}); diff --git a/mobile/app.json b/mobile/app.json new file mode 100644 index 0000000..15a5dc7 --- /dev/null +++ b/mobile/app.json @@ -0,0 +1,29 @@ +{ + "expo": { + "name": "mobile", + "slug": "mobile", + "version": "1.0.0", + "orientation": "portrait", + "icon": "./assets/icon.png", + "userInterfaceStyle": "light", + "newArchEnabled": true, + "splash": { + "image": "./assets/splash-icon.png", + "resizeMode": "contain", + "backgroundColor": "#ffffff" + }, + "ios": { + "supportsTablet": true + }, + "android": { + "adaptiveIcon": { + "foregroundImage": "./assets/adaptive-icon.png", + "backgroundColor": "#ffffff" + }, + "edgeToEdgeEnabled": true + }, + "web": { + "favicon": "./assets/favicon.png" + } + } +} diff --git a/mobile/assets/adaptive-icon.png b/mobile/assets/adaptive-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..03d6f6b6c6727954aec1d8206222769afd178d8d GIT binary patch literal 17547 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 literal 0 HcmV?d00001 diff --git a/mobile/assets/icon.png b/mobile/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a0b1526fc7b78680fd8d733dbc6113e1af695487 GIT binary patch literal 22380 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 literal 0 HcmV?d00001 diff --git a/mobile/assets/splash-icon.png b/mobile/assets/splash-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..03d6f6b6c6727954aec1d8206222769afd178d8d GIT binary patch literal 17547 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 App); +// It also ensures that whether you load the app in Expo Go or in a native build, +// the environment is set up appropriately +registerRootComponent(App); diff --git a/mobile/package-lock.json b/mobile/package-lock.json new file mode 100644 index 0000000..6fd8cb0 --- /dev/null +++ b/mobile/package-lock.json @@ -0,0 +1,9308 @@ +{ + "name": "mobile", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "mobile", + "version": "1.0.0", + "dependencies": { + "expo": "~54.0.20", + "expo-status-bar": "~3.0.8", + "react": "19.1.0", + "react-dom": "19.1.0", + "react-native": "0.81.5", + "react-native-web": "^0.21.0" + } + }, + "node_modules/@0no-co/graphql.web": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.2.0.tgz", + "integrity": "sha512-/1iHy9TTr63gE1YcR5idjx8UREz1s0kFhydf3bBLCXyqjhkIc6igAzTOx3zPifCwFR87tsh/4Pa9cNts6d2otw==", + "license": "MIT", + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + }, + "peerDependenciesMeta": { + "graphql": { + "optional": true + } + } + }, + "node_modules/@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "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==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", + "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.10" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", + "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz", + "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.28.0.tgz", + "integrity": "sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-decorators": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-default-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.27.1.tgz", + "integrity": "sha512-hjlsMBl1aJc5lp8MoCDEZCiYzlgdRAShOjAfRw6X+GlpLpUPU7c3XNLsKFZbQk/1cRzBlJ7CXg3xJAJMrFa1Uw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz", + "integrity": "sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-default-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.27.1.tgz", + "integrity": "sha512-eBC/3KSekshx19+N40MzjWqJd7KTEdOoLesAfa4IDFI8eRz5a47i5Oszus6zG/cwIXN63YhgLOMSSNJx49sENg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz", + "integrity": "sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", + "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", + "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", + "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", + "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", + "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", + "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", + "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", + "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz", + "integrity": "sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-flow": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", + "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", + "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", + "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", + "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", + "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz", + "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", + "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", + "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz", + "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz", + "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz", + "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==", + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", + "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", + "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz", + "integrity": "sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", + "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz", + "integrity": "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz", + "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-transform-react-display-name": "^7.28.0", + "@babel/plugin-transform-react-jsx": "^7.27.1", + "@babel/plugin-transform-react-jsx-development": "^7.27.1", + "@babel/plugin-transform-react-pure-annotations": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz", + "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template/node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse--for-generate-function-map": { + "name": "@babel/traverse", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse--for-generate-function-map/node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@expo/code-signing-certificates": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.5.tgz", + "integrity": "sha512-BNhXkY1bblxKZpltzAx98G2Egj9g1Q+JRcvR7E99DOj862FTCX+ZPsAUtPTr7aHxwtrL7+fL3r0JSmM9kBm+Bw==", + "license": "MIT", + "dependencies": { + "node-forge": "^1.2.1", + "nullthrows": "^1.1.1" + } + }, + "node_modules/@expo/config": { + "version": "12.0.10", + "resolved": "https://registry.npmjs.org/@expo/config/-/config-12.0.10.tgz", + "integrity": "sha512-lJMof5Nqakq1DxGYlghYB/ogSBjmv4Fxn1ovyDmcjlRsQdFCXgu06gEUogkhPtc9wBt9WlTTfqENln5HHyLW6w==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "~7.10.4", + "@expo/config-plugins": "~54.0.2", + "@expo/config-types": "^54.0.8", + "@expo/json-file": "^10.0.7", + "deepmerge": "^4.3.1", + "getenv": "^2.0.0", + "glob": "^10.4.2", + "require-from-string": "^2.0.2", + "resolve-from": "^5.0.0", + "resolve-workspace-root": "^2.0.0", + "semver": "^7.6.0", + "slugify": "^1.3.4", + "sucrase": "3.35.0" + } + }, + "node_modules/@expo/config-plugins": { + "version": "54.0.2", + "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-54.0.2.tgz", + "integrity": "sha512-jD4qxFcURQUVsUFGMcbo63a/AnviK8WUGard+yrdQE3ZrB/aurn68SlApjirQQLEizhjI5Ar2ufqflOBlNpyPg==", + "license": "MIT", + "dependencies": { + "@expo/config-types": "^54.0.8", + "@expo/json-file": "~10.0.7", + "@expo/plist": "^0.4.7", + "@expo/sdk-runtime-versions": "^1.0.0", + "chalk": "^4.1.2", + "debug": "^4.3.5", + "getenv": "^2.0.0", + "glob": "^10.4.2", + "resolve-from": "^5.0.0", + "semver": "^7.5.4", + "slash": "^3.0.0", + "slugify": "^1.6.6", + "xcode": "^3.0.1", + "xml2js": "0.6.0" + } + }, + "node_modules/@expo/config-plugins/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@expo/config-plugins/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@expo/config-plugins/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@expo/config-plugins/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==", + "license": "MIT" + }, + "node_modules/@expo/config-plugins/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/config-plugins/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/config-types": { + "version": "54.0.8", + "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-54.0.8.tgz", + "integrity": "sha512-lyIn/x/Yz0SgHL7IGWtgTLg6TJWC9vL7489++0hzCHZ4iGjVcfZmPTUfiragZ3HycFFj899qN0jlhl49IHa94A==", + "license": "MIT" + }, + "node_modules/@expo/devcert": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.2.0.tgz", + "integrity": "sha512-Uilcv3xGELD5t/b0eM4cxBFEKQRIivB3v7i+VhWLV/gL98aw810unLKKJbGAxAIhY6Ipyz8ChWibFsKFXYwstA==", + "license": "MIT", + "dependencies": { + "@expo/sudo-prompt": "^9.3.1", + "debug": "^3.1.0", + "glob": "^10.4.2" + } + }, + "node_modules/@expo/devcert/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@expo/devtools": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@expo/devtools/-/devtools-0.1.7.tgz", + "integrity": "sha512-dfIa9qMyXN+0RfU6SN4rKeXZyzKWsnz6xBSDccjL4IRiE+fQ0t84zg0yxgN4t/WK2JU5v6v4fby7W7Crv9gJvA==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@expo/devtools/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@expo/devtools/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@expo/devtools/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@expo/devtools/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==", + "license": "MIT" + }, + "node_modules/@expo/devtools/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/devtools/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/env": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.0.7.tgz", + "integrity": "sha512-BNETbLEohk3HQ2LxwwezpG8pq+h7Fs7/vAMP3eAtFT1BCpprLYoBBFZH7gW4aqGfqOcVP4Lc91j014verrYNGg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "debug": "^4.3.4", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "getenv": "^2.0.0" + } + }, + "node_modules/@expo/env/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@expo/env/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@expo/env/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@expo/env/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==", + "license": "MIT" + }, + "node_modules/@expo/env/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/env/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/fingerprint": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.15.2.tgz", + "integrity": "sha512-mA3weHEOd9B3mbDLNDKmAcFWo3kqsAJqPne7uMJndheKXPbRw15bV+ajAGBYZh2SS37xixLJ5eDpuc+Wr6jJtw==", + "license": "MIT", + "dependencies": { + "@expo/spawn-async": "^1.7.2", + "arg": "^5.0.2", + "chalk": "^4.1.2", + "debug": "^4.3.4", + "getenv": "^2.0.0", + "glob": "^10.4.2", + "ignore": "^5.3.1", + "minimatch": "^9.0.0", + "p-limit": "^3.1.0", + "resolve-from": "^5.0.0", + "semver": "^7.6.0" + }, + "bin": { + "fingerprint": "bin/cli.js" + } + }, + "node_modules/@expo/fingerprint/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@expo/fingerprint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@expo/fingerprint/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@expo/fingerprint/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==", + "license": "MIT" + }, + "node_modules/@expo/fingerprint/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/fingerprint/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/image-utils": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.8.7.tgz", + "integrity": "sha512-SXOww4Wq3RVXLyOaXiCCuQFguCDh8mmaHBv54h/R29wGl4jRY8GEyQEx8SypV/iHt1FbzsU/X3Qbcd9afm2W2w==", + "license": "MIT", + "dependencies": { + "@expo/spawn-async": "^1.7.2", + "chalk": "^4.0.0", + "getenv": "^2.0.0", + "jimp-compact": "0.16.1", + "parse-png": "^2.1.0", + "resolve-from": "^5.0.0", + "resolve-global": "^1.0.0", + "semver": "^7.6.0", + "temp-dir": "~2.0.0", + "unique-string": "~2.0.0" + } + }, + "node_modules/@expo/image-utils/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@expo/image-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@expo/image-utils/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@expo/image-utils/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==", + "license": "MIT" + }, + "node_modules/@expo/image-utils/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/image-utils/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/json-file": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.0.7.tgz", + "integrity": "sha512-z2OTC0XNO6riZu98EjdNHC05l51ySeTto6GP7oSQrCvQgG9ARBwD1YvMQaVZ9wU7p/4LzSf1O7tckL3B45fPpw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "~7.10.4", + "json5": "^2.2.3" + } + }, + "node_modules/@expo/mcp-tunnel": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@expo/mcp-tunnel/-/mcp-tunnel-0.0.8.tgz", + "integrity": "sha512-6261obzt6h9TQb6clET7Fw4Ig4AY2hfTNKI3gBt0gcTNxZipwMg8wER7ssDYieA9feD/FfPTuCPYFcR280aaWA==", + "license": "MIT", + "dependencies": { + "ws": "^8.18.3", + "zod": "^3.25.76", + "zod-to-json-schema": "^3.24.6" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": "^1.13.2" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + } + } + }, + "node_modules/@expo/mcp-tunnel/node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "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/@expo/metro": { + "version": "54.1.0", + "resolved": "https://registry.npmjs.org/@expo/metro/-/metro-54.1.0.tgz", + "integrity": "sha512-MgdeRNT/LH0v1wcO0TZp9Qn8zEF0X2ACI0wliPtv5kXVbXWI+yK9GyrstwLAiTXlULKVIg3HVSCCvmLu0M3tnw==", + "license": "MIT", + "dependencies": { + "metro": "0.83.2", + "metro-babel-transformer": "0.83.2", + "metro-cache": "0.83.2", + "metro-cache-key": "0.83.2", + "metro-config": "0.83.2", + "metro-core": "0.83.2", + "metro-file-map": "0.83.2", + "metro-resolver": "0.83.2", + "metro-runtime": "0.83.2", + "metro-source-map": "0.83.2", + "metro-transform-plugins": "0.83.2", + "metro-transform-worker": "0.83.2" + } + }, + "node_modules/@expo/osascript": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.3.7.tgz", + "integrity": "sha512-IClSOXxR0YUFxIriUJVqyYki7lLMIHrrzOaP01yxAL1G8pj2DWV5eW1y5jSzIcIfSCNhtGsshGd1tU/AYup5iQ==", + "license": "MIT", + "dependencies": { + "@expo/spawn-async": "^1.7.2", + "exec-async": "^2.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@expo/package-manager": { + "version": "1.9.8", + "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.9.8.tgz", + "integrity": "sha512-4/I6OWquKXYnzo38pkISHCOCOXxfeEmu4uDoERq1Ei/9Ur/s9y3kLbAamEkitUkDC7gHk1INxRWEfFNzGbmOrA==", + "license": "MIT", + "dependencies": { + "@expo/json-file": "^10.0.7", + "@expo/spawn-async": "^1.7.2", + "chalk": "^4.0.0", + "npm-package-arg": "^11.0.0", + "ora": "^3.4.0", + "resolve-workspace-root": "^2.0.0" + } + }, + "node_modules/@expo/package-manager/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@expo/package-manager/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@expo/package-manager/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@expo/package-manager/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==", + "license": "MIT" + }, + "node_modules/@expo/package-manager/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/package-manager/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/plist": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.4.7.tgz", + "integrity": "sha512-dGxqHPvCZKeRKDU1sJZMmuyVtcASuSYh1LPFVaM1DuffqPL36n6FMEL0iUqq2Tx3xhWk8wCnWl34IKplUjJDdA==", + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.2.3", + "xmlbuilder": "^15.1.1" + } + }, + "node_modules/@expo/schema-utils": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@expo/schema-utils/-/schema-utils-0.1.7.tgz", + "integrity": "sha512-jWHoSuwRb5ZczjahrychMJ3GWZu54jK9ulNdh1d4OzAEq672K9E5yOlnlBsfIHWHGzUAT+0CL7Yt1INiXTz68g==", + "license": "MIT" + }, + "node_modules/@expo/sdk-runtime-versions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz", + "integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==", + "license": "MIT" + }, + "node_modules/@expo/spawn-async": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.7.2.tgz", + "integrity": "sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@expo/sudo-prompt": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/@expo/sudo-prompt/-/sudo-prompt-9.3.2.tgz", + "integrity": "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==", + "license": "MIT" + }, + "node_modules/@expo/ws-tunnel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-1.0.6.tgz", + "integrity": "sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q==", + "license": "MIT" + }, + "node_modules/@expo/xcpretty": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.3.2.tgz", + "integrity": "sha512-ReZxZ8pdnoI3tP/dNnJdnmAk7uLT4FjsKDGW7YeDdvdOMz2XCQSmSCM9IWlrXuWtMF9zeSB6WJtEhCQ41gQOfw==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/code-frame": "7.10.4", + "chalk": "^4.1.0", + "find-up": "^5.0.0", + "js-yaml": "^4.1.0" + }, + "bin": { + "excpretty": "build/cli.js" + } + }, + "node_modules/@expo/xcpretty/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@expo/xcpretty/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==", + "license": "Python-2.0" + }, + "node_modules/@expo/xcpretty/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@expo/xcpretty/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@expo/xcpretty/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==", + "license": "MIT" + }, + "node_modules/@expo/xcpretty/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==", + "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/@expo/xcpretty/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@expo/xcpretty/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==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@expo/xcpretty/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==", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@expo/xcpretty/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==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@expo/xcpretty/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "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/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@isaacs/ttlcache": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz", + "integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/create-cache-key-function": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", + "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==", + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@jest/transform/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/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==", + "license": "MIT" + }, + "node_modules/@jest/transform/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/@jest/types/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/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==", + "license": "MIT" + }, + "node_modules/@jest/types/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "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==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@react-native/assets-registry": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.81.5.tgz", + "integrity": "sha512-705B6x/5Kxm1RKRvSv0ADYWm5JOnoiQ1ufW7h8uu2E6G9Of/eE6hP/Ivw3U5jI16ERqZxiKQwk34VJbB0niX9w==", + "license": "MIT", + "engines": { + "node": ">= 20.19.4" + } + }, + "node_modules/@react-native/babel-plugin-codegen": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.81.5.tgz", + "integrity": "sha512-oF71cIH6je3fSLi6VPjjC3Sgyyn57JLHXs+mHWc9MoCiJJcM4nqsS5J38zv1XQ8d3zOW2JtHro+LF0tagj2bfQ==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.3", + "@react-native/codegen": "0.81.5" + }, + "engines": { + "node": ">= 20.19.4" + } + }, + "node_modules/@react-native/babel-preset": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.81.5.tgz", + "integrity": "sha512-UoI/x/5tCmi+pZ3c1+Ypr1DaRMDLI3y+Q70pVLLVgrnC3DHsHRIbHcCHIeG/IJvoeFqFM2sTdhSOLJrf8lOPrA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/plugin-proposal-export-default-from": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-default-from": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.4", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.25.4", + "@babel/plugin-transform-classes": "^7.25.4", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-flow-strip-types": "^7.25.2", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", + "@babel/plugin-transform-literals": "^7.25.2", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-react-display-name": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.25.2", + "@babel/plugin-transform-react-jsx-self": "^7.24.7", + "@babel/plugin-transform-react-jsx-source": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-runtime": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.25.2", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/template": "^7.25.0", + "@react-native/babel-plugin-codegen": "0.81.5", + "babel-plugin-syntax-hermes-parser": "0.29.1", + "babel-plugin-transform-flow-enums": "^0.0.2", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": ">= 20.19.4" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, + "node_modules/@react-native/codegen": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.81.5.tgz", + "integrity": "sha512-a2TDA03Up8lpSa9sh5VRGCQDXgCTOyDOFH+aqyinxp1HChG8uk89/G+nkJ9FPd0rqgi25eCTR16TWdS3b+fA6g==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/parser": "^7.25.3", + "glob": "^7.1.1", + "hermes-parser": "0.29.1", + "invariant": "^2.2.4", + "nullthrows": "^1.1.1", + "yargs": "^17.6.2" + }, + "engines": { + "node": ">= 20.19.4" + }, + "peerDependencies": { + "@babel/core": "*" + } + }, + "node_modules/@react-native/codegen/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@react-native/codegen/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", + "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/@react-native/codegen/node_modules/hermes-estree": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", + "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", + "license": "MIT" + }, + "node_modules/@react-native/codegen/node_modules/hermes-parser": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", + "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", + "license": "MIT", + "dependencies": { + "hermes-estree": "0.29.1" + } + }, + "node_modules/@react-native/codegen/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@react-native/community-cli-plugin": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.81.5.tgz", + "integrity": "sha512-yWRlmEOtcyvSZ4+OvqPabt+NS36vg0K/WADTQLhrYrm9qdZSuXmq8PmdJWz/68wAqKQ+4KTILiq2kjRQwnyhQw==", + "license": "MIT", + "dependencies": { + "@react-native/dev-middleware": "0.81.5", + "debug": "^4.4.0", + "invariant": "^2.2.4", + "metro": "^0.83.1", + "metro-config": "^0.83.1", + "metro-core": "^0.83.1", + "semver": "^7.1.3" + }, + "engines": { + "node": ">= 20.19.4" + }, + "peerDependencies": { + "@react-native-community/cli": "*", + "@react-native/metro-config": "*" + }, + "peerDependenciesMeta": { + "@react-native-community/cli": { + "optional": true + }, + "@react-native/metro-config": { + "optional": true + } + } + }, + "node_modules/@react-native/debugger-frontend": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.81.5.tgz", + "integrity": "sha512-bnd9FSdWKx2ncklOetCgrlwqSGhMHP2zOxObJbOWXoj7GHEmih4MKarBo5/a8gX8EfA1EwRATdfNBQ81DY+h+w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 20.19.4" + } + }, + "node_modules/@react-native/dev-middleware": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.81.5.tgz", + "integrity": "sha512-WfPfZzboYgo/TUtysuD5xyANzzfka8Ebni6RIb2wDxhb56ERi7qDrE4xGhtPsjCL4pQBXSVxyIlCy0d8I6EgGA==", + "license": "MIT", + "dependencies": { + "@isaacs/ttlcache": "^1.4.1", + "@react-native/debugger-frontend": "0.81.5", + "chrome-launcher": "^0.15.2", + "chromium-edge-launcher": "^0.2.0", + "connect": "^3.6.5", + "debug": "^4.4.0", + "invariant": "^2.2.4", + "nullthrows": "^1.1.1", + "open": "^7.0.3", + "serve-static": "^1.16.2", + "ws": "^6.2.3" + }, + "engines": { + "node": ">= 20.19.4" + } + }, + "node_modules/@react-native/dev-middleware/node_modules/ws": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", + "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", + "license": "MIT", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/@react-native/gradle-plugin": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.81.5.tgz", + "integrity": "sha512-hORRlNBj+ReNMLo9jme3yQ6JQf4GZpVEBLxmTXGGlIL78MAezDZr5/uq9dwElSbcGmLEgeiax6e174Fie6qPLg==", + "license": "MIT", + "engines": { + "node": ">= 20.19.4" + } + }, + "node_modules/@react-native/js-polyfills": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.81.5.tgz", + "integrity": "sha512-fB7M1CMOCIUudTRuj7kzxIBTVw2KXnsgbQ6+4cbqSxo8NmRRhA0Ul4ZUzZj3rFd3VznTL4Brmocv1oiN0bWZ8w==", + "license": "MIT", + "engines": { + "node": ">= 20.19.4" + } + }, + "node_modules/@react-native/normalize-colors": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.81.5.tgz", + "integrity": "sha512-0HuJ8YtqlTVRXGZuGeBejLE04wSQsibpTI+RGOyVqxZvgtlLLC/Ssw0UmbHhT4lYMp2fhdtvKZSs5emWB1zR/g==", + "license": "MIT" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "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==", + "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.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "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==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/node": { + "version": "24.9.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.2.tgz", + "integrity": "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.34", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.34.tgz", + "integrity": "sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/@urql/core": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@urql/core/-/core-5.2.0.tgz", + "integrity": "sha512-/n0ieD0mvvDnVAXEQgX/7qJiVcvYvNkOHeBvkwtylfjydar123caCXcl58PXFY11oU1oquJocVXHxLAbtv4x1A==", + "license": "MIT", + "dependencies": { + "@0no-co/graphql.web": "^1.0.13", + "wonka": "^6.3.2" + } + }, + "node_modules/@urql/exchange-retry": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@urql/exchange-retry/-/exchange-retry-1.3.2.tgz", + "integrity": "sha512-TQMCz2pFJMfpNxmSfX1VSfTjwUIFx/mL+p1bnfM1xjjdla7Z+KnGMW/EhFbpckp3LyWAH4PgOsMwOMnIN+MBFg==", + "license": "MIT", + "dependencies": { + "@urql/core": "^5.1.2", + "wonka": "^6.3.2" + }, + "peerDependencies": { + "@urql/core": "^5.0.0" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz", + "integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/anser": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", + "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==", + "license": "MIT" + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "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==", + "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==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT" + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "license": "MIT" + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/babel-jest/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/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==", + "license": "MIT" + }, + "node_modules/babel-jest/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-react-compiler": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz", + "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.0" + } + }, + "node_modules/babel-plugin-react-native-web": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.21.2.tgz", + "integrity": "sha512-SPD0J6qjJn8231i0HZhlAGH6NORe+QvRSQM2mwQEzJ2Fb3E4ruWTiiicPlHjmeWShDXLcvoorOCXjeR7k/lyWA==", + "license": "MIT" + }, + "node_modules/babel-plugin-syntax-hermes-parser": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.29.1.tgz", + "integrity": "sha512-2WFYnoWGdmih1I1J5eIqxATOeycOqRwYxAQBu3cUu/rhwInwHUg7k60AFNbuGjSDL8tje5GDrAnxzRLcu2pYcA==", + "license": "MIT", + "dependencies": { + "hermes-parser": "0.29.1" + } + }, + "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-estree": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", + "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", + "license": "MIT" + }, + "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-parser": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", + "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", + "license": "MIT", + "dependencies": { + "hermes-estree": "0.29.1" + } + }, + "node_modules/babel-plugin-transform-flow-enums": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz", + "integrity": "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==", + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-flow": "^7.12.1" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "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/baseline-browser-mapping": { + "version": "2.8.21", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.21.tgz", + "integrity": "sha512-JU0h5APyQNsHOlAM7HnQnPToSDQoEBZqzu/YBlqDnEeymPnZDREeXJA3KBMQee+dKteAxZ2AtvQEvVYdZf241Q==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/better-opn": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", + "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==", + "license": "MIT", + "dependencies": { + "open": "^8.0.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/better-opn/node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "license": "Unlicense", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bplist-creator": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz", + "integrity": "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==", + "license": "MIT", + "dependencies": { + "stream-buffers": "2.2.x" + } + }, + "node_modules/bplist-parser": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz", + "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==", + "license": "MIT", + "dependencies": { + "big-integer": "1.6.x" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", + "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", + "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": { + "baseline-browser-mapping": "^2.8.19", + "caniuse-lite": "^1.0.30001751", + "electron-to-chromium": "^1.5.238", + "node-releases": "^2.0.26", + "update-browserslist-db": "^1.1.4" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", + "integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/chrome-launcher": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz", + "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==", + "license": "Apache-2.0", + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0" + }, + "bin": { + "print-chrome-path": "bin/print-chrome-path.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/chrome-launcher/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==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chromium-edge-launcher": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-0.2.0.tgz", + "integrity": "sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg==", + "license": "Apache-2.0", + "dependencies": { + "@types/node": "*", + "escape-string-regexp": "^4.0.0", + "is-wsl": "^2.2.0", + "lighthouse-logger": "^1.0.0", + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + } + }, + "node_modules/chromium-edge-launcher/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==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "license": "MIT" + }, + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/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==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", + "engines": { + "node": ">= 0.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==", + "license": "MIT" + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "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==", + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.46.0.tgz", + "integrity": "sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.26.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cross-fetch": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", + "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/css-in-js-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", + "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", + "license": "MIT", + "dependencies": { + "hyphenate-style-name": "^1.0.3" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "11.0.7", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz", + "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==", + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.243", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.243.tgz", + "integrity": "sha512-ZCphxFW3Q1TVhcgS9blfut1PX8lusVi2SvXQgmEEnK4TCmE1JhH2JkjJN+DNt0pJJwfBri5AROBnz2b/C+YU9g==", + "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==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/env-editor": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.2.tgz", + "integrity": "sha512-ObFo8v4rQJAE59M69QzwloxPZtd33TpYEIjtKD1rrFDcM1Gd7IkDxEBU+HriziN6HSHQnBJi8Dmy+JWkav5HKA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "license": "MIT", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/exec-async": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/exec-async/-/exec-async-2.2.0.tgz", + "integrity": "sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw==", + "license": "MIT" + }, + "node_modules/expo": { + "version": "54.0.21", + "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.21.tgz", + "integrity": "sha512-I3kzMNW/43a71pt6hT0Zebd2zAPIMMeucUDDEdfUKYrzzTRwISZfVAv0dp8GWKHHDjZsy+FjE4RQCMdyKmiDeQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.20.0", + "@expo/cli": "54.0.14", + "@expo/config": "~12.0.10", + "@expo/config-plugins": "~54.0.2", + "@expo/devtools": "0.1.7", + "@expo/fingerprint": "0.15.2", + "@expo/metro": "~54.1.0", + "@expo/metro-config": "54.0.8", + "@expo/vector-icons": "^15.0.3", + "@ungap/structured-clone": "^1.3.0", + "babel-preset-expo": "~54.0.6", + "expo-asset": "~12.0.9", + "expo-constants": "~18.0.10", + "expo-file-system": "~19.0.17", + "expo-font": "~14.0.9", + "expo-keep-awake": "~15.0.7", + "expo-modules-autolinking": "3.0.19", + "expo-modules-core": "3.0.23", + "pretty-format": "^29.7.0", + "react-refresh": "^0.14.2", + "whatwg-url-without-unicode": "8.0.0-3" + }, + "bin": { + "expo": "bin/cli", + "expo-modules-autolinking": "bin/autolinking", + "fingerprint": "bin/fingerprint" + }, + "peerDependencies": { + "@expo/dom-webview": "*", + "@expo/metro-runtime": "*", + "react": "*", + "react-native": "*", + "react-native-webview": "*" + }, + "peerDependenciesMeta": { + "@expo/dom-webview": { + "optional": true + }, + "@expo/metro-runtime": { + "optional": true + }, + "react-native-webview": { + "optional": true + } + } + }, + "node_modules/expo-modules-autolinking": { + "version": "3.0.19", + "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.19.tgz", + "integrity": "sha512-tSMYGnfZmAaN77X8iMLiaSgbCFnA7eh6s2ac09J2N2N0Rcf2RCE27jg0c0XenTMTWUcM4QvLhsNHof/WtlKqPw==", + "license": "MIT", + "dependencies": { + "@expo/spawn-async": "^1.7.2", + "chalk": "^4.1.0", + "commander": "^7.2.0", + "glob": "^10.4.2", + "require-from-string": "^2.0.2", + "resolve-from": "^5.0.0" + }, + "bin": { + "expo-modules-autolinking": "bin/expo-modules-autolinking.js" + } + }, + "node_modules/expo-modules-autolinking/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/expo-modules-autolinking/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/expo-modules-autolinking/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/expo-modules-autolinking/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==", + "license": "MIT" + }, + "node_modules/expo-modules-autolinking/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/expo-modules-autolinking/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/expo-modules-core": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-3.0.23.tgz", + "integrity": "sha512-NYHi5LK/cdIyOjK9ZQAgfDPCOqER26cIbU3gzsce7YdnsmlNFR0qMfWOj9zAmaFBviC2kCkCOmitwk4357Td3Q==", + "license": "MIT", + "dependencies": { + "invariant": "^2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/expo-server": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-1.0.3.tgz", + "integrity": "sha512-SOwdzM/BFAL+vTFlUDJG6ljhyk6TyTl+LRK3ubGmN+Pf18ENRqKj37U8krc5vH926sAsB3IFcE8kJEYf4dG7PA==", + "license": "MIT", + "engines": { + "node": ">=20.16.0" + } + }, + "node_modules/expo-status-bar": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-3.0.8.tgz", + "integrity": "sha512-L248XKPhum7tvREoS1VfE0H6dPCaGtoUWzRsUv7hGKdiB4cus33Rc0sxkWkoQ77wE8stlnUlL5lvmT0oqZ3ZBw==", + "license": "MIT", + "dependencies": { + "react-native-is-edge-to-edge": "^1.2.1" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/expo/node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/expo/node_modules/@expo/cli": { + "version": "54.0.14", + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.14.tgz", + "integrity": "sha512-M7QW/GHx1FJg+CGgChGKerYXmCGWDskJ8S6w+8m49IBZ41CMDeWRH5snQkFoGCttF8WnzhGiX+nu69AFnEuDHQ==", + "license": "MIT", + "dependencies": { + "@0no-co/graphql.web": "^1.0.8", + "@expo/code-signing-certificates": "^0.0.5", + "@expo/config": "~12.0.10", + "@expo/config-plugins": "~54.0.2", + "@expo/devcert": "^1.1.2", + "@expo/env": "~2.0.7", + "@expo/image-utils": "^0.8.7", + "@expo/json-file": "^10.0.7", + "@expo/mcp-tunnel": "~0.0.7", + "@expo/metro": "~54.1.0", + "@expo/metro-config": "~54.0.8", + "@expo/osascript": "^2.3.7", + "@expo/package-manager": "^1.9.8", + "@expo/plist": "^0.4.7", + "@expo/prebuild-config": "^54.0.6", + "@expo/schema-utils": "^0.1.7", + "@expo/spawn-async": "^1.7.2", + "@expo/ws-tunnel": "^1.0.1", + "@expo/xcpretty": "^4.3.0", + "@react-native/dev-middleware": "0.81.5", + "@urql/core": "^5.0.6", + "@urql/exchange-retry": "^1.3.0", + "accepts": "^1.3.8", + "arg": "^5.0.2", + "better-opn": "~3.0.2", + "bplist-creator": "0.1.0", + "bplist-parser": "^0.3.1", + "chalk": "^4.0.0", + "ci-info": "^3.3.0", + "compression": "^1.7.4", + "connect": "^3.7.0", + "debug": "^4.3.4", + "env-editor": "^0.4.1", + "expo-server": "^1.0.3", + "freeport-async": "^2.0.0", + "getenv": "^2.0.0", + "glob": "^10.4.2", + "lan-network": "^0.1.6", + "minimatch": "^9.0.0", + "node-forge": "^1.3.1", + "npm-package-arg": "^11.0.0", + "ora": "^3.4.0", + "picomatch": "^3.0.1", + "pretty-bytes": "^5.6.0", + "pretty-format": "^29.7.0", + "progress": "^2.0.3", + "prompts": "^2.3.2", + "qrcode-terminal": "0.11.0", + "require-from-string": "^2.0.2", + "requireg": "^0.2.2", + "resolve": "^1.22.2", + "resolve-from": "^5.0.0", + "resolve.exports": "^2.0.3", + "semver": "^7.6.0", + "send": "^0.19.0", + "slugify": "^1.3.4", + "source-map-support": "~0.5.21", + "stacktrace-parser": "^0.1.10", + "structured-headers": "^0.4.1", + "tar": "^7.4.3", + "terminal-link": "^2.1.1", + "undici": "^6.18.2", + "wrap-ansi": "^7.0.0", + "ws": "^8.12.1" + }, + "bin": { + "expo-internal": "build/bin/cli" + }, + "peerDependencies": { + "expo": "*", + "expo-router": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "expo-router": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/expo/node_modules/@expo/cli/node_modules/@expo/prebuild-config": { + "version": "54.0.6", + "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-54.0.6.tgz", + "integrity": "sha512-xowuMmyPNy+WTNq+YX0m0EFO/Knc68swjThk4dKivgZa8zI1UjvFXOBIOp8RX4ljCXLzwxQJM5oBBTvyn+59ZA==", + "license": "MIT", + "dependencies": { + "@expo/config": "~12.0.10", + "@expo/config-plugins": "~54.0.2", + "@expo/config-types": "^54.0.8", + "@expo/image-utils": "^0.8.7", + "@expo/json-file": "^10.0.7", + "@react-native/normalize-colors": "0.81.5", + "debug": "^4.3.1", + "resolve-from": "^5.0.0", + "semver": "^7.6.0", + "xml2js": "0.6.0" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo/node_modules/@expo/metro-config": { + "version": "54.0.8", + "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-54.0.8.tgz", + "integrity": "sha512-rCkDQ8IT6sgcGNy48O2cTE4NlazCAgAIsD5qBsNPJLZSS0XbaILvAgGsFt/4nrx0GMGj6iQcOn5ifwV4NssTmw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.20.0", + "@babel/core": "^7.20.0", + "@babel/generator": "^7.20.5", + "@expo/config": "~12.0.10", + "@expo/env": "~2.0.7", + "@expo/json-file": "~10.0.7", + "@expo/metro": "~54.1.0", + "@expo/spawn-async": "^1.7.2", + "browserslist": "^4.25.0", + "chalk": "^4.1.0", + "debug": "^4.3.2", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "getenv": "^2.0.0", + "glob": "^10.4.2", + "hermes-parser": "^0.29.1", + "jsc-safe-url": "^0.2.4", + "lightningcss": "^1.30.1", + "minimatch": "^9.0.0", + "postcss": "~8.4.32", + "resolve-from": "^5.0.0" + }, + "peerDependencies": { + "expo": "*" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + } + } + }, + "node_modules/expo/node_modules/@expo/vector-icons": { + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.0.3.tgz", + "integrity": "sha512-SBUyYKphmlfUBqxSfDdJ3jAdEVSALS2VUPOUyqn48oZmb2TL/O7t7/PQm5v4NQujYEPLPMTLn9KVw6H7twwbTA==", + "license": "MIT", + "peerDependencies": { + "expo-font": ">=14.0.4", + "react": "*", + "react-native": "*" + } + }, + "node_modules/expo/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/expo/node_modules/babel-preset-expo": { + "version": "54.0.6", + "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-54.0.6.tgz", + "integrity": "sha512-GxJfwnuOPQJbzDe5WASJZdNQiukLw7i9z+Lh6JQWkUHXsShHyQrqgiKE55MD/KaP9VqJ70yZm7bYqOu8zwcWqQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/plugin-proposal-decorators": "^7.12.9", + "@babel/plugin-proposal-export-default-from": "^7.24.7", + "@babel/plugin-syntax-export-default-from": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.27.1", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-flow-strip-types": "^7.25.2", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-runtime": "^7.24.7", + "@babel/preset-react": "^7.22.15", + "@babel/preset-typescript": "^7.23.0", + "@react-native/babel-preset": "0.81.5", + "babel-plugin-react-compiler": "^1.0.0", + "babel-plugin-react-native-web": "~0.21.0", + "babel-plugin-syntax-hermes-parser": "^0.29.1", + "babel-plugin-transform-flow-enums": "^0.0.2", + "debug": "^4.3.4", + "resolve-from": "^5.0.0" + }, + "peerDependencies": { + "@babel/runtime": "^7.20.0", + "expo": "*", + "react-refresh": ">=0.14.0 <1.0.0" + }, + "peerDependenciesMeta": { + "@babel/runtime": { + "optional": true + }, + "expo": { + "optional": true + } + } + }, + "node_modules/expo/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/expo/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/expo/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/expo/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==", + "license": "MIT" + }, + "node_modules/expo/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==", + "license": "MIT" + }, + "node_modules/expo/node_modules/expo-asset": { + "version": "12.0.9", + "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-12.0.9.tgz", + "integrity": "sha512-vrdRoyhGhBmd0nJcssTSk1Ypx3Mbn/eXaaBCQVkL0MJ8IOZpAObAjfD5CTy8+8RofcHEQdh3wwZVCs7crvfOeg==", + "license": "MIT", + "dependencies": { + "@expo/image-utils": "^0.8.7", + "expo-constants": "~18.0.9" + }, + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*" + } + }, + "node_modules/expo/node_modules/expo-constants": { + "version": "18.0.10", + "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-18.0.10.tgz", + "integrity": "sha512-Rhtv+X974k0Cahmvx6p7ER5+pNhBC0XbP1lRviL2J1Xl4sT2FBaIuIxF/0I0CbhOsySf0ksqc5caFweAy9Ewiw==", + "license": "MIT", + "dependencies": { + "@expo/config": "~12.0.10", + "@expo/env": "~2.0.7" + }, + "peerDependencies": { + "expo": "*", + "react-native": "*" + } + }, + "node_modules/expo/node_modules/expo-file-system": { + "version": "19.0.17", + "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-19.0.17.tgz", + "integrity": "sha512-WwaS01SUFrxBnExn87pg0sCTJjZpf2KAOzfImG0o8yhkU7fbYpihpl/oocXBEsNbj58a8hVt1Y4CVV5c1tzu/g==", + "license": "MIT", + "peerDependencies": { + "expo": "*", + "react-native": "*" + } + }, + "node_modules/expo/node_modules/expo-font": { + "version": "14.0.9", + "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.9.tgz", + "integrity": "sha512-xCoQbR/36qqB6tew/LQ6GWICpaBmHLhg/Loix5Rku/0ZtNaXMJv08M9o1AcrdiGTn/Xf/BnLu6DgS45cWQEHZg==", + "license": "MIT", + "dependencies": { + "fontfaceobserver": "^2.1.0" + }, + "peerDependencies": { + "expo": "*", + "react": "*", + "react-native": "*" + } + }, + "node_modules/expo/node_modules/expo-keep-awake": { + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-15.0.7.tgz", + "integrity": "sha512-CgBNcWVPnrIVII5G54QDqoE125l+zmqR4HR8q+MQaCfHet+dYpS5vX5zii/RMayzGN4jPgA4XYIQ28ePKFjHoA==", + "license": "MIT", + "peerDependencies": { + "expo": "*", + "react": "*" + } + }, + "node_modules/expo/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/expo/node_modules/hermes-estree": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.29.1.tgz", + "integrity": "sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==", + "license": "MIT" + }, + "node_modules/expo/node_modules/hermes-parser": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.29.1.tgz", + "integrity": "sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==", + "license": "MIT", + "dependencies": { + "hermes-estree": "0.29.1" + } + }, + "node_modules/expo/node_modules/picomatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", + "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/expo/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==", + "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/expo/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==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/expo/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/expo/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "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/expo/node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "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/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "license": "Apache-2.0" + }, + "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==", + "license": "MIT" + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fbjs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz", + "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==", + "license": "MIT", + "dependencies": { + "cross-fetch": "^3.1.5", + "fbjs-css-vars": "^1.0.0", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^1.0.35" + } + }, + "node_modules/fbjs-css-vars": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==", + "license": "MIT" + }, + "node_modules/fbjs/node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "license": "MIT", + "dependencies": { + "asap": "~2.0.3" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flow-enums-runtime": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz", + "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==", + "license": "MIT" + }, + "node_modules/fontfaceobserver": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz", + "integrity": "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==", + "license": "BSD-2-Clause" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/freeport-async": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/freeport-async/-/freeport-async-2.0.0.tgz", + "integrity": "sha512-K7od3Uw45AJg00XUmy15+Hae2hOcgKcmN3/EF6Y7i01O0gaqiRx8sUSpsb9+BRNL8RPBrhzPsVfy8q9ADlJuWQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.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==", + "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==", + "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==", + "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==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/getenv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/getenv/-/getenv-2.0.0.tgz", + "integrity": "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "license": "MIT", + "dependencies": { + "ini": "^1.3.4" + }, + "engines": { + "node": ">=4" + } + }, + "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/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==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hermes-estree": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.32.0.tgz", + "integrity": "sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ==", + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.32.0.tgz", + "integrity": "sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw==", + "license": "MIT", + "dependencies": { + "hermes-estree": "0.32.0" + } + }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/hyphenate-style-name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", + "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", + "license": "BSD-3-Clause" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz", + "integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==", + "license": "MIT", + "dependencies": { + "queue": "6.0.2" + }, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "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.", + "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==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/inline-style-prefixer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz", + "integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==", + "license": "MIT", + "dependencies": { + "css-in-js-utils": "^3.1.0" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/jest-message-util/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-message-util/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/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==", + "license": "MIT" + }, + "node_modules/jest-message-util/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-util/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/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==", + "license": "MIT" + }, + "node_modules/jest-util/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/jest-validate/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/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==", + "license": "MIT" + }, + "node_modules/jest-validate/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jimp-compact": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/jimp-compact/-/jimp-compact-0.16.1.tgz", + "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==", + "license": "MIT" + }, + "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": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsc-safe-url": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz", + "integrity": "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==", + "license": "0BSD" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lan-network": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/lan-network/-/lan-network-0.1.7.tgz", + "integrity": "sha512-mnIlAEMu4OyEvUNdzco9xpuB9YVcPkQec+QsgycBCtPZvEqWPCDPfbAE4OJMdBBWpZWtpCn1xw9jJYlwjWI5zQ==", + "license": "MIT", + "bin": { + "lan-network": "dist/lan-network-cli.js" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lighthouse-logger": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz", + "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==", + "license": "Apache-2.0", + "dependencies": { + "debug": "^2.6.9", + "marky": "^1.2.2" + } + }, + "node_modules/lighthouse-logger/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/lighthouse-logger/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/lightningcss": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" + }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "license": "MIT", + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "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/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==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/marky": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz", + "integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==", + "license": "Apache-2.0" + }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/metro": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.83.2.tgz", + "integrity": "sha512-HQgs9H1FyVbRptNSMy/ImchTTE5vS2MSqLoOo7hbDoBq6hPPZokwJvBMwrYSxdjQZmLXz2JFZtdvS+ZfgTc9yw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/core": "^7.25.2", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.3", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.3", + "@babel/types": "^7.25.2", + "accepts": "^1.3.7", + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "connect": "^3.6.5", + "debug": "^4.4.0", + "error-stack-parser": "^2.0.6", + "flow-enums-runtime": "^0.0.6", + "graceful-fs": "^4.2.4", + "hermes-parser": "0.32.0", + "image-size": "^1.0.2", + "invariant": "^2.2.4", + "jest-worker": "^29.7.0", + "jsc-safe-url": "^0.2.2", + "lodash.throttle": "^4.1.1", + "metro-babel-transformer": "0.83.2", + "metro-cache": "0.83.2", + "metro-cache-key": "0.83.2", + "metro-config": "0.83.2", + "metro-core": "0.83.2", + "metro-file-map": "0.83.2", + "metro-resolver": "0.83.2", + "metro-runtime": "0.83.2", + "metro-source-map": "0.83.2", + "metro-symbolicate": "0.83.2", + "metro-transform-plugins": "0.83.2", + "metro-transform-worker": "0.83.2", + "mime-types": "^2.1.27", + "nullthrows": "^1.1.1", + "serialize-error": "^2.1.0", + "source-map": "^0.5.6", + "throat": "^5.0.0", + "ws": "^7.5.10", + "yargs": "^17.6.2" + }, + "bin": { + "metro": "src/cli.js" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro-babel-transformer": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.83.2.tgz", + "integrity": "sha512-rirY1QMFlA1uxH3ZiNauBninwTioOgwChnRdDcbB4tgRZ+bGX9DiXoh9QdpppiaVKXdJsII932OwWXGGV4+Nlw==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "flow-enums-runtime": "^0.0.6", + "hermes-parser": "0.32.0", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro-cache": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.83.2.tgz", + "integrity": "sha512-Z43IodutUZeIS7OTH+yQFjc59QlFJ6s5OvM8p2AP9alr0+F8UKr8ADzFzoGKoHefZSKGa4bJx7MZJLF6GwPDHQ==", + "license": "MIT", + "dependencies": { + "exponential-backoff": "^3.1.1", + "flow-enums-runtime": "^0.0.6", + "https-proxy-agent": "^7.0.5", + "metro-core": "0.83.2" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro-cache-key": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.83.2.tgz", + "integrity": "sha512-3EMG/GkGKYoTaf5RqguGLSWRqGTwO7NQ0qXKmNBjr0y6qD9s3VBXYlwB+MszGtmOKsqE9q3FPrE5Nd9Ipv7rZw==", + "license": "MIT", + "dependencies": { + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro-config": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.83.2.tgz", + "integrity": "sha512-1FjCcdBe3e3D08gSSiU9u3Vtxd7alGH3x/DNFqWDFf5NouX4kLgbVloDDClr1UrLz62c0fHh2Vfr9ecmrOZp+g==", + "license": "MIT", + "dependencies": { + "connect": "^3.6.5", + "flow-enums-runtime": "^0.0.6", + "jest-validate": "^29.7.0", + "metro": "0.83.2", + "metro-cache": "0.83.2", + "metro-core": "0.83.2", + "metro-runtime": "0.83.2", + "yaml": "^2.6.1" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro-core": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.83.2.tgz", + "integrity": "sha512-8DRb0O82Br0IW77cNgKMLYWUkx48lWxUkvNUxVISyMkcNwE/9ywf1MYQUE88HaKwSrqne6kFgCSA/UWZoUT0Iw==", + "license": "MIT", + "dependencies": { + "flow-enums-runtime": "^0.0.6", + "lodash.throttle": "^4.1.1", + "metro-resolver": "0.83.2" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro-file-map": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.83.2.tgz", + "integrity": "sha512-cMSWnEqZrp/dzZIEd7DEDdk72PXz6w5NOKriJoDN9p1TDQ5nAYrY2lHi8d6mwbcGLoSlWmpPyny9HZYFfPWcGQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "fb-watchman": "^2.0.0", + "flow-enums-runtime": "^0.0.6", + "graceful-fs": "^4.2.4", + "invariant": "^2.2.4", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "nullthrows": "^1.1.1", + "walker": "^1.0.7" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro-minify-terser": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.83.2.tgz", + "integrity": "sha512-zvIxnh7U0JQ7vT4quasKsijId3dOAWgq+ip2jF/8TMrPUqQabGrs04L2dd0haQJ+PA+d4VvK/bPOY8X/vL2PWw==", + "license": "MIT", + "dependencies": { + "flow-enums-runtime": "^0.0.6", + "terser": "^5.15.0" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro-resolver": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.83.2.tgz", + "integrity": "sha512-Yf5mjyuiRE/Y+KvqfsZxrbHDA15NZxyfg8pIk0qg47LfAJhpMVEX+36e6ZRBq7KVBqy6VDX5Sq55iHGM4xSm7Q==", + "license": "MIT", + "dependencies": { + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro-runtime": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.83.2.tgz", + "integrity": "sha512-nnsPtgRvFbNKwemqs0FuyFDzXLl+ezuFsUXDbX8o0SXOfsOPijqiQrf3kuafO1Zx1aUWf4NOrKJMAQP5EEHg9A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.0", + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro-source-map": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.83.2.tgz", + "integrity": "sha512-5FL/6BSQvshIKjXOennt9upFngq2lFvDakZn5LfauIVq8+L4sxXewIlSTcxAtzbtjAIaXeOSVMtCJ5DdfCt9AA==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.3", + "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3", + "@babel/types": "^7.25.2", + "flow-enums-runtime": "^0.0.6", + "invariant": "^2.2.4", + "metro-symbolicate": "0.83.2", + "nullthrows": "^1.1.1", + "ob1": "0.83.2", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro-symbolicate": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.83.2.tgz", + "integrity": "sha512-KoU9BLwxxED6n33KYuQQuc5bXkIxF3fSwlc3ouxrrdLWwhu64muYZNQrukkWzhVKRNFIXW7X2iM8JXpi2heIPw==", + "license": "MIT", + "dependencies": { + "flow-enums-runtime": "^0.0.6", + "invariant": "^2.2.4", + "metro-source-map": "0.83.2", + "nullthrows": "^1.1.1", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + }, + "bin": { + "metro-symbolicate": "src/index.js" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro-transform-plugins": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.83.2.tgz", + "integrity": "sha512-5WlW25WKPkiJk2yA9d8bMuZrgW7vfA4f4MBb9ZeHbTB3eIAoNN8vS8NENgG/X/90vpTB06X66OBvxhT3nHwP6A==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/generator": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.3", + "flow-enums-runtime": "^0.0.6", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro-transform-worker": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.83.2.tgz", + "integrity": "sha512-G5DsIg+cMZ2KNfrdLnWMvtppb3+Rp1GMyj7Bvd9GgYc/8gRmvq1XVEF9XuO87Shhb03kFhGqMTgZerz3hZ1v4Q==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.3", + "@babel/types": "^7.25.2", + "flow-enums-runtime": "^0.0.6", + "metro": "0.83.2", + "metro-babel-transformer": "0.83.2", + "metro-cache": "0.83.2", + "metro-cache-key": "0.83.2", + "metro-minify-terser": "0.83.2", + "metro-source-map": "0.83.2", + "metro-transform-plugins": "0.83.2", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "node_modules/metro/node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/metro/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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/metro/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/metro/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/metro/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==", + "license": "MIT" + }, + "node_modules/metro/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/metro/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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "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==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "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": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "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==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "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==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "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/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nested-error-stacks": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.0.1.tgz", + "integrity": "sha512-SrQrok4CATudVzBS7coSz26QRSmlK9TzzoFbeKfcPBUFPjcQM9Rqvr/DlJkOrwI/0KcgvMub1n1g5Jt9EgRn4A==", + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "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==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-package-arg": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz", + "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==", + "license": "ISC", + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "license": "MIT" + }, + "node_modules/ob1": { + "version": "0.83.2", + "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.83.2.tgz", + "integrity": "sha512-XlK3w4M+dwd1g1gvHzVbxiXEbUllRONEgcF2uEO0zm4nxa0eKlh41c6N65q1xbiDOeKKda1tvNOAD33fNjyvCg==", + "license": "MIT", + "dependencies": { + "flow-enums-runtime": "^0.0.6" + }, + "engines": { + "node": ">=20.19.4" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", + "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-spinners": "^2.0.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "node_modules/parse-png": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-png/-/parse-png-2.1.0.tgz", + "integrity": "sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ==", + "license": "MIT", + "dependencies": { + "pngjs": "^3.3.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "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==", + "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==", + "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==", + "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==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-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==", + "license": "MIT" + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "license": "MIT", + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "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/qrcode-terminal": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz", + "integrity": "sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==", + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "license": "MIT", + "dependencies": { + "inherits": "~2.0.3" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/react": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-devtools-core": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.5.tgz", + "integrity": "sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==", + "license": "MIT", + "dependencies": { + "shell-quote": "^1.6.1", + "ws": "^7" + } + }, + "node_modules/react-dom": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", + "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.26.0" + }, + "peerDependencies": { + "react": "^19.1.0" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/react-native": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.81.5.tgz", + "integrity": "sha512-1w+/oSjEXZjMqsIvmkCRsOc8UBYv163bTWKTI8+1mxztvQPhCRYGTvZ/PL1w16xXHneIj/SLGfxWg2GWN2uexw==", + "license": "MIT", + "dependencies": { + "@jest/create-cache-key-function": "^29.7.0", + "@react-native/assets-registry": "0.81.5", + "@react-native/codegen": "0.81.5", + "@react-native/community-cli-plugin": "0.81.5", + "@react-native/gradle-plugin": "0.81.5", + "@react-native/js-polyfills": "0.81.5", + "@react-native/normalize-colors": "0.81.5", + "@react-native/virtualized-lists": "0.81.5", + "abort-controller": "^3.0.0", + "anser": "^1.4.9", + "ansi-regex": "^5.0.0", + "babel-jest": "^29.7.0", + "babel-plugin-syntax-hermes-parser": "0.29.1", + "base64-js": "^1.5.1", + "commander": "^12.0.0", + "flow-enums-runtime": "^0.0.6", + "glob": "^7.1.1", + "invariant": "^2.2.4", + "jest-environment-node": "^29.7.0", + "memoize-one": "^5.0.0", + "metro-runtime": "^0.83.1", + "metro-source-map": "^0.83.1", + "nullthrows": "^1.1.1", + "pretty-format": "^29.7.0", + "promise": "^8.3.0", + "react-devtools-core": "^6.1.5", + "react-refresh": "^0.14.0", + "regenerator-runtime": "^0.13.2", + "scheduler": "0.26.0", + "semver": "^7.1.3", + "stacktrace-parser": "^0.1.10", + "whatwg-fetch": "^3.0.0", + "ws": "^6.2.3", + "yargs": "^17.6.2" + }, + "bin": { + "react-native": "cli.js" + }, + "engines": { + "node": ">= 20.19.4" + }, + "peerDependencies": { + "@types/react": "^19.1.0", + "react": "^19.1.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-native-is-edge-to-edge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz", + "integrity": "sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q==", + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-web": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.2.tgz", + "integrity": "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.6", + "@react-native/normalize-colors": "^0.74.1", + "fbjs": "^3.0.4", + "inline-style-prefixer": "^7.0.1", + "memoize-one": "^6.0.0", + "nullthrows": "^1.1.1", + "postcss-value-parser": "^4.2.0", + "styleq": "^0.1.3" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-native-web/node_modules/@react-native/normalize-colors": { + "version": "0.74.89", + "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.89.tgz", + "integrity": "sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg==", + "license": "MIT" + }, + "node_modules/react-native-web/node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "license": "MIT" + }, + "node_modules/react-native/node_modules/@react-native/virtualized-lists": { + "version": "0.81.5", + "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.81.5.tgz", + "integrity": "sha512-UVXgV/db25OPIvwZySeToXD/9sKKhOdkcWmmf4Jh8iBZuyfML+/5CasaZ1E7Lqg6g3uqVQq75NqIwkYmORJMPw==", + "license": "MIT", + "dependencies": { + "invariant": "^2.2.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 20.19.4" + }, + "peerDependencies": { + "@types/react": "^19.1.0", + "react": "*", + "react-native": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-native/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/react-native/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/react-native/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", + "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/react-native/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/react-native/node_modules/ws": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", + "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", + "license": "MIT", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT" + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", + "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requireg": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/requireg/-/requireg-0.2.2.tgz", + "integrity": "sha512-nYzyjnFcPNGR3lx9lwPPPnuQxv6JWEZd2Ci0u9opN7N5zUEPIhY/GbL3vMGOr2UXwEg9WwSyV9X9Y/kLFgPsOg==", + "dependencies": { + "nested-error-stacks": "~2.0.1", + "rc": "~1.2.7", + "resolve": "~1.7.1" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/requireg/node_modules/resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "license": "MIT", + "dependencies": { + "path-parse": "^1.0.5" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-global": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", + "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", + "license": "MIT", + "dependencies": { + "global-dirs": "^0.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-workspace-root/-/resolve-workspace-root-2.0.0.tgz", + "integrity": "sha512-IsaBUZETJD5WsI11Wt8PKHwaIe45or6pwNc8yflvLJ4DWtImK9kuLoH5kUva/2Mmx/RdIyr4aONNSa2v9LTJsw==", + "license": "MIT" + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "license": "MIT", + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "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", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "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", + "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/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC" + }, + "node_modules/scheduler": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", + "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", + "integrity": "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "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==", + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-plist": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.1.tgz", + "integrity": "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==", + "license": "MIT", + "dependencies": { + "bplist-creator": "0.1.0", + "bplist-parser": "0.3.1", + "plist": "^3.0.5" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slugify": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", + "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "license": "MIT" + }, + "node_modules/stacktrace-parser": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz", + "integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==", + "license": "Unlicense", + "engines": { + "node": ">= 0.10.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==", + "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==", + "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==", + "license": "MIT" + }, + "node_modules/string-width-cjs/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==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-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==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/structured-headers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/structured-headers/-/structured-headers-0.4.1.tgz", + "integrity": "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==", + "license": "MIT" + }, + "node_modules/styleq": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/styleq/-/styleq-0.1.3.tgz", + "integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/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==", + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.1.tgz", + "integrity": "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==", + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz", + "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/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", + "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/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "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==", + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "license": "MIT" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "license": "BSD-3-Clause" + }, + "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==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "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==", + "license": "Apache-2.0" + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/ua-parser-js": { + "version": "1.0.41", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.41.tgz", + "integrity": "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/undici": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.22.0.tgz", + "integrity": "sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "license": "MIT", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vlq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz", + "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==", + "license": "MIT" + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "license": "MIT" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/whatwg-url-without-unicode": { + "version": "8.0.0-3", + "resolved": "https://registry.npmjs.org/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-3.tgz", + "integrity": "sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==", + "license": "MIT", + "dependencies": { + "buffer": "^5.4.3", + "punycode": "^2.1.1", + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/whatwg-url/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wonka": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.5.tgz", + "integrity": "sha512-SSil+ecw6B4/Dm7Pf2sAshKQ5hWFvfyGlfPbEd6A14dOH6VDjrmbY86u6nZvy9omGwwIPFR8V41+of1EezgoUw==", + "license": "MIT" + }, + "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==", + "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==", + "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/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/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==", + "license": "MIT" + }, + "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==", + "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==", + "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-cjs/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==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?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==", + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xcode": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz", + "integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==", + "license": "Apache-2.0", + "dependencies": { + "simple-plist": "^1.1.0", + "uuid": "^7.0.3" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/xml2js": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.0.tgz", + "integrity": "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==", + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml2js/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "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/yargs/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==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.24.6", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", + "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.24.1" + } + } + } +} diff --git a/mobile/package.json b/mobile/package.json new file mode 100644 index 0000000..2d7ca12 --- /dev/null +++ b/mobile/package.json @@ -0,0 +1,20 @@ +{ + "name": "mobile", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "start": "expo start", + "android": "expo start --android", + "ios": "expo start --ios", + "web": "expo start --web" + }, + "dependencies": { + "expo": "~54.0.20", + "expo-status-bar": "~3.0.8", + "react": "19.1.0", + "react-dom": "19.1.0", + "react-native": "0.81.5", + "react-native-web": "^0.21.0" + }, + "private": true +} diff --git a/web/.gitignore b/web/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/web/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/web/README.md b/web/README.md new file mode 100644 index 0000000..3dfe94e --- /dev/null +++ b/web/README.md @@ -0,0 +1,109 @@ +# 🚀 MONAI MLOps Console Frontend (DDO Console) + +Frontend Console สำหรับการจัดการ **AI Model Registry**, **MLOps Pipeline**, และการเรียกใช้งาน **AI Inference Service** +รองรับงาน **Medical Imaging** โดยเชื่อมต่อกับ Backend หลักที่เป็น **Django DRF** (Lightweight Gateway/Security) +และระบบ AI inference บน **FastAPI/MONAI** + +--- + +## 💡 สถาปัตยกรรมและเทคโนโลยีหลัก + +| องค์ประกอบ | เทคโนโลยี | บทบาท / เหตุผล | +| :--- |:-----------------------------------------------| :--- | +| **Framework** | 🧩 **React (Vite)** | ความเร็วสูง, Hot Reload, โครงสร้าง Component-Based | +| **Styling** | 🎨 **Tailwind CSS + DaisyUI** | Utility-first CSS พร้อมชุด Component ที่สวยงาม | +| **Server State / Data Fetching** | ⚙️ **TanStack Query (React Query)** | จัดการ Cache, Loading, Error, และ Data Synchronization | +| **Form Handling** | 🧠 **React Hook Form + Yup** | Validation ที่มีประสิทธิภาพ, ลดการ re-render | +| **Security Flow** | 🔐 **JWT + Axios Interceptor + Refresh Token** | ใช้ `axiosClient` จัดการ Token, Refresh Token, และ Force Logout | + +--- + +## 🧱 โครงสร้างโปรเจกต์ (Clean Architecture) + +โปรเจกต์นี้ใช้แนวทาง **Clean Architecture + Modularization** +เพื่อให้ดูแลและขยายระบบได้ง่ายในระยะยาว + +| โฟลเดอร์ | หน้าที่ | +| :--- | :--- | +| `src/routes/` | กำหนด Routing เช่น `AuthRoutes`, `PrivateRoutes`, และ `ProtectedRoute` | +| `src/services/` | เก็บ Hooks สำหรับเรียก API (`useModelList`, `useRunInferenceMutation`) และ `axiosClient` | +| `src/schemas/` | เก็บ **Yup Schemas** สำหรับตรวจสอบข้อมูลจากฟอร์ม | +| `src/features/` | เก็บ Redux Slice เช่น `authSlice` สำหรับจัดการ state ระดับ global | +| `src/pages/` | เก็บ Component หลักของแต่ละหน้า เช่น Dashboard, Model Registry | +| `src/components/` | Component ที่ใช้ซ้ำได้ เช่น Modal, Table, Input (RHF Adapter) | + +--- + +## 🧩 Role-Based Access Control (RBAC) + +ระบบมีการควบคุมสิทธิ์ทั้งฝั่ง Backend และ Frontend: + +- **Backend (Django DRF):** + ใช้ Custom Permission Class (`IsAdminOrManager`) เพื่อจำกัดการเข้าถึง API +- **Frontend (React):** + ใช้ Role จาก JWT เพื่อกรองเมนูใน `sidebarRoutes.jsx` + และควบคุมการเข้าถึงหน้าใน `MainLayout.jsx` + +| Role | สิทธิ์ | +| :--- | :--- | +| `admin` | เข้าถึงทุกเมนู และสามารถจัดการผู้ใช้งานได้ | +| `manager` | เข้าถึงหน้า Model Registry และ Pipeline Management | +| `viewer` | อ่านข้อมูลเท่านั้น | + +--- + +## ⚙️ การติดตั้งและเริ่มต้นใช้งาน + +### 🔧 Prerequisites + +- Node.js `v18+` +- npm หรือ yarn + +--- + +### 🧰 1. ติดตั้ง Dependencies + +```bash +npm install +``` + +### ⚙️ 2. ตั้งค่า Environment Variables + +สร้างไฟล์ .env.local ใน Root Directory +และกำหนด Base URL ของ Django DRF API Gateway: + +.env.local + +VITE_API_BASE_URL=http://localhost:8000 + +หรือ URL จริงของ API Gateway + +### 🧠 3. รัน Development Server +```bash +npm run dev +``` + +🌐 แอปจะรันที่ http://localhost:5173 + +และจะ Redirect ไปที่หน้า Login ทันที เพื่อบังคับยืนยันตัวตนก่อนเข้า Console + +## 🧩 Best Practices & Design Principles + +ใช้ Atomic Design Pattern สำหรับการออกแบบ Component + +ใช้ TanStack Query DevTools เพื่อ Debug API Cache ได้ง่าย + +รองรับการเพิ่ม Theme (ผ่าน DaisyUI Theme Config) + +แยก Business Logic ออกจาก UI เพื่อให้ทดสอบได้ง่าย + +## 📘 License + +Distributed under the MIT License. +See LICENSE for more information. + +## 👨‍💻 Authors + +FlookSP — DDD Project + +“Building Trustworthy AI Infrastructure for Medical Data Operations.” \ No newline at end of file diff --git a/web/eslint.config.js b/web/eslint.config.js new file mode 100644 index 0000000..cee1e2c --- /dev/null +++ b/web/eslint.config.js @@ -0,0 +1,29 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{js,jsx}'], + extends: [ + js.configs.recommended, + reactHooks.configs['recommended-latest'], + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + parserOptions: { + ecmaVersion: 'latest', + ecmaFeatures: { jsx: true }, + sourceType: 'module', + }, + }, + rules: { + 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }], + }, + }, +]) diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..ec5fcf3 --- /dev/null +++ b/web/index.html @@ -0,0 +1,13 @@ + + + + + + + Frontend + + +

+ + + diff --git a/web/package-lock.json b/web/package-lock.json new file mode 100644 index 0000000..5c17f5a --- /dev/null +++ b/web/package-lock.json @@ -0,0 +1,3984 @@ +{ + "name": "web", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "web", + "version": "0.0.0", + "dependencies": { + "@heroicons/react": "^2.2.0", + "@hookform/resolvers": "^5.2.2", + "@reduxjs/toolkit": "^2.10.1", + "@tailwindcss/vite": "^4.1.16", + "@tanstack/react-query": "^5.90.7", + "axios": "^1.13.2", + "daisyui": "^5.3.10", + "prop-types": "^15.8.1", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-hook-form": "^7.66.0", + "react-icons": "^5.5.0", + "react-redux": "^9.2.0", + "react-router-dom": "^7.9.5", + "tailwindcss": "^4.1.16", + "uuid": "^13.0.0", + "yup": "^1.7.1" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@types/react": "^19.1.16", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.4", + "eslint": "^9.36.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.22", + "globals": "^16.4.0", + "vite": "^7.1.7" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", + "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz", + "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz", + "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz", + "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz", + "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz", + "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz", + "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz", + "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz", + "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz", + "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz", + "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz", + "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz", + "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz", + "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz", + "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz", + "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz", + "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz", + "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz", + "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz", + "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz", + "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz", + "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz", + "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz", + "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz", + "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz", + "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/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/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers/node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", + "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.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": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.38.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.38.0.tgz", + "integrity": "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@heroicons/react": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz", + "integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==", + "license": "MIT", + "peerDependencies": { + "react": ">= 16 || ^19.0.0-rc" + } + }, + "node_modules/@hookform/resolvers": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.2.2.tgz", + "integrity": "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA==", + "license": "MIT", + "dependencies": { + "@standard-schema/utils": "^0.3.0" + }, + "peerDependencies": { + "react-hook-form": "^7.55.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.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/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.10.1.tgz", + "integrity": "sha512-/U17EXQ9Do9Yx4DlNGU6eVNfZvFJfYpUtRRdLf19PbPjdWBxNlxGZXywQZ1p1Nz8nMkWplTI7iD/23m07nolDA==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^10.2.0", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.43", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.43.tgz", + "integrity": "sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz", + "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz", + "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz", + "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz", + "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz", + "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz", + "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz", + "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz", + "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz", + "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz", + "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz", + "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz", + "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz", + "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz", + "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz", + "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz", + "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz", + "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz", + "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz", + "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz", + "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz", + "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz", + "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.16.tgz", + "integrity": "sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.6.1", + "lightningcss": "1.30.2", + "magic-string": "^0.30.19", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.16" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.16.tgz", + "integrity": "sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg==", + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.16", + "@tailwindcss/oxide-darwin-arm64": "4.1.16", + "@tailwindcss/oxide-darwin-x64": "4.1.16", + "@tailwindcss/oxide-freebsd-x64": "4.1.16", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.16", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.16", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.16", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.16", + "@tailwindcss/oxide-linux-x64-musl": "4.1.16", + "@tailwindcss/oxide-wasm32-wasi": "4.1.16", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.16", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.16" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.16.tgz", + "integrity": "sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.16.tgz", + "integrity": "sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.16.tgz", + "integrity": "sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.16.tgz", + "integrity": "sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.16.tgz", + "integrity": "sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.16.tgz", + "integrity": "sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.16.tgz", + "integrity": "sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.16.tgz", + "integrity": "sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.16.tgz", + "integrity": "sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.16.tgz", + "integrity": "sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.0.7", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.16.tgz", + "integrity": "sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.16.tgz", + "integrity": "sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.16.tgz", + "integrity": "sha512-bbguNBcDxsRmi9nnlWJxhfDWamY3lmcyACHcdO1crxfzuLpOhHLLtEIN/nCbbAtj5rchUgQD17QVAKi1f7IsKg==", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.1.16", + "@tailwindcss/oxide": "4.1.16", + "tailwindcss": "4.1.16" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.90.7", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.7.tgz", + "integrity": "sha512-6PN65csiuTNfBMXqQUxQhCNdtm1rV+9kC9YwWAIKcaxAauq3Wu7p18j3gQY3YIBJU70jT/wzCCZ2uqto/vQgiQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.90.7", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.7.tgz", + "integrity": "sha512-wAHc/cgKzW7LZNFloThyHnV/AX9gTg3w5yAv0gvQHPZoCnepwqCMtzbuPbb2UvfvO32XZ46e8bPOYbfZhzVnnQ==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.90.7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "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.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "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.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "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/react": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", + "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz", + "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.0.tgz", + "integrity": "sha512-4LuWrg7EKWgQaMJfnN+wcmbAW+VSsCmqGohftWjuct47bv8uE4n/nPpq4XjJPsxgq00GGG5J8dvBczp8uxScew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.4", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.43", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "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/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-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/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/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/axios": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.21", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.21.tgz", + "integrity": "sha512-JU0h5APyQNsHOlAM7HnQnPToSDQoEBZqzu/YBlqDnEeymPnZDREeXJA3KBMQee+dKteAxZ2AtvQEvVYdZf241Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", + "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", + "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": { + "baseline-browser-mapping": "^2.8.19", + "caniuse-lite": "^1.0.30001751", + "electron-to-chromium": "^1.5.238", + "node-releases": "^2.0.26", + "update-browserslist-db": "^1.1.4" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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/caniuse-lite": { + "version": "1.0.30001751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", + "integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/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/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/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/daisyui": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.3.10.tgz", + "integrity": "sha512-vmjyPmm0hvFhA95KB6uiGmWakziB2pBv6CUcs5Ka/3iMBMn9S+C3SZYx9G9l2JrgTZ1EFn61F/HrPcwaUm2kLQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/saadeghi/daisyui?sponsor=1" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "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/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/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.243", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.243.tgz", + "integrity": "sha512-ZCphxFW3Q1TVhcgS9blfut1PX8lusVi2SvXQgmEEnK4TCmE1JhH2JkjJN+DNt0pJJwfBri5AROBnz2b/C+YU9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", + "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.11", + "@esbuild/android-arm": "0.25.11", + "@esbuild/android-arm64": "0.25.11", + "@esbuild/android-x64": "0.25.11", + "@esbuild/darwin-arm64": "0.25.11", + "@esbuild/darwin-x64": "0.25.11", + "@esbuild/freebsd-arm64": "0.25.11", + "@esbuild/freebsd-x64": "0.25.11", + "@esbuild/linux-arm": "0.25.11", + "@esbuild/linux-arm64": "0.25.11", + "@esbuild/linux-ia32": "0.25.11", + "@esbuild/linux-loong64": "0.25.11", + "@esbuild/linux-mips64el": "0.25.11", + "@esbuild/linux-ppc64": "0.25.11", + "@esbuild/linux-riscv64": "0.25.11", + "@esbuild/linux-s390x": "0.25.11", + "@esbuild/linux-x64": "0.25.11", + "@esbuild/netbsd-arm64": "0.25.11", + "@esbuild/netbsd-x64": "0.25.11", + "@esbuild/openbsd-arm64": "0.25.11", + "@esbuild/openbsd-x64": "0.25.11", + "@esbuild/openharmony-arm64": "0.25.11", + "@esbuild/sunos-x64": "0.25.11", + "@esbuild/win32-arm64": "0.25.11", + "@esbuild/win32-ia32": "0.25.11", + "@esbuild/win32-x64": "0.25.11" + } + }, + "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": "9.38.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.38.0.tgz", + "integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.1", + "@eslint/core": "^0.16.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.38.0", + "@eslint/plugin-kit": "^0.4.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "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 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.24.tgz", + "integrity": "sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.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/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/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-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/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "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": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "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==", + "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-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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/globals": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", + "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "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/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-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "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==", + "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==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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/immer": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz", + "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "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/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-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/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/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "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": "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/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/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/lightningcss": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "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/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "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/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/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "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/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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/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-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/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "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.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", + "license": "MIT" + }, + "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/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", + "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", + "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.0" + } + }, + "node_modules/react-hook-form": { + "version": "7.66.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.66.0.tgz", + "integrity": "sha512-xXBqsWGKrY46ZqaHDo+ZUYiMUgi8suYu5kdrS20EG8KiL7VRQitEbNjm+UcrDYrNi1YLyfpmAeGjCZYXLT9YBw==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.5.tgz", + "integrity": "sha512-JmxqrnBZ6E9hWmf02jzNn9Jm3UqyeimyiwzD69NjxGySG6lIz/1LVPsoTCwN7NBX2XjCEa1LIX5EMz1j2b6u6A==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.5.tgz", + "integrity": "sha512-mkEmq/K8tKN63Ae2M7Xgz3c9l9YNbY+NHH6NNeUmLA3kDkhKXRsNb/ZpxaEunvGo2/3YXdk5EJU3Hxp3ocaBPw==", + "license": "MIT", + "dependencies": { + "react-router": "7.9.5" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, + "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/rollup": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", + "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.5", + "@rollup/rollup-android-arm64": "4.52.5", + "@rollup/rollup-darwin-arm64": "4.52.5", + "@rollup/rollup-darwin-x64": "4.52.5", + "@rollup/rollup-freebsd-arm64": "4.52.5", + "@rollup/rollup-freebsd-x64": "4.52.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", + "@rollup/rollup-linux-arm-musleabihf": "4.52.5", + "@rollup/rollup-linux-arm64-gnu": "4.52.5", + "@rollup/rollup-linux-arm64-musl": "4.52.5", + "@rollup/rollup-linux-loong64-gnu": "4.52.5", + "@rollup/rollup-linux-ppc64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-musl": "4.52.5", + "@rollup/rollup-linux-s390x-gnu": "4.52.5", + "@rollup/rollup-linux-x64-gnu": "4.52.5", + "@rollup/rollup-linux-x64-musl": "4.52.5", + "@rollup/rollup-openharmony-arm64": "4.52.5", + "@rollup/rollup-win32-arm64-msvc": "4.52.5", + "@rollup/rollup-win32-ia32-msvc": "4.52.5", + "@rollup/rollup-win32-x64-gnu": "4.52.5", + "@rollup/rollup-win32-x64-msvc": "4.52.5", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "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/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "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/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "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/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/tailwindcss": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.16.tgz", + "integrity": "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA==", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", + "license": "MIT" + }, + "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": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.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/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/uuid": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz", + "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist-node/bin/uuid" + } + }, + "node_modules/vite": { + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz", + "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "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/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/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/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" + } + }, + "node_modules/yup": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz", + "integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==", + "license": "MIT", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + } + } +} diff --git a/web/package.json b/web/package.json new file mode 100644 index 0000000..48da0d4 --- /dev/null +++ b/web/package.json @@ -0,0 +1,42 @@ +{ + "name": "web", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@heroicons/react": "^2.2.0", + "@hookform/resolvers": "^5.2.2", + "@reduxjs/toolkit": "^2.10.1", + "@tailwindcss/vite": "^4.1.16", + "@tanstack/react-query": "^5.90.7", + "axios": "^1.13.2", + "daisyui": "^5.3.10", + "prop-types": "^15.8.1", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-hook-form": "^7.66.0", + "react-icons": "^5.5.0", + "react-redux": "^9.2.0", + "react-router-dom": "^7.9.5", + "tailwindcss": "^4.1.16", + "uuid": "^13.0.0", + "yup": "^1.7.1" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@types/react": "^19.1.16", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.4", + "eslint": "^9.36.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.22", + "globals": "^16.4.0", + "vite": "^7.1.7" + } +} diff --git a/web/public/favicon-32x32.svg b/web/public/favicon-32x32.svg new file mode 100644 index 0000000..70627f0 --- /dev/null +++ b/web/public/favicon-32x32.svg @@ -0,0 +1,16 @@ + + + +Created with Fabric.js 2.4.6 + + + + + + + + + DDO + + + \ No newline at end of file diff --git a/web/public/intro.png b/web/public/intro.png new file mode 100644 index 0000000000000000000000000000000000000000..001ec91dd7828eda40c7db88590cf1af5091e07a GIT binary patch literal 189330 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 fCgcAdW3FH$gW^&hxOIK#WFgIV($@~6-f>OC* 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 LEyWM=7D4|HD{$3J literal 0 HcmV?d00001 diff --git a/web/public/vite.svg b/web/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/web/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/src/App.jsx b/web/src/App.jsx new file mode 100644 index 0000000..a355717 --- /dev/null +++ b/web/src/App.jsx @@ -0,0 +1,23 @@ +import { BrowserRouter, Route, Routes } from "react-router-dom"; + +import AuthRoutes from "./routes/AuthRoutes.jsx"; +import PrivateRoutes from "./routes/PrivateRoutes.jsx"; +import ToastNotification from './components/ToastNotification.jsx'; + +function App() { + return ( + // ต้องห่อหุ้มด้วย Provider ของ Redux และ QueryClient ใน main.jsx + + + + {/* Private Routes: ตรวจสอบล็อกอินก่อนเข้า /dashboard/* */} + }/> + + {/* Auth Routes: สำหรับ /login, /register และเป็น Fallback หลัก */} + }/> + + + ) +} + +export default App \ No newline at end of file diff --git a/web/src/app/store.js b/web/src/app/store.js new file mode 100644 index 0000000..244f389 --- /dev/null +++ b/web/src/app/store.js @@ -0,0 +1,25 @@ +import { configureStore } from '@reduxjs/toolkit'; +import authReducer from '../features/auth/authSlice'; +import toastReducer from '../features/toast/toastSlice'; + +export const store = configureStore({ + reducer: { + // กำหนด Reducer หลัก + auth: authReducer, + toast: toastReducer, + // [เพิ่ม Reducer อื่น ๆ ที่นี่] + }, + // ปิด serializableCheck ใน Production เพื่อประสิทธิภาพ + middleware: (getDefaultMiddleware) => getDefaultMiddleware({ + serializableCheck: { + // อาจจะต้องยกเว้น action types บางตัวที่ไม่ serialize ได้ + }, + }), + // ใน Vite ตัวแปร import.meta.env.MODE จะถูก ตั้งค่าให้อัตโนมัติ ตามคำสั่งที่ใช้ตอนรัน เช่น + // vite หรือ npm run dev "development" + // vite build หรือ npm run build "production" + devTools: import.meta.env.MODE !== 'production', +}); + +// Export ฟังก์ชันเพื่อให้ Components ภายนอก (เช่น axiosClient) เข้าถึง store instance ได้ +export const getStore = () => store; \ No newline at end of file diff --git a/web/src/assets/react.svg b/web/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/web/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/src/components/ConfirmModal.jsx b/web/src/components/ConfirmModal.jsx new file mode 100644 index 0000000..a24fb4c --- /dev/null +++ b/web/src/components/ConfirmModal.jsx @@ -0,0 +1,50 @@ +import React from 'react'; +import { FaTrash, FaTimesCircle } from 'react-icons/fa'; // Icons + +export default function ConfirmModal({ message, onConfirm, onCancel, isOpen, isDeleting }) { + + // ใช้ open={isOpen} ใน

เพื่อควบคุมการแสดงผล + if (!isOpen) return null; + + return ( + // Div ครอบคลุมจอทั้งหมด (Backdrop) +
+ +
+ + {/* Header/Title */} +

+ + ยืนยันการลบข้อมูล +

+ + {/* Message Body */} +

{message}

+ + {/* Action Buttons */} +
+ {/* ปุ่มยกเลิก */} + + + {/* ปุ่มยืนยันการลบ */} + +
+
+
+
+ ); +} \ No newline at end of file diff --git a/web/src/components/ErrorText.jsx b/web/src/components/ErrorText.jsx new file mode 100644 index 0000000..a477498 --- /dev/null +++ b/web/src/components/ErrorText.jsx @@ -0,0 +1,17 @@ +import React from 'react'; + +function ErrorText({ children, styleClass }) { + const defaultClasses = "p-3 bg-red-100 text-red-600 rounded-lg text-sm font-medium border border-red-300 break-words whitespace-normal"; + + return ( + <> + {children && ( +

+ {children} +

+ )} + + ); +} + +export default ErrorText; diff --git a/web/src/components/FileUploadAndSubmit.jsx b/web/src/components/FileUploadAndSubmit.jsx new file mode 100644 index 0000000..39a9b15 --- /dev/null +++ b/web/src/components/FileUploadAndSubmit.jsx @@ -0,0 +1,34 @@ +import React from 'react'; + +// ใน component นี้ เราจะจัดการแค่ UI/Input/Button และเรียก onSubmit() ที่มาจาก parent +export default function FileUploadAndSubmit({ file, setFile, isPending, onSubmit, selectedModelId }) { + + // กำหนดว่าปุ่มควรถูก Disable หรือไม่ + const isDisabled = isPending || !selectedModelId || !file; + + return ( +
+ {/* File Upload */} +
+ + setFile(e.target.files[0])} + /> +
+ + {/* Submit */} + +
+ ); +} \ No newline at end of file diff --git a/web/src/components/Health/InfraStatusCard.jsx b/web/src/components/Health/InfraStatusCard.jsx new file mode 100644 index 0000000..d4da7c8 --- /dev/null +++ b/web/src/components/Health/InfraStatusCard.jsx @@ -0,0 +1,36 @@ +import React from 'react'; +import TitleCard from '../TitleCard'; +import { FaDatabase, FaServer, FaFlask } from 'react-icons/fa'; +import ServiceStatus from '../ServiceStatus'; + +const infrastructureServicesMap = [ + { key: 'database', name: 'CockroachDB', icon: FaDatabase }, + { key: 'cache', name: 'Redis Cache', icon: FaServer }, + { key: 'storage', name: 'MinIO S3', icon: FaServer }, + { key: 'ai_service', name: 'MONAI FastAPI (Instance)', icon: FaFlask }, +]; + +const InfraStatusCard = ({ serviceData }) => { + return ( +
+

Infrastructure Status

+
+ {infrastructureServicesMap.map((service) => { + const svc = serviceData?.[service.key]; + if (!svc) return null; + return ( + + ); + })} +
+
+ ); +}; + +export default InfraStatusCard; \ No newline at end of file diff --git a/web/src/components/Health/ModelEndpointList.jsx b/web/src/components/Health/ModelEndpointList.jsx new file mode 100644 index 0000000..44a8c95 --- /dev/null +++ b/web/src/components/Health/ModelEndpointList.jsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { FaFlask, FaCheckCircle, FaTimesCircle } from 'react-icons/fa'; +import ServiceStatus from '../ServiceStatus'; + +const ModelEndpointsStatus = ({ modelData }) => { + const models = modelData.models || []; + + if (models.length === 0) { + return

ไม่พบ Model ที่มีสถานะ ACTIVE

; + } + + return ( +
+

+ + สถานะ Model Endpoints ({models.length} รายการ) +

+
+ {models.map((model) => ( + + ))} +
+
+ ); +}; + +export default ModelEndpointsStatus; \ No newline at end of file diff --git a/web/src/components/InputText.jsx b/web/src/components/InputText.jsx new file mode 100644 index 0000000..32ec38c --- /dev/null +++ b/web/src/components/InputText.jsx @@ -0,0 +1,28 @@ +import React, { forwardRef } from "react"; + +// ใช้ forwardRef เพื่อให้ RHF สามารถส่ง ref มาที่ input ได้ +const InputText = forwardRef( + // รับ Props ที่จำเป็นสำหรับ RHF (ref, name, value, onChange, onBlur) + // และรับ error object เพื่อแสดงข้อความ Validation + ({ labelTitle, labelStyle, type, containerStyle, placeholder, error, ...rest }, ref) => { + + return( +
+ + + {/* แสดงข้อความ Error ที่ส่งมาจาก RHF errors object */} + {error &&

{error.message}

} +
+ ); + } +); + +export default InputText; \ No newline at end of file diff --git a/web/src/components/LandingIntro.jsx b/web/src/components/LandingIntro.jsx new file mode 100644 index 0000000..a309ed4 --- /dev/null +++ b/web/src/components/LandingIntro.jsx @@ -0,0 +1,31 @@ +import TemplatePointers from "./TemplatePointers.jsx" + +function LandingIntro(){ + + return( +
+
+
+ +

+ {/* ไฟล์ logo192.png ใน /public */} + App Logo + DDO Console +

+ + {/* ไฟล์ intro.png ใน /public */} +
+ Admin Template +
+ + + +
+ +
+
+ ) + +} + +export default LandingIntro diff --git a/web/src/components/LoginForm.jsx b/web/src/components/LoginForm.jsx new file mode 100644 index 0000000..6119ad2 --- /dev/null +++ b/web/src/components/LoginForm.jsx @@ -0,0 +1,139 @@ +import { useState } from 'react'; +import { Link } from 'react-router-dom'; + +// นำเข้า Hooks และ Library ที่จำเป็น +import { useForm } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; + +// นำเข้า Hook API และ Components +import { useLoginMutation } from '../services/authApi'; +import LandingIntro from './LandingIntro'; +import InputText from './InputText'; // ตรวจสอบ Path ให้ถูกต้อง + +import { loginSchema } from '../schemas/authSchema'; // ตรวจสอบ Path ให้ถูกต้อง + + +export default function LoginForm() { + const loginMutation = useLoginMutation(); + const [apiErrorMessage, setApiErrorMessage] = useState(""); + + const { + register, + handleSubmit, + formState: { errors } + } = useForm({ + resolver: yupResolver(loginSchema), + defaultValues: { + username: '', + password: '' + } + }); + + const onSubmit = (data) => { + setApiErrorMessage(""); + + // เรียกใช้ Mutation (Token + Fetch User) + loginMutation.mutate({ + username: data.username, + password: data.password + }, { + onError: (error) => { + setApiErrorMessage(error.message || "การล็อกอินล้มเหลว กรุณาตรวจสอบข้อมูล"); + } + }); + } + + const loading = loginMutation.isPending; + + return ( + // Card หลัก: ปรับ bg-white, shadow, border-radius ตามสไตล์ Contabo +
+
+ + {/* คอลัมน์ซ้าย: Intro/Features */} +
+ +
+ + {/* คอลัมน์ขวา: Form Wrapper (จัดกึ่งกลางเนื้อหา) */} +
+ + {/* Div จำกัดความกว้างของฟอร์มจริง ๆ */} +
+ + {/* Text: ปรับเป็นภาษาไทย */} +

ยินดีต้อนรับกลับมา

+

+ ที่นี่คุณสามารถเข้าสู่ระบบ DDO Console ได้ โปรดทราบว่าข้อมูลประจำตัวนี้อาจแตกต่างจากข้อมูลประจำตัวสำหรับระบบอื่น ๆ +

+ +
+ + {/* API Error Alert */} + {apiErrorMessage && ( +
+ + {apiErrorMessage} +
+ )} + +
+ {/* Username Input: เปลี่ยนเป็น 'ชื่อผู้ใช้' */} + + + {/* Password Input: เปลี่ยนเป็น 'รหัสผ่าน' */} + +
+ + {/* Checkbox และ Link ลืมรหัสผ่าน */} +
+ + + + ลืมรหัสผ่าน? + + +
+ + + + {/* "ยังไม่มีบัญชีใช่ไหม?" */} +
+ ยังไม่มีบัญชีใช่ไหม? + + + ลงทะเบียน + + +
+
+
{/* สิ้นสุด Div จำกัดความกว้าง */} + +
{/* สิ้นสุดคอลัมน์ขวา */} +
+
+ ) +} \ No newline at end of file diff --git a/web/src/components/ModalForm.jsx b/web/src/components/ModalForm.jsx new file mode 100644 index 0000000..4cdfecb --- /dev/null +++ b/web/src/components/ModalForm.jsx @@ -0,0 +1,189 @@ +import React, { useEffect } from 'react'; +import { useForm } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; +import InputText from './InputText'; +import { modelSchema } from '../schemas/modelSchema'; +import SelectInput from './SelectInput'; + +export default function ModalForm({ isOpen, onClose, mode, OnSubmit, model }) { + + // สถานะ Status Choices จาก AiModel (กำหนดเองใน Frontend) + const STATUS_OPTIONS = [ + { value: 'ACTIVE', name: 'ACTIVE (พร้อมใช้งาน)' }, + { value: 'INACTIVE', name: 'INACTIVE (ไม่ได้ใช้งาน)' }, + { value: 'TESTING', name: 'TESTING (กำลังทดสอบ)' }, + ]; + + // 1. RHF Setup + const { + register, + handleSubmit, + reset, + formState: { errors, isSubmitting } + } = useForm({ + resolver: yupResolver(modelSchema), // ใช้ Schema สำหรับ Model Registry + // กำหนดค่าเริ่มต้นตาม mode + defaultValues: { + id: '', + name: '', + model_version: 'v1.0.0', + developer: '', + base_url: '', + inference_path: '', + status: 'INACTIVE', + auth_required: false, + } + }); + + // 2. Logic โหลดข้อมูล Model เข้า Form เมื่อเปิดโหมด Edit + useEffect(() => { + if (mode === 'edit' && model) { + // ใช้ reset() ของ RHF เพื่อโหลดข้อมูลลงในฟอร์ม + reset({ + id: model.id || '', // ID เป็น ReadOnly + name: model.name || '', + model_version: model.model_version || 'v1.0.0', + developer: model.developer || '', + base_url: model.base_url || '', + inference_path: model.inference_path || '', + status: model.status || 'INACTIVE', + auth_required: model.auth_required || false, + }); + } else { + // Reset ฟอร์มเป็นค่าเริ่มต้นเมื่อเปิดโหมด Add + reset(); + } + }, [mode, model, reset]); + + + // 3. Logic การ Submit + const onSubmitHandler = (data) => { + // เพิ่ม ID เข้าไปในข้อมูลถ้าเป็นโหมด Edit + if (mode === 'edit') { + data.id = model.id; + } + + // เรียกใช้ OnSubmit ที่มาจาก Page Component (เรียก Mutation) + OnSubmit(data); + + onClose(); // ปิด Modal หลังจาก Submit + }; + + const modalTitle = mode === 'add' ? 'ลงทะเบียน AI Model ใหม่' : `แก้ไข Model: ${model?.name}`; + const submitText = mode === 'add' ? 'ลงทะเบียน' : 'บันทึกการแก้ไข'; + + + return ( + +
{/* เพิ่มขนาด Modal */} +

{modalTitle}

+ + {/* ปุ่มปิด Modal */} + + + {/* 4. Form หลัก (ใช้ handleSubmit ของ RHF) */} +
+
+ + {/* ---------------------------------- */} + {/* กลุ่มที่ 1: ชื่อและสถานะ */} + {/* ---------------------------------- */} +
+
+ +
+
+ +
+
+ + {/* ---------------------------------- */} + {/* กลุ่มที่ 2: Base URL / Inference Path */} + {/* ---------------------------------- */} +
+
+ +
+
+ +
+
+ + {/* ---------------------------------- */} + {/* กลุ่มที่ 3: สถานะและการควบคุม */} + {/* ---------------------------------- */} +
+
+ + {errors.status &&

{errors.status.message}

} +
+ +
+
+ +
+
+
+ +
+ +
+ + +
+ + {/* 5. ปุ่ม Submit และ Cancel */} +
+ + +
+
+
+
+ ); +} \ No newline at end of file diff --git a/web/src/components/ModelRegistry/ModelTable.jsx b/web/src/components/ModelRegistry/ModelTable.jsx new file mode 100644 index 0000000..db2d4fd --- /dev/null +++ b/web/src/components/ModelRegistry/ModelTable.jsx @@ -0,0 +1,92 @@ +import React from 'react'; +//import { useTestConnection } from '../../services/modelRegistryApi'; // Hook สำหรับ Test Connection +import { FaCheckCircle, FaExclamationTriangle, FaTrash, FaEdit } from 'react-icons/fa'; +import { useDispatch } from 'react-redux'; +import { addToast } from '../../features/toast/toastSlice'; + +// ---------------------------------------------------- +// Helper Function: แสดง Badge สถานะ +// ---------------------------------------------------- +const getStatusBadge = (status) => { + const baseClass = "badge badge-sm"; + switch (status) { + case 'ACTIVE': return
ACTIVE
; + case 'TESTING': return
TESTING
; + case 'INACTIVE': return
INACTIVE
; + default: return
N/A
; + } +}; + +function ModelTable({ models, handleOpenEdit, handleDelete, deleteLoading }) { + // ประกาศ useDispatch Hook + const dispatch = useDispatch(); + + // Hook สำหรับทดสอบการเชื่อมต่อ (Test Connection) + // ใช้ Hook ตรงนี้ เพราะเป็น Logic ที่เกี่ยวข้องกับ Action ในตารางโดยตรง + //const testConnectionMutation = useTestConnection(); + + // 2. Logic การแสดงผลตาราง + return ( + + {/* Table Head */} + + + + + + + + + + + {/* Table Body */} + + {models.map((model) => ( + + + + + + + {/* Actions (CRUD/Control) */} + + + ))} + +
Model/VersionBase URLDeveloperStatusActions
+ {model.name} + {model.model_version} + + {model.full_endpoint} + {model.developer || 'N/A'}{getStatusBadge(model.status)} + {/* Edit/Update Button (Protected by RBAC in Backend) */} + + + {/* Test Connection Button */} + + + {/* Delete Button (Protected by RBAC in Backend) */} + +
+ ); +} + +export default ModelTable; \ No newline at end of file diff --git a/web/src/components/ModelRegistry/ModelTopBar.jsx b/web/src/components/ModelRegistry/ModelTopBar.jsx new file mode 100644 index 0000000..e57be78 --- /dev/null +++ b/web/src/components/ModelRegistry/ModelTopBar.jsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { FaPlus, FaSearch } from 'react-icons/fa'; + +function ModelTopBar({ onOpenAdd, onSearch }) { + return ( +
+ {/* Search Bar */} +
+ onSearch(e.target.value)} + /> + +
+ + {/* Add Button */} + +
+ ); +} + +export default ModelTopBar; \ No newline at end of file diff --git a/web/src/components/ModelSelector.jsx b/web/src/components/ModelSelector.jsx new file mode 100644 index 0000000..36846b1 --- /dev/null +++ b/web/src/components/ModelSelector.jsx @@ -0,0 +1,28 @@ +import React from 'react'; + +export default function ModelSelector({ activeModels, isLoading, selectedModelId, setSelectedModelId, isPending }) { + return ( +
+ + +
+ ); +} \ No newline at end of file diff --git a/web/src/components/PasswordReset/ResetInfoCard.jsx b/web/src/components/PasswordReset/ResetInfoCard.jsx new file mode 100644 index 0000000..02d5654 --- /dev/null +++ b/web/src/components/PasswordReset/ResetInfoCard.jsx @@ -0,0 +1,47 @@ +import React from 'react'; +import {FaEnvelope, FaQuestionCircle, FaClock, FaExclamationTriangle, FaPhoneAlt} from 'react-icons/fa'; + +export default function ResetInfoCard() { + return ( + // ใช้ w-full h-full เพื่อให้ Component ขยายเต็มพื้นที่ Container +
+ +
+
+ + คำแนะนำในการรีเซ็ตรหัสผ่าน +
+ + {/* 1. ขั้นตอนการรีเซ็ต */} +

+ + กระบวนการ +

+
    +
  1. กรุณากรอกอีเมลที่ใช้ลงทะเบียน
  2. +
  3. ระบบจะส่งลิงก์รีเซ็ตไปให้คุณ
  4. +
  5. ลิงก์จะหมดอายุภายใน 24 ชั่วโมง
  6. +
  7. หากไม่พบอีเมล ให้ตรวจสอบใน /Spam Folder
  8. +
+ +
+ + {/* 2. ช่องทางติดต่อช่วยเหลือ */} +

+ + หากไม่ได้รับอีเมล +

+
    +
  • + + ติดต่อ: support@ddo.tech +
  • +
  • + + โทร: 02-XXX-XXXX +
  • +
+
+
+ ); +} \ No newline at end of file diff --git a/web/src/components/PasswordReset/ResetPasswordForm.jsx b/web/src/components/PasswordReset/ResetPasswordForm.jsx new file mode 100644 index 0000000..2638c2c --- /dev/null +++ b/web/src/components/PasswordReset/ResetPasswordForm.jsx @@ -0,0 +1,63 @@ +import React from 'react'; +import { useForm } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; + +import InputText from '../InputText'; +import ErrorText from '../ErrorText'; +import { resetConfirmSchema } from '../../schemas/authSchema'; + +export default function ResetPasswordForm({ uid, token, confirmMutation }) { + + // 1. Hook Form Setup + const { register, handleSubmit, formState: { errors } } = useForm({ + resolver: yupResolver(resetConfirmSchema), + }); + + // 2. Submission Handler + const onSubmit = (data) => { + // ส่ง uid, token, new_password, และ re_new_password ไปให้ API + confirmMutation.mutate({ + uid: uid, + token: token, + new_password: data.new_password, + re_new_password: data.re_new_password + }); + }; + + const loading = confirmMutation.isPending; + + return ( +
+

ตั้งรหัสผ่านใหม่

+

กรุณากรอกรหัสผ่านใหม่เพื่อเข้าสู่ระบบ

+ + + + + {confirmMutation.isError && ( + {confirmMutation.error.message} + )} + + + + ); +} \ No newline at end of file diff --git a/web/src/components/Profile/PasswordChangeForm.jsx b/web/src/components/Profile/PasswordChangeForm.jsx new file mode 100644 index 0000000..f133a65 --- /dev/null +++ b/web/src/components/Profile/PasswordChangeForm.jsx @@ -0,0 +1,78 @@ +import React from 'react'; +import { useForm } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; +import { passwordSchema } from '../../schemas/authSchema'; +import InputText from '../InputText'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import axiosClient from '../../services/axiosClient'; +import { useDispatch } from 'react-redux'; +import { addToast } from '../../features/toast/toastSlice'; +import ErrorText from '../ErrorText'; + + +// Hook เฉพาะสำหรับการเปลี่ยนรหัสผ่าน (POST /users/set_password/) +const useChangePasswordMutation = () => { + const dispatch = useDispatch(); + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async ({ current_password, new_password, re_new_password }) => { + // Djoser Endpoint + const response = await axiosClient.post(`/api/v1/auth/users/set_password/`, { + current_password: current_password, + new_password: new_password, + re_new_password: re_new_password, // Djoser ต้องการ re_new_password field + }); + return response.data; + }, + onSuccess: () => { + dispatch(addToast({ message: 'เปลี่ยนรหัสผ่านสำเร็จแล้ว!', type: 'success' })); + queryClient.invalidateQueries({ queryKey: ['userProfile'] }); // Invalidate เพื่อความปลอดภัย + }, + onError: (error) => { + const msg = error.response?.data?.current_password?.[0] || 'รหัสผ่านปัจจุบันไม่ถูกต้อง'; + dispatch(addToast({ message: `เปลี่ยนรหัสผ่านล้มเหลว: ${msg}`, type: 'error' })); + throw new Error(msg); // Throw เพื่อให้ RHF จับ error ได้ + }, + }); +}; + + +export default function PasswordChangeForm() { + const changeMutation = useChangePasswordMutation(); + const isChanging = changeMutation.isPending; + + const { register, handleSubmit, reset, formState: { errors } } = useForm({ + resolver: yupResolver(passwordSchema), + }); + + const onSubmit = (data) => { + changeMutation.mutate(data, { + onSuccess: () => { + reset(); // Clear form on success + } + }); + }; + + return ( +
+ + + + + {changeMutation.isError && ( + + {errors.current_password?.message || changeMutation.error.message || 'เกิดข้อผิดพลาดในการเปลี่ยนรหัสผ่าน'} + + )} + + + + ); +} \ No newline at end of file diff --git a/web/src/components/Profile/ProfileEditForm.jsx b/web/src/components/Profile/ProfileEditForm.jsx new file mode 100644 index 0000000..ad5afab --- /dev/null +++ b/web/src/components/Profile/ProfileEditForm.jsx @@ -0,0 +1,52 @@ +import React, { useEffect } from 'react'; +import { useForm } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; +import { profileSchema } from '../../schemas/authSchema'; +import InputText from '../InputText'; +import { useUpdateProfileMutation } from '../../services/authApi'; + +export default function ProfileEditForm({ user }) { + const updateMutation = useUpdateProfileMutation(); + const isUpdating = updateMutation.isPending; + + const { register, handleSubmit, reset, formState: { errors } } = useForm({ + resolver: yupResolver(profileSchema), + }); + + // โหลดข้อมูลผู้ใช้เข้า Form เมื่อ Component โหลด + useEffect(() => { + if (user) { + reset({ + first_name: user.first_name || '', + last_name: user.last_name || '', + phone_number: user.phone_number || '', + email: user.email || '', + // ไม่โหลด username เพราะอาจมีปัญหาในการอัปเดต + }); + } + }, [user, reset]); + + const onSubmit = (data) => { + // Djoser /users/me/ Endpoint รองรับ PATCH เพื่อส่งเฉพาะ Field ที่เปลี่ยน + updateMutation.mutate(data); + }; + + return ( +
+ + + + + +

Username: {user.username} (ไม่สามารถแก้ไขได้)

+ + + + ); +} \ No newline at end of file diff --git a/web/src/components/Registration/RegisterInfoCard.jsx b/web/src/components/Registration/RegisterInfoCard.jsx new file mode 100644 index 0000000..acef857 --- /dev/null +++ b/web/src/components/Registration/RegisterInfoCard.jsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { FaEnvelope, FaQuestionCircle, FaPhoneAlt } from 'react-icons/fa'; + +export default function RegisterInfoCard() { + return ( + // ใช้ w-full h-full เพื่อให้ Component ขยายเต็มพื้นที่ Container +
+
+ + คำแนะนำและช่วยเหลือ +
+ + {/* 1. แนวทางการกรอกข้อมูล */} +

1. แนวทางการกรอกข้อมูล

+
    +
  • ชื่อผู้ใช้งาน: ใช้ตัวอักษร/ตัวเลขเท่านั้น (ขั้นต่ำ 4 ตัว)
  • +
  • รหัสผ่าน: ต้องยาวอย่างน้อย 8 ตัวอักษร
  • +
  • เบอร์โทรศัพท์: เป็นตัวเลข 10 หลัก (ไม่บังคับ)
  • +
+ +
+ + {/* 2. ช่องทางติดต่อช่วยเหลือ */} +

2. ช่องทางติดต่อช่วยเหลือ

+
    +
  • + + Email: support@ddo.tech +
  • +
  • + + โทร: 02-XXX-XXXX +
  • +
+
+ ); +} \ No newline at end of file diff --git a/web/src/components/ResultDisplay.jsx b/web/src/components/ResultDisplay.jsx new file mode 100644 index 0000000..22a28fd --- /dev/null +++ b/web/src/components/ResultDisplay.jsx @@ -0,0 +1,25 @@ +import React from 'react'; + +export default function ResultDisplay({ result }) { + // หากไม่มีผลลัพธ์ (result เป็น null) ก็ไม่ต้องแสดงผลอะไร + if (!result) { + return null; + } + + return ( +
+
+

Inference Success!

+

ได้รับผลลัพธ์จากเซิร์ฟเวอร์แล้ว (JSON Payload)

+
+ + {/* แสดงผลลัพธ์ JSON ในรูปแบบที่อ่านง่าย */} +
+                {/* text-base-content: เพื่อให้สีตัวอักษรเป็นสีพื้นฐานของ Theme (ไม่ใช่สีขาว) */}
+                {/* whitespace-pre-wrap: บังคับให้ข้อความขึ้นบรรทัดใหม่แม้จะอยู่ใน 
 */}
+                {JSON.stringify(result, null, 2)}
+            
+
+ ); +} \ No newline at end of file diff --git a/web/src/components/SelectInput.jsx b/web/src/components/SelectInput.jsx new file mode 100644 index 0000000..31e3ba8 --- /dev/null +++ b/web/src/components/SelectInput.jsx @@ -0,0 +1,48 @@ +import React, { forwardRef } from "react"; +import PropTypes from "prop-types"; + +// 1. สร้าง Functional Component ปกติ (ไม่ใช้ forwardRef โดยตรง) +function SelectInputBase({ labelTitle, options, containerStyle, error, ...rest }, ref) { + return ( +
+ + + + + {error &&

{error.message}

} +
+ ); +} + +// 2. กำหนด propTypes ปกติ (จะไม่มี warning อีก) +SelectInputBase.propTypes = { + labelTitle: PropTypes.string.isRequired, + options: PropTypes.arrayOf( + PropTypes.shape({ + value: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + }) + ).isRequired, + containerStyle: PropTypes.string, + error: PropTypes.object, +}; + +// 3. ใช้ forwardRef กับตัวหลัก +const SelectInput = forwardRef(SelectInputBase); + +export default SelectInput; diff --git a/web/src/components/ServiceStatus.jsx b/web/src/components/ServiceStatus.jsx new file mode 100644 index 0000000..d05616a --- /dev/null +++ b/web/src/components/ServiceStatus.jsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { FaCheckCircle, FaTimesCircle, FaDatabase, FaServer, FaFlask } from 'react-icons/fa'; +import PropTypes from 'prop-types'; // สำหรับการตรวจสอบ Props (Best Practice) + +// Helper Function: Mapping Icon +const IconMap = { + FaDatabase, + FaServer, + FaFlask, + FaCheckCircle, + FaTimesCircle, +}; + +export default function ServiceStatus({ name, status, details, icon: Icon }) { + const isUp = status === 'UP' || status === 'Healthy'; + const colorClass = isUp ? 'text-success' : 'text-error'; + const badgeClass = isUp ? 'badge-success' : 'badge-error'; + + // Icon สำหรับแสดงสถานะ (ใช้ Check/Times Circle เป็น Fallback) + const StatusIcon = Icon || (isUp ? FaCheckCircle : FaTimesCircle); + + return ( +
+
+ {/* Icon ของ Service */} + + {/* ชื่อ Service */} + {name} +
+ +
+ {/* Badge แสดงสถานะ */} + + {/* รายละเอียด (Truncate เพื่อป้องกัน overflow) */} + {details} +
+
+ ); +} + +// กำหนด PropTypes เพื่อเพิ่มความแข็งแกร่งในการพัฒนา +ServiceStatus.propTypes = { + name: PropTypes.string.isRequired, + status: PropTypes.string.isRequired, + details: PropTypes.string.isRequired, + icon: PropTypes.elementType, +}; \ No newline at end of file diff --git a/web/src/components/SidebarSubmenu.jsx b/web/src/components/SidebarSubmenu.jsx new file mode 100644 index 0000000..9b78ccb --- /dev/null +++ b/web/src/components/SidebarSubmenu.jsx @@ -0,0 +1,87 @@ +// src/components/SidebarSubmenu.jsx (ปรับปรุงสำหรับ RBAC) + +import ChevronDownIcon from '@heroicons/react/24/outline/ChevronDownIcon'; +import { useEffect, useState } from 'react'; +import { NavLink, useLocation } from 'react-router-dom'; +import { useSelector } from 'react-redux'; + +// Component นี้คาดหวังว่าฟังก์ชัน canAccess จะถูกส่งมาจาก MainLayout หรือสร้างขึ้นใหม่ + +function SidebarSubmenu({ submenu, name, icon, closeMobileSidebar }) { + const location = useLocation(); + const [isExpanded, setIsExpanded] = useState(false); + const role = useSelector(state => state.auth.role); // ดึง Role จาก Redux + + // ฟังก์ชันตรวจสอบสิทธิ์ (ควรมาจาก MainLayout แต่เราจะใช้ Logic พื้นฐาน) + const canAccess = (requiredRole) => { + if (role === 'admin') return true; + if (!requiredRole) return true; + const allowedRoles = Array.isArray(requiredRole) ? requiredRole : [requiredRole]; + return allowedRoles.includes(role); + }; + + // เปิด Submenu หาก Path ปัจจุบันอยู่ใน Submenu นั้น + useEffect(() => { + // ตรวจสอบว่ามีเมนูย่อยใดที่ผู้ใช้เข้าถึงได้และเป็น Path ปัจจุบันหรือไม่ + const isActive = submenu.some( + m => canAccess(m.requiredRole) && m.path === location.pathname + ); + if (isActive) { + setIsExpanded(true); + } + }, [location.pathname, submenu, role]); // เพิ่ม role ใน dependency array + + return ( +
+ ); +} + +export default SidebarSubmenu; \ No newline at end of file diff --git a/web/src/components/Subtitle.jsx b/web/src/components/Subtitle.jsx new file mode 100644 index 0000000..c2db806 --- /dev/null +++ b/web/src/components/Subtitle.jsx @@ -0,0 +1,12 @@ +import React from 'react'; + +function Subtitle({ styleClass, children }) { + return ( + // ใช้ text-2xl เพื่อให้ดูโดดเด่นขึ้นสำหรับหัวข้อหน้า +
+ {children} +
+ ); +} + +export default Subtitle; diff --git a/web/src/components/TemplatePointers.jsx b/web/src/components/TemplatePointers.jsx new file mode 100644 index 0000000..3b2e94f --- /dev/null +++ b/web/src/components/TemplatePointers.jsx @@ -0,0 +1,34 @@ +function TemplatePointers(){ + return( + <> +

DDO Console Features

+ + {/* 1. ส่วน A: Dashboard & Monitoring */} +

+ ✓ ความน่าเชื่อถือของข้อมูล (HA Data Layer): ใช้ CockroachDB Cluster (3 Node HA) เพื่อรับประกันความต่อเนื่องของบริการฐานข้อมูล +

+ + {/* 2. ส่วน B: Control & Management (MLOps Flow) */} +

+ ✓ Asynchronous AI Processing: ประมวลผลงานหนักผ่าน Celery เพื่อให้ Frontend ตอบสนองทันที และจัดการคิวงานได้ +

+ + {/* 3. ส่วน C: Data Governance & Discovery (เน้น Medical/AI) */} +

+ ✓ AI Model Serving Layer: บริการ Model Inference พร้อมจัดการไฟล์ภาพขนาดใหญ่ด้วย MinIO (S3) +

+ + {/* 4. ส่วน Security (การยืนยันตัวตนและการเข้าถึง) */} +

+ ✓ Security & Gateway: การจัดการผู้ใช้และสิทธิ์ (JWT/RBAC) ผ่าน Django DRF ซึ่งทำหน้าที่เป็น Lightweight Gateway หลัก +

+ + {/* 5. ส่วนสถาปัตยกรรมกระจายศูนย์ */} +

+ ✓ สถาปัตยกรรมกระจายศูนย์ (Distributed): สร้างบนเทคโนโลยีหลัก เช่น MONAI, Django DRF, CockroachDB HA, Redis Cache และ MinIO Object Storage +

+ + ) +} + +export default TemplatePointers \ No newline at end of file diff --git a/web/src/components/TitleCard.jsx b/web/src/components/TitleCard.jsx new file mode 100644 index 0000000..ecfd5bc --- /dev/null +++ b/web/src/components/TitleCard.jsx @@ -0,0 +1,33 @@ +import React from 'react'; +import Subtitle from './Subtitle'; + +function TitleCard({ title, children, topMargin, TopSideButtons }) { + return ( +
+ + {/* Title และ Top Side Buttons */} +
+ + {title} + + + {/* Top side button, show only if present */} + {TopSideButtons && ( +
+ {TopSideButtons} +
+ )} +
+ + {/* Divider (เส้นแบ่ง) */} +
+ + {/* Card Body */} +
+ {children} +
+
+ ); +} + +export default TitleCard; diff --git a/web/src/components/ToastNotification.jsx b/web/src/components/ToastNotification.jsx new file mode 100644 index 0000000..4155707 --- /dev/null +++ b/web/src/components/ToastNotification.jsx @@ -0,0 +1,137 @@ +import React, { useEffect } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { removeToast } from '../features/toast/toastSlice'; + +const TOAST_DURATION = 3000; + +// ---------------------------------------------------- +// Helper Functions +// ---------------------------------------------------- + +const getColors = (type) => { + switch (type) { + case 'success': + return 'alert-success'; + case 'error': + return 'alert-error'; + case 'warning': + return 'alert-warning'; + case 'info': + return 'alert-info'; + default: + return 'alert-info'; + } +}; + +const getIcon = (type) => { + switch (type) { + case 'success': + return ( + + + + ); + case 'error': + return ( + + + + ); + case 'warning': + return ( + + + + ); + case 'info': + return ( + + + + ); + default: + return null; + } +}; + +// ---------------------------------------------------- +// ToastNotification Component +// ---------------------------------------------------- + +export default function ToastNotification() { + const dispatch = useDispatch(); + const queue = useSelector((state) => state.toast.queue); + + useEffect(() => { + if (queue.length > 0) { + queue.forEach((toast) => { + if (!toast.timerId) { + setTimeout(() => { + dispatch(removeToast({ id: toast.id })); + }, TOAST_DURATION); + } + }); + } + }, [queue, dispatch]); + + return ( +
+ {queue.map((toast) => ( +
dispatch(removeToast({ id: toast.id }))} + > +
+ {getIcon(toast.type)} + {toast.message} +
+
+ ))} +
+ ); +} diff --git a/web/src/config/sidebarRoutes.jsx b/web/src/config/sidebarRoutes.jsx new file mode 100644 index 0000000..32b1a86 --- /dev/null +++ b/web/src/config/sidebarRoutes.jsx @@ -0,0 +1,57 @@ +import {FaTachometerAlt, FaCog, FaHeartbeat, FaFlask, FaUserCircle} from 'react-icons/fa'; + +const routes = [ + { + path: '/dashboard', + icon: , + name: 'แดชบอร์ด/ภาพรวม', + }, + + // ----------------================-- + // กลุ่ม: Data & AI/MLOps (เหลือแค่ Model Ops) + // ---------------------------------- + { + path: '', + icon: , + name: 'AI Model Operations', + requiredRole: ['viewer', 'admin', 'manager'], + submenu: [ + { + path: '/dashboard/inference-run', + name: 'AI Inference (Run)', + requiredRole: ['viewer', 'admin', 'manager'], + }, + { + path: '/dashboard/model-registry', + name: 'Model Registry & Control', + requiredRole: ['manager', 'admin'], + }, + ], + }, + + // --- เมนูจัดการโปรไฟล์ --- + { + path: '/dashboard/profile', + icon: , + name: 'การจัดการโปรไฟล์', + requiredRole: ['viewer', 'admin', 'manager'], // ทุก Role ควรเข้าถึงได้ + }, + + // ---------------------------------- + // กลุ่ม: การดูแลระบบ + // ---------------------------------- + { + path: '/dashboard/health', + icon: , + name: 'สถานะระบบ (Health)', + requiredRole: ['viewer', 'admin', 'manager'], + }, + { + path: '/dashboard/guide', + icon: , + name: 'คู่มือการใช้งาน (Guide)', + requiredRole: ['viewer', 'manager', 'admin'], + }, +]; + +export default routes; \ No newline at end of file diff --git a/web/src/features/auth/authSlice.js b/web/src/features/auth/authSlice.js new file mode 100644 index 0000000..60625fd --- /dev/null +++ b/web/src/features/auth/authSlice.js @@ -0,0 +1,79 @@ +import { createSlice } from '@reduxjs/toolkit'; + +// ---------------------------------------------------- +// Helper Function: กำหนดบทบาท (Role) จาก Django User Object +// ---------------------------------------------------- +const determineRole = (user) => { + if (!user || !user.id) { + return 'guest'; + } + + // 1. ใช้ฟิลด์ 'role' ที่ส่งมาจาก Backend โดยตรง (ถ้ามี) + if (user.role) { + return user.role.toLowerCase(); // เช่น 'ADMIN' -> 'admin' + } + + // 2. ใช้ฟิลด์ is_superuser/is_staff เป็น Fallback + if (user.is_superuser) { + return 'admin'; + } + if (user.is_staff) { + return 'manager'; + } + // ผู้ใช้ทั่วไป + return 'viewer'; +}; + +// ---------------------------------------------------- +// ฟังก์ชันช่วยในการอ่านค่าจาก Local Storage เพื่อกำหนดสถานะเริ่มต้น +// ---------------------------------------------------- +const getInitialAuthState = () => { + const token = localStorage.getItem('token'); + const user = JSON.parse(localStorage.getItem('user')); + + // ดึง Role + const role = determineRole(user); + + return { + isAuthenticated: !!token, + user: user || null, + role: role, + }; +}; + +const initialState = getInitialAuthState(); + +const authSlice = createSlice({ + name: 'auth', + initialState, + reducers: { + // Reducer สำหรับการล็อกอินสำเร็จ + loginSuccess: (state, action) => { + state.isAuthenticated = true; + state.user = action.payload.user; + state.role = action.payload.role; + }, + + // Reducer สำหรับการออกจากระบบ + logout: (state) => { + state.isAuthenticated = false; + state.user = null; + state.role = 'guest'; + // ลบข้อมูลจาก localStorage + localStorage.removeItem('token'); + localStorage.removeItem('user'); + }, + + // Reducer สำหรับอัปเดตข้อมูลผู้ใช้ (เช่น หลังอัปเดตโปรไฟล์) + updateUser: (state, action) => { + state.user = action.payload.user; + state.role = action.payload.role; // อัปเดต Role ด้วย (เผื่อมีการอัปเดตสิทธิ์) + localStorage.setItem('user', JSON.stringify(action.payload.user)); + localStorage.setItem('role', action.payload.role); + } + }, +}); + +export const { loginSuccess, logout, updateUser } = authSlice.actions; + +export default authSlice.reducer; \ No newline at end of file diff --git a/web/src/features/toast/toastSlice.js b/web/src/features/toast/toastSlice.js new file mode 100644 index 0000000..c1148df --- /dev/null +++ b/web/src/features/toast/toastSlice.js @@ -0,0 +1,31 @@ +import { createSlice } from '@reduxjs/toolkit'; +import { v4 as uuidv4 } from 'uuid'; + +const TOAST_DURATION = 3000; // 3 วินาที + +const toastSlice = createSlice({ + name: 'toast', + initialState: { + queue: [], // สถานะเก็บรายการ Toast ทั้งหมดที่ต้องแสดง + }, + reducers: { + // Action สำหรับเพิ่ม Toast เข้าคิว + addToast: (state, action) => { + const newToast = { + id: uuidv4(), + message: action.payload.message, + type: action.payload.type || 'info', + }; + state.queue.push(newToast); + + }, + + // Action สำหรับลบ Toast ออกจากคิว + removeToast: (state, action) => { + state.queue = state.queue.filter(toast => toast.id !== action.payload.id); + } + }, +}); + +export const { addToast, removeToast } = toastSlice.actions; +export default toastSlice.reducer; \ No newline at end of file diff --git a/web/src/index.css b/web/src/index.css new file mode 100644 index 0000000..49b3c40 --- /dev/null +++ b/web/src/index.css @@ -0,0 +1,4 @@ +@import "tailwindcss"; +@plugin "daisyui"{ + themes: light --default, dark --prefersdark, corporate; +} diff --git a/web/src/layouts/AuthLayout.jsx b/web/src/layouts/AuthLayout.jsx new file mode 100644 index 0000000..4b8ae83 --- /dev/null +++ b/web/src/layouts/AuthLayout.jsx @@ -0,0 +1,16 @@ +import {Outlet} from "react-router-dom"; + +export default function AuthLayout(){ + return( + <> + {/* 1. Div หลัก: จัดให้อยู่ตรงกลางจอ (ใช้ flex h-screen) */} +
+ + {/* 2. Div ภาชนะสำหรับเนื้อหา: กำหนดขนาดสูงสุด */} +
+ +
+
+ + ) +} \ No newline at end of file diff --git a/web/src/layouts/MainLayout.jsx b/web/src/layouts/MainLayout.jsx new file mode 100644 index 0000000..b80a1fa --- /dev/null +++ b/web/src/layouts/MainLayout.jsx @@ -0,0 +1,176 @@ +import React from 'react'; +import { Link, Outlet, useNavigate, NavLink, useLocation } from 'react-router-dom'; +import { useSelector, useDispatch } from 'react-redux'; +import { logout } from '../features/auth/authSlice'; +import { FaSignOutAlt, FaUserCircle } from 'react-icons/fa'; +import Bars3Icon from '@heroicons/react/24/outline/Bars3Icon'; +import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon'; + +import routes from '../config/sidebarRoutes'; +import SidebarSubmenu from '../components/SidebarSubmenu'; + + +export default function MainLayout() { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const location = useLocation(); // Hook สำหรับตรวจสอบ Path ปัจจุบัน + + // ดึงข้อมูลผู้ใช้และ Role จาก Redux Store + const user = useSelector(state => state.auth.user); + const role = useSelector(state => state.auth.role); + + const handleLogout = () => { + dispatch(logout()); + navigate('/login', { replace: true }); + }; + + // Logic: ฟังก์ชันตรวจสอบสิทธิ์ (RBAC) + const canAccess = (requiredRole) => { + if (role === 'admin') return true; + if (!requiredRole) return true; + + // ตรวจสอบ Role ของผู้ใช้กับ Role ที่จำเป็น + const allowedRoles = Array.isArray(requiredRole) ? requiredRole : [requiredRole]; + return allowedRoles.includes(role); + }; + + // ฟังก์ชันปิด Sidebar ใน Mobile + const closeMobileSidebar = () => { + document.getElementById('my-drawer-2').checked = false; + } + + // ฟังก์ชันสำหรับดึงชื่อเมนูตาม Path ปัจจุบัน (สำหรับ Header) + const getPageTitle = (pathname) => { + let title = "DDO Console"; + routes.forEach((route) => { + if (route.path && route.path === pathname) { + title = route.name; + } else if (route.submenu) { + route.submenu.forEach((submenuRoute) => { + if (submenuRoute.path === pathname) { + title = submenuRoute.name; + } + }); + } + }); + return title; + }; + + const currentTitle = getPageTitle(location.pathname); + + + return ( +
+ {/* 1. Drawer Toggle */} + + + {/* 2. Main Content Area */} +
+ {/* Header/Navbar */} +
+
+ {/* Mobile Toggle Button (ใช้ Heroicon) */} + +
+ {/* แสดงชื่อหน้าปัจจุบัน */} +
+ {currentTitle} +
+ + {/* User Profile/Logout Dropdown */} +
+
+
+ + {user ? user.username : 'ผู้ใช้งาน'} + {role} +
+
    +
  • + + โปรไฟล์ + +
  • +
    +
  • + +
  • +
+
+
+
+ + {/* Page Content (Outlet) */} +
+ +
+ + {/* Footer (Optional) */} +
+ +
+
+ + {/* 3. Sidebar (ปรับโครงสร้างใหม่) */} +
+ +
    + + {/* ปุ่มปิด Sidebar สำหรับ Mobile */} + + + {/* ส่วนโลโก้ DDO Console */} +
  • + + DDO Console Logo + DDO Console + +
  • + + {/* การวนลูปเมนูจาก sidebarRoutes.jsx */} +
  • เมนูหลัก
  • + {routes.map((route, k) => { + // 1. ตรวจสอบสิทธิ์เมนูหลัก + if (!canAccess(route.requiredRole)) return null; + + return ( +
  • + {route.submenu ? + // 2. ถ้ามี Submenu ใช้ SidebarSubmenu Component + : + ( + // 3. ถ้าไม่มี Submenu ใช้ NavLink ธรรมดา + + `text-base ${isActive ? 'bg-base-200 text-primary font-semibold' : 'hover:bg-base-400'}` + } + > + {route.icon} {route.name} + + ) + } +
  • + ); + })} +
+
+
+ ); +} \ No newline at end of file diff --git a/web/src/main.jsx b/web/src/main.jsx new file mode 100644 index 0000000..9ab579f --- /dev/null +++ b/web/src/main.jsx @@ -0,0 +1,22 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.jsx' +import './styles.css' + +import { Provider } from 'react-redux'; +import { store } from './app/store'; +// TanStack Query +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; + +const queryClient = new QueryClient(); + +createRoot(document.getElementById('root')).render( + + + + + + + , +) diff --git a/web/src/pages/BlankPage.jsx b/web/src/pages/BlankPage.jsx new file mode 100644 index 0000000..90a2a75 --- /dev/null +++ b/web/src/pages/BlankPage.jsx @@ -0,0 +1,41 @@ +import React from 'react'; +import TitleCard from '../components/TitleCard'; +import { useLocation } from 'react-router-dom'; + +function BlankPage({ title, message }) { + const location = useLocation(); + + // ตั้งค่า Default Message ตามประเภทของหน้า + const defaultTitle = title || "Feature Under Development"; + const defaultMessage = message || + `เส้นทางปัจจุบัน: ${location.pathname} ยังไม่มีเนื้อหาที่พร้อมใช้งาน กรุณากลับไปที่หน้าหลักหรือเมนูอื่น`; + + return ( + // ใช้ TitleCard ห่อหุ้มเนื้อหาเพื่อให้มีโครงสร้างเหมือน Page อื่นๆ + +
+ + {/* Icon แจ้งเตือน */} + + + + +

+ {defaultTitle} +

+ +

+ {defaultMessage} +

+ + +
+
+ ); +} + +export default BlankPage; diff --git a/web/src/pages/Dashboard.jsx b/web/src/pages/Dashboard.jsx new file mode 100644 index 0000000..3f8afd1 --- /dev/null +++ b/web/src/pages/Dashboard.jsx @@ -0,0 +1,144 @@ +import React from 'react'; +import TitleCard from '../components/TitleCard'; +//import { useModelList } from '../services/modelRegistryApi'; +import { useSystemHealth } from '../services/healthApi'; +import { useInferenceSummary } from '../services/auditApi'; + +import { FaPlay, FaDatabase, FaClock, FaCheckCircle, FaTimesCircle, FaPercent, FaSyncAlt } from 'react-icons/fa'; +import { Link } from 'react-router-dom'; + +// ---------------------------------------------------- +// Helper Component: สรุปตัวเลขสถิติ (Stats) +// ---------------------------------------------------- +const StatCard = ({ icon, title, value, unit, colorClass, linkPath, isLoading }) => { + + // แสดง loading spinner ถ้ากำลังโหลดข้อมูล + const displayValue = isLoading ? ( + + ) : ( + value + ); + + return ( +
+
+
+ {icon} +
+
{title}
+
{displayValue} {unit}
+ {linkPath && ( +
+ + ดูรายละเอียด + +
+ )} +
+
+ ); +}; + +function Dashboard() { + // Hooks สำหรับดึงข้อมูลสถานะ + //const { data: models, isLoading: modelsLoading } = useModelList(); + const { data: health, isLoading: healthLoading, isFetching: healthFetching } = useSystemHealth(); + const { data: summary, isLoading: summaryLoading } = useInferenceSummary(); + + // --- Logic คำนวณ --- + //const activeModelCount = models?.filter(m => m.status === 'ACTIVE').length || 0; + //const totalModelCount = models?.length || 0; + + // Health Status + const healthStatus = health?.status || (healthLoading ? 'CHECKING' : 'UNKNOWN'); + const isHealthy = healthStatus === 'Healthy'; + const healthIcon = isHealthy ? : ; + const healthColor = isHealthy ? 'text-success' : 'text-error'; + + // Inference Stats (จาก useInferenceSummary) + const totalRuns = summary?.total_runs || 0; + const successRate = summary?.success_rate || 0; + const avgLatencyMs = summary?.avg_latency_ms || 0; + + + return ( +
+

แดชบอร์ด/ภาพรวม

+ + {/* 1. ส่วนแสดงสถิติสำคัญ (KPI Cards) */} +
+ + {/* Card 1: Model Active Count */} + } + title="Model พร้อมรัน (ACTIVE)" + value={0} // <-- เปลี่ยนเป็นค่าคงที่ 0 + unit={`จาก 0`} // <-- เปลี่ยนเป็นค่าคงที่ + colorClass="text-success" + // ลบ linkPath ทิ้ง เพราะเมนูอาจจะไม่มีแล้ว + // linkPath="/dashboard/model-registry" + isLoading={false} // <-- เปลี่ยนเป็น false + /> + + {/* Card 2: Total Inference Runs (Audit Log) */} + } + title="งานรันทั้งหมด (24 ชม.)" + value={totalRuns} + unit="ครั้ง" + colorClass="text-info" + isLoading={summaryLoading} + // Note: ต้องมีเมนู Pipeline Logs หรือ Audit Log List + /> + + {/* Card 3: Success Rate (Audit Log) */} + } + title="Success Rate (24 ชม.)" + value={successRate} + unit="%" + colorClass={successRate > 90 ? "text-success" : "text-warning"} + isLoading={summaryLoading} + /> + + {/* Card 4: Avg Latency (Audit Log) */} + } + title="Latency เฉลี่ย (AI)" + value={avgLatencyMs} + unit="ms" + colorClass={avgLatencyMs > 5000 ? "text-error" : "text-warning"} + isLoading={summaryLoading} + /> +
+ + {/* 2. ส่วนแสดงสถานะ Infrastructure (Health) */} + : null} + > + + +

+ ตรวจสอบสถานะของ DB, Redis, MinIO, และ AI Model Endpoints ได้ที่เมนูสถานะระบบ +

+
+ + {/* 3. ส่วนแสดง Log ล่าสุด (Audit Log) */} + +
+                    {summaryLoading ? "กำลังโหลด Log ล่าสุด..." : JSON.stringify(summary?.last_logs || [], null, 2)}
+                
+
+
+ ); +} + +export default Dashboard; \ No newline at end of file diff --git a/web/src/pages/Profile.jsx b/web/src/pages/Profile.jsx new file mode 100644 index 0000000..a57ba68 --- /dev/null +++ b/web/src/pages/Profile.jsx @@ -0,0 +1,37 @@ +import React, { useState } from 'react'; +import TitleCard from '../components/TitleCard'; +import { useUserQuery } from '../services/authApi'; +import ProfileEditForm from '../components/Profile/ProfileEditForm'; +import PasswordChangeForm from '../components/Profile/PasswordChangeForm'; +import { FaUserCircle, FaLock } from 'react-icons/fa'; + +export default function Profile() { + const { data: user, isLoading, isError } = useUserQuery(); + const [activeTab, setActiveTab] = useState('profile'); + + if (isLoading) return

กำลังโหลดข้อมูลผู้ใช้...

; + if (isError) return

ไม่สามารถดึงข้อมูลโปรไฟล์ได้

; + + return ( + +
+ + +
+ + {activeTab === 'profile' && } + {activeTab === 'password' && } + +
+ ); +} \ No newline at end of file diff --git a/web/src/pages/auth/ForgotPasswordPage.jsx b/web/src/pages/auth/ForgotPasswordPage.jsx new file mode 100644 index 0000000..f3940a1 --- /dev/null +++ b/web/src/pages/auth/ForgotPasswordPage.jsx @@ -0,0 +1,93 @@ +import React from 'react'; +import { useForm } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; +import { Link } from 'react-router-dom'; +import * as yup from 'yup'; + +// Imports Components และ Hooks +import InputText from '../../components/InputText'; +import ErrorText from '../../components/ErrorText'; +import { useRequestPasswordReset } from '../../services/authApi'; +import ResetInfoCard from '../../components/PasswordReset/ResetInfoCard'; + +// ---------------------------------------------------- +// Schema สำหรับตรวจสอบข้อมูล (รับแค่อีเมล) +// ---------------------------------------------------- +const requestSchema = yup.object().shape({ + email: yup.string().email('รูปแบบอีเมลไม่ถูกต้อง').required('กรุณากรอกอีเมลที่ใช้ลงทะเบียน'), +}); + +export default function ForgotPasswordPage() { + const requestMutation = useRequestPasswordReset(); + + // 1. Hook Form Setup + const { + register, + handleSubmit, + formState: { errors } + } = useForm({ + resolver: yupResolver(requestSchema), + }); + + const onSubmit = (data) => { + // ส่งคำขอรีเซ็ตผ่าน Mutation + requestMutation.mutate(data); + }; + + const loading = requestMutation.isPending; + + return ( + // Layout หลัก: ใช้ h-full เพื่อให้เต็มหน้าจอ +
+ + {/* Grid Layout: แบ่งเป็น 12 ส่วน, 6 ส่วนสำหรับ Info (ซ้าย), 6 ส่วนสำหรับ Form (ขวา) */} +
+ + {/* 1. คอลัมน์ซ้าย (คำแนะนำและช่วยเหลือ) */} +
+ +
+ + {/* 2. คอลัมน์ขวา (Form หลัก) */} +
+
+ +

ลืมรหัสผ่าน?

+

+ กรุณากรอกอีเมลของคุณเพื่อรับลิงก์สำหรับรีเซ็ตรหัสผ่าน +

+ +
+ + + {requestMutation.isError && ( + + {requestMutation.error.message || "การส่งคำขอล้มเหลว"} + + )} + + + + +
+ ย้อนกลับไปหน้าล็อกอิน +
+
+
+ +
+
+ ); +} \ No newline at end of file diff --git a/web/src/pages/auth/RegisterPage.jsx b/web/src/pages/auth/RegisterPage.jsx new file mode 100644 index 0000000..f9a7ed8 --- /dev/null +++ b/web/src/pages/auth/RegisterPage.jsx @@ -0,0 +1,83 @@ +import { Link } from 'react-router-dom'; +import { useForm } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; + +import { useRegisterMutation } from '../../services/authApi'; +import { registrationSchema } from '../../schemas/authSchema'; +import InputText from '../../components/InputText'; +import RegisterInfoCard from '../../components/Registration/RegisterInfoCard'; + + +export default function RegisterPage() { + const registerMutation = useRegisterMutation(); + + // ... (Hook Form Setup และ Logic เหมือนเดิม) ... + const { register, handleSubmit, formState: { errors } } = useForm({ + resolver: yupResolver(registrationSchema), + defaultValues: { username: '', email: '', phone_number: '', password: '', confirm_password: '' } + }); + + const onSubmit = (data) => { + const { confirm_password: _, ...payload } = data; + registerMutation.mutate(payload); + }; + + const loading = registerMutation.isPending; + + return ( + // Card หลัก: ใช้ h-full เพื่อให้เต็มหน้าจอ (ตาม AuthLayout.jsx ที่ถูกปรับ) +
+ + {/* Grid Layout: แบ่งเป็น 12 ส่วน, 6 ส่วนสำหรับ Guide (ซ้าย), 6 ส่วนสำหรับ Form (ขวา) */} +
+ + {/* 1. คอลัมน์ซ้าย (Guide/Info Card) */} +
+ +
+ + {/* 2. คอลัมน์ขวา (Form หลัก) */} + {/* ใช้พื้นที่ 6/12 คอลัมน์ (50%), แสดง Form ที่นี่ */} +
+
+ +

สร้างบัญชี DDO Console

+

กรุณากรอกข้อมูลที่จำเป็นทั้งหมดเพื่อเข้าใช้งานระบบ MLOps Gateway

+ +
+ + {/* ... (ErrorText และ Input Fields ทั้งหมดเหมือนเดิม) ... */} + +
+ + + + + +
+ + + +
+ เป็นสมาชิกอยู่แล้ว? + + + เข้าสู่ระบบ + + +
+
+
+
+ +
+
+ ); +} \ No newline at end of file diff --git a/web/src/pages/auth/ResetConfirmPage.jsx b/web/src/pages/auth/ResetConfirmPage.jsx new file mode 100644 index 0000000..de1ddf9 --- /dev/null +++ b/web/src/pages/auth/ResetConfirmPage.jsx @@ -0,0 +1,49 @@ +import React from 'react'; +import { useParams, Link } from 'react-router-dom'; +import { useConfirmPasswordReset } from '../../services/authApi'; +import ResetPasswordForm from '../../components/PasswordReset/ResetPasswordForm'; + +import { FaLock } from 'react-icons/fa'; // Icon Lock + +export default function ResetConfirmPage() { + // 1. Logic Management (รับพารามิเตอร์และ Hook) + const { uid, token } = useParams(); + const confirmMutation = useConfirmPasswordReset(); + + // 2. Pre-check: ตรวจสอบ URL Validity + if (!uid || !token) { + return ( +
+
+ + ลิงก์รีเซ็ตรหัสผ่านไม่สมบูรณ์ หรือหมดอายุแล้ว +
กลับสู่หน้าล็อกอิน
+
+
+ ); + } + + // 3. Presentation (A-List UI) + return ( +
+
+ +
+
+ {/* ไอคอน Lock ขนาดใหญ่ พร้อมพื้นหลังสีอ่อน */} + +

ยืนยันการตั้งรหัสผ่าน

+
+ + {/* Rendering the separated Form Component */} + + +
+
+
+ ); +} \ No newline at end of file diff --git a/web/src/pages/data/InferenceRun.jsx b/web/src/pages/data/InferenceRun.jsx new file mode 100644 index 0000000..e2dc52d --- /dev/null +++ b/web/src/pages/data/InferenceRun.jsx @@ -0,0 +1,64 @@ +import React, { useState } from 'react'; +// Import Components ย่อยจากโฟลเดอร์ components/ +import ModelSelector from '../../components/ModelSelector'; +import FileUploadAndSubmit from '../../components/FileUploadAndSubmit'; +import ResultDisplay from '../../components/ResultDisplay'; + +// Import Hooks จากโฟลเดอร์ services/ +//import { useActiveModelList } from '../../services/modelRegistryApi'; +import { useRunInferenceMutation } from '../../services/inferenceApi'; + +export default function InferenceRun() { + // 1. Hooks สำหรับดึงข้อมูลและเรียกใช้งาน AI + //const { data: activeModels, isLoading } = useActiveModelList(); + const { mutateAsync: runInference, isPending } = useRunInferenceMutation(); + + // 2. State สำหรับ Component + const [selectedModelId] = useState(''); + const [file, setFile] = useState(null); + const [result, setResult] = useState(null); + + // 3. Logic เมื่อกดปุ่ม Submit + const handleSubmit = async (e) => { + e.preventDefault(); + setResult(null); // เคลียร์ผลลัพธ์เก่า + + if (!selectedModelId || !file) return alert('กรุณาเลือก Model และอัปโหลดไฟล์'); + + const formData = new FormData(); + formData.append('file', file); + + try { + // เรียก Mutation Hook: ส่ง modelId แทน targetUrl + const res = await runInference({ + formData, + modelId: selectedModelId // Backend คาดหวัง String ใน URL Path + }); + setResult(res); + } catch (error) { + // Error handling ถูกจัดการด้วย Toast ใน Hook แล้ว + console.error('Inference run failed in page component:', error); + } + }; + + return ( +
+

AI Inference (Run)

+

เลือก Model ที่ต้องการ และอัปโหลดไฟล์เพื่อสั่งรันการประมวลผล

+ + {/* Component 1: ตัวเลือก Model */} + + {/* Component 2: อัปโหลดไฟล์และปุ่ม Submit */} + + + {/* Component 3: แสดงผลลัพธ์ */} + +
+ ); +} \ No newline at end of file diff --git a/web/src/pages/data/ModelRegistry.jsx b/web/src/pages/data/ModelRegistry.jsx new file mode 100644 index 0000000..c35c9b7 --- /dev/null +++ b/web/src/pages/data/ModelRegistry.jsx @@ -0,0 +1,29 @@ +import React from 'react'; +import TitleCard from '../../components/TitleCard'; + +function ModelRegistry() { + // ลบ State, Hooks, และ Logic การจัดการ Model ทั้งหมดออก + + return ( +
+ +
+

ฟังก์ชัน Model Registry ถูกนำออกแล้ว

+

+ คุณลักษณะสำหรับการลงทะเบียน, จัดการ, และควบคุม Model AI ถูกลบออกจากระบบแล้ว +

+
+
+ + {/* ลบ ModalForm และ ConfirmModal ออก */} + +
+ ); +} + +export default ModelRegistry; \ No newline at end of file diff --git a/web/src/pages/system/Health.jsx b/web/src/pages/system/Health.jsx new file mode 100644 index 0000000..b3a5e46 --- /dev/null +++ b/web/src/pages/system/Health.jsx @@ -0,0 +1,52 @@ +import React from 'react'; +import TitleCard from '../../components/TitleCard'; +import { useSystemHealth } from '../../services/healthApi'; +import { FaTimesCircle, FaSyncAlt, FaCheckCircle } from 'react-icons/fa'; + +// Imports Components ย่อย +import InfraStatusCard from '../../components/Health/InfraStatusCard'; +import ModelEndpointsStatus from '../../components/Health/ModelEndpointList'; + + +export default function SystemHealth() { + const { data, isLoading, isError, isFetching } = useSystemHealth(); + + // ตรวจสอบสถานะภาพรวม + const overallStatus = data?.status || (isError ? 'Error' : 'Loading'); + const overallColor = overallStatus === 'Healthy' ? 'alert-success' : overallStatus === 'Degraded' ? 'alert-warning' : 'alert-error'; + const lastChecked = data?.last_checked ? new Date(data.last_checked).toLocaleTimeString() : 'N/A'; + + if (isError) { + return +

ไม่สามารถเชื่อมต่อกับ Health API ได้ (Backend อาจหยุดทำงาน)

+
+ } + + return ( + : null} + > + + {/* 1. สถานะภาพรวม */} +
+ + {overallStatus === 'Healthy' ? : } + สถานะภาพรวม: {overallStatus} + +
+ + {/* 2. Infrastructure Services Card */} + {data?.services && } + + {/* 3. Model Endpoint List */} + {data?.services?.model_endpoints && } + + {/* เวลาตรวจสอบ */} +

+ {isLoading && !data ? "กำลังตรวจสอบสถานะครั้งแรก..." : `อัปเดตล่าสุด: ${lastChecked}`} +

+
+ ); +} \ No newline at end of file diff --git a/web/src/pages/system/UserGuide.jsx b/web/src/pages/system/UserGuide.jsx new file mode 100644 index 0000000..c27e90b --- /dev/null +++ b/web/src/pages/system/UserGuide.jsx @@ -0,0 +1,77 @@ +// src/pages/Guide/UserGuide.jsx +import React from 'react'; +import { FaUpload, FaFlask, FaDatabase, FaServer, FaBook } from 'react-icons/fa'; +import TitleCard from '../../components/TitleCard'; + +export default function UserGuide() { + return ( + } + > + {/* SINGLE COLUMN LAYOUT */} +
+
+ + {/* ภาพรวม */} +
+

ภาพรวมระบบ DDO Console

+

+ DDO Console ถูกออกแบบมาเพื่อเป็น MLOps Gateway สำหรับจัดการวงจรชีวิต + ของ AI Model ทางการแพทย์ (Medical Imaging AI) โดยเฉพาะ... +

+
+ + {/* Model Registry */} +
+

+ 1. Model Registry & Control +

+ +
    +
  • ไปที่เมนู "Model Registry & Control"
  • +
  • การลงทะเบียน: ต้องกรอก Base URL และ Inference Path
  • +
+
+ + {/* Inference */} +
+

+ 2. AI Inference (Run) +

+ +
    +
  • เลือก Model: ต้องเลือกเฉพาะ Model ที่เป็น ACTIVE
  • +
  • อัปโหลดไฟล์: รองรับไฟล์ภาพ NIfTI (.nii)
  • +
+
+ + {/* การเตรียม Model */} +
+

+ 3. การเตรียม Model (Deployment) +

+ +
    +
  • การจัดเก็บ: ไฟล์โมเดลต้องอยู่ใน MinIO bucket 'models'
  • +
  • FastAPI: ต้องมี Health Check (GET)
  • +
+
+ + {/* การตรวจสอบสถานะ */} +
+

+ 4. การตรวจสอบสถานะระบบ (System Ops) +

+ +

+ ใช้เมนู "สถานะระบบ (Health)" เพื่อตรวจสอบความพร้อมของ infrastructure และ Model ACTIVE +

+
+ +
+
+
+ ); +} diff --git a/web/src/routes/AuthRoutes.jsx b/web/src/routes/AuthRoutes.jsx new file mode 100644 index 0000000..109dc27 --- /dev/null +++ b/web/src/routes/AuthRoutes.jsx @@ -0,0 +1,27 @@ +import { Route, Routes, Navigate } from "react-router-dom"; +import AuthLayout from "../layouts/AuthLayout.jsx"; +import LoginForm from "../components/LoginForm.jsx"; +import RegisterPage from "../pages/auth/RegisterPage.jsx"; +import ForgotPasswordPage from "../pages/auth/ForgotPasswordPage.jsx"; +import ResetConfirmPage from "../pages/auth/ResetConfirmPage.jsx"; + +export default function AuthRoutes() { + return( + + {/* 1. Root Path ('/') นำทางไปยัง /login ทันที */} + } /> + + {/* 2. AuthLayout สำหรับหน้า Login, Register, Forgot Password */} + }> + }/> + }/> + }/> + } + /> + + + {/* 3. Fallback สำหรับเส้นทางที่ไม่รู้จักในส่วน Public */} + 404 Not Found}/> + + ); +} \ No newline at end of file diff --git a/web/src/routes/PrivateRoutes.jsx b/web/src/routes/PrivateRoutes.jsx new file mode 100644 index 0000000..60c1dfc --- /dev/null +++ b/web/src/routes/PrivateRoutes.jsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { Routes, Route } from "react-router-dom"; +import ProtectedRoute from "./ProtectedRoute.jsx"; +import MainLayout from "../layouts/MainLayout.jsx"; + +// Import เส้นทางย่อยทั้งหมดที่กำหนดไว้ภายนอก +import pageRoutes from './pageRoutes.jsx'; + + +export default function PrivateRoutes() { + return ( + // 1. Routes หลักที่ครอบคลุมทั้งหมดภายใต้ /dashboard/* + + {/* 2. Layer ความปลอดภัย: MainLayout ถูกครอบด้วย ProtectedRoute */} + } />}> + + {/* 3. Layer เส้นทางย่อย: วนซ้ำ pageRoutes เพื่อสร้าง s */} + {pageRoutes.map((route, index) => ( + // สร้าง Route สำหรับแต่ละรายการใน pageRoutes + + ))} + + + + ); +} \ No newline at end of file diff --git a/web/src/routes/ProtectedRoute.jsx b/web/src/routes/ProtectedRoute.jsx new file mode 100644 index 0000000..b2debaf --- /dev/null +++ b/web/src/routes/ProtectedRoute.jsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import { Navigate } from 'react-router-dom'; + +export default function ProtectedRoute({ element: Element }) { + // ดึงสถานะการล็อกอินจาก Redux Store + const isAuthenticated = useSelector(state => state.auth.isAuthenticated); + + if (!isAuthenticated) { + // ถ้ายังไม่ได้ล็อกอิน ให้นำทางกลับไปที่หน้า /login + // replace: true ป้องกันการย้อนกลับไปหน้า Dashboard ใน History + return ; + } + + // ถ้าล็อกอินแล้ว อนุญาตให้แสดง Element (Layout/Page) + return Element; +} diff --git a/web/src/routes/pageRoutes.jsx b/web/src/routes/pageRoutes.jsx new file mode 100644 index 0000000..06cb992 --- /dev/null +++ b/web/src/routes/pageRoutes.jsx @@ -0,0 +1,52 @@ +import Dashboard from '../pages/Dashboard'; +import BlankPage from '../pages/BlankPage'; +import ModelRegistry from '../pages/data/ModelRegistry'; +import InferenceRun from '../pages/data/InferenceRun'; +import SystemHealth from '../pages/system/Health'; +import UserGuide from '../pages/system/UserGuide'; +import Profile from '../pages/Profile'; + +// Array ของเส้นทางย่อยภายใต้ /dashboard/ +const pageRoutes = [ + // --- Dashboard --- + { + path: '', // ตรงกับ /dashboard + element: , + }, + // --- Model Registry & Control --- + { + // Path: /dashboard/model-registry + path: 'model-registry', + element: , + }, + // --- AI Inference (Run) --- + { + // Path: /dashboard/inference-run + path: 'inference-run', + element: , + }, + // --- สถานะระบบ (Health) --- + { + // Path: /dashboard/health + path: 'health', + element: , + }, + // --- คู่มือการใช้งาน (Guide) --- + { + // Path: /dashboard/guide + path: 'guide', + element: , + }, + // --- Profile Management --- + { + path: 'profile', + element: , + }, + // Fallback สำหรับเส้นทางที่ไม่ตรงกับเมนูใดๆ + { + path: '*', + element: , + } +]; + +export default pageRoutes; diff --git a/web/src/schemas/authSchema.js b/web/src/schemas/authSchema.js new file mode 100644 index 0000000..b0d669b --- /dev/null +++ b/web/src/schemas/authSchema.js @@ -0,0 +1,42 @@ +import * as yup from 'yup'; + +// ---------------------------------------------------------------------- +// Schema สำหรับตรวจสอบข้อมูล Login (ใช้ Yup) +// ---------------------------------------------------------------------- +export const loginSchema = yup.object().shape({ + username: yup.string().required('กรุณากรอกชื่อผู้ใช้งาน'), + password: yup.string().required('กรุณากรอกรหัสผ่าน'), +}); + +// Schema สำหรับตรวจสอบข้อมูล Registration +export const registrationSchema = yup.object().shape({ + username: yup.string().required('กรุณากรอกชื่อผู้ใช้งาน').min(4, 'ชื่อผู้ใช้ต้องมีความยาวอย่างน้อย 4 ตัวอักษร'), + email: yup.string().email('รูปแบบอีเมลไม่ถูกต้อง').required('กรุณากรอกอีเมล'), + phone_number: yup.string().nullable().matches(/^[0-9]*$/, 'เบอร์โทรศัพท์ต้องเป็นตัวเลขเท่านั้น'), + password: yup.string().required('กรุณากรอกรหัสผ่าน').min(8, 'รหัสผ่านต้องมีความยาวอย่างน้อย 8 ตัวอักษร'), + confirm_password: yup.string() + .oneOf([yup.ref('password'), null], 'รหัสผ่านไม่ตรงกัน') + .required('กรุณายืนยันรหัสผ่าน'), +}); + +export const resetConfirmSchema = yup.object().shape({ + new_password: yup.string().required('กรุณากรอกรหัสผ่านใหม่').min(8, 'รหัสผ่านต้องมีอย่างน้อย 8 ตัวอักษร'), + re_new_password: yup.string() + .oneOf([yup.ref('new_password'), null], 'รหัสผ่านไม่ตรงกัน') + .required('กรุณายืนยันรหัสผ่านใหม่'), +}); + +export const profileSchema = yup.object().shape({ + first_name: yup.string().nullable(), + last_name: yup.string().nullable(), + phone_number: yup.string().nullable().matches(/^[0-9]*$/, 'เบอร์โทรศัพท์ต้องเป็นตัวเลขเท่านั้น'), + email: yup.string().email('รูปแบบอีเมลไม่ถูกต้อง').required('ต้องระบุอีเมล'), +}); + +export const passwordSchema = yup.object().shape({ + current_password: yup.string().required('กรุณากรอกรหัสผ่านปัจจุบัน'), + new_password: yup.string().required('กรุณากรอกรหัสผ่านใหม่').min(8, 'รหัสผ่านต้องมีอย่างน้อย 8 ตัวอักษร'), + re_new_password: yup.string() + .oneOf([yup.ref('new_password'), null], 'รหัสผ่านใหม่ไม่ตรงกัน') + .required('กรุณายืนยันรหัสผ่านใหม่'), +}); \ No newline at end of file diff --git a/web/src/schemas/modelSchema.js b/web/src/schemas/modelSchema.js new file mode 100644 index 0000000..2769391 --- /dev/null +++ b/web/src/schemas/modelSchema.js @@ -0,0 +1,11 @@ +import * as yup from 'yup'; + +export const modelSchema = yup.object().shape({ + name: yup.string().required('ต้องระบุชื่อโมเดล'), + model_version: yup.string().required('ต้องระบุเวอร์ชัน'), + developer: yup.string().nullable(), + base_url: yup.string().url('ต้องเป็นรูปแบบ URL ที่ถูกต้อง').required('ต้องระบุ Internal Base URL'), + inference_path: yup.string().required('ต้องระบุ Inference Path'), + status: yup.string().oneOf(['ACTIVE', 'INACTIVE', 'TESTING']).required(), + auth_required: yup.boolean(), +}); diff --git a/web/src/services/auditApi.js b/web/src/services/auditApi.js new file mode 100644 index 0000000..079d331 --- /dev/null +++ b/web/src/services/auditApi.js @@ -0,0 +1,21 @@ +import { useQuery } from '@tanstack/react-query'; +import axiosClient from './axiosClient'; + +const STALE_TIME = 60000; // 1 นาที + +/** + * Hook สำหรับดึงสรุปสถิติ Inference (Total Runs, Success Rate, Avg Latency) + * Endpoint: GET /api/v1/audit/inference-summary/ + */ +export const useInferenceSummary = () => { + return useQuery({ + queryKey: ['inferenceSummary'], + queryFn: async () => { + const response = await axiosClient.get('/api/v1/audit/inference-summary/'); + return response.data; + }, + staleTime: STALE_TIME, + // ดึงข้อมูลใหม่ทุก 30 วินาทีเพื่ออัปเดตสถิติ Dashboard + refetchInterval: 30000, + }); +}; \ No newline at end of file diff --git a/web/src/services/authApi.js b/web/src/services/authApi.js new file mode 100644 index 0000000..57945de --- /dev/null +++ b/web/src/services/authApi.js @@ -0,0 +1,340 @@ +import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; +import { useDispatch, useSelector } from 'react-redux'; +import { loginSuccess, updateUser } from '../features/auth/authSlice'; +import { useNavigate } from 'react-router-dom'; +import axios from 'axios'; // ใช้ Axios ธรรมดาสำหรับการเรียกที่ยังไม่มี Token +import { addToast } from '../features/toast/toastSlice'; +import axiosClient from "./axiosClient.js"; + +const API_BASE_URL = import.meta.env.VITE_API_BASE_URL; + +// ---------------------------------------------------- +// Helper Functions +// ---------------------------------------------------- + +/** + * แปลง Object ให้เป็นฟอร์มข้อมูล (x-www-form-urlencoded) + */ +const toFormUrlEncoded = (data) => { + // วนซ้ำ key และ encode + return Object.keys(data) + .map(key => { + let value = data[key]; + // รับค่า remember_me (boolean) มาแปลงเป็น String 'true' + if (value === true) { + value = 'true'; + } else if (value === false) { + value = 'false'; // หรือจะส่งเฉพาะเมื่อเป็น true ก็ได้ + } + return encodeURIComponent(key) + '=' + encodeURIComponent(value); + }) + .join('&'); +}; + +/** + * กำหนดบทบาท (Role) จาก Django User Object ที่สมบูรณ์ + * @param {object} user - User Object จาก /users/me/ + */ +const determineRole = (user) => { + if (!user || !user.id) { + return 'guest'; + } + + // 1. ใช้ฟิลด์ 'role' ที่ส่งมาจาก Backend โดยตรง (ถ้ามี) + if (user.role) { + return user.role.toLowerCase(); // เช่น 'ADMIN' -> 'admin' + } + + // 2. ใช้ฟิลด์ is_superuser/is_staff เป็น Fallback/เกณฑ์มาตรฐาน + if (user.is_superuser) { + return 'admin'; + } + if (user.is_staff) { + // ถ้าเป็น is_staff แต่ไม่ใช่ superuser + return 'manager'; + } + + // ผู้ใช้ทั่วไป + return 'viewer'; +}; + + +/** + * ฟังก์ชันหลักในการล็อกอิน: ขั้นตอนที่ 1 (รับ Token) และ ขั้นตอนที่ 2 (รับ User Object) + */ +const loginUser = async (credentials) => { + // credentials จะเป็น { username, password } + const formData = toFormUrlEncoded(credentials); + + let access, refresh; + + // --------------------------------------------- + // ขั้นตอนที่ 1: รับ Access/Refresh Token (POST /jwt/create/) + // --------------------------------------------- + try { + const tokenResponse = await axios.post(`${API_BASE_URL}/api/v1/auth/jwt/create/`, formData, { + headers: { 'Content-Type': 'application/x-www-form-urlencoded' } + }); + + access = tokenResponse.data.access; + refresh = tokenResponse.data.refresh; + + } catch (error) { + // จัดการ Error จากการล็อกอิน + const errorMessage = error.response?.data?.detail || "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง"; + throw new Error(errorMessage); + } + + // --------------------------------------------- + // ขั้นตอนที่ 2: ใช้ Access Token เพื่อดึง User Object (GET /users/me/) + // --------------------------------------------- + let user; + try { + const userResponse = await axios.get(`${API_BASE_URL}/api/v1/auth/users/me/`, { + headers: { + // ใช้ JWT เพื่อยืนยันตัวตน + 'Authorization': `Bearer ${access}`, + }, + }); + + user = userResponse.data; + + } catch (error) { + console.error("Failed to fetch user data after token creation:", error); + throw new Error("ล็อกอินสำเร็จ แต่ไม่สามารถดึงข้อมูลผู้ใช้ได้ (กรุณาติดต่อผู้ดูแลระบบ)"); + } + + // --------------------------------------------- + // ขั้นตอนที่ 3: คำนวณ Role และส่งกลับข้อมูล + // --------------------------------------------- + const userRole = determineRole(user); + + return { + access_token: access, + refresh_token: refresh, + user: user, + role: userRole, + }; +}; + + +// ---------------------------------------------------- +// Custom Hook สำหรับจัดการการล็อกอิน +// ---------------------------------------------------- +export const useLoginMutation = () => { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: loginUser, + onSuccess: (data) => { + + // 1. จัดการ Token และ User Data + localStorage.setItem('token', data.access_token); + // บันทึก Refresh Token แยกต่างหาก + localStorage.setItem('refresh_token', data.refresh_token); + localStorage.setItem('user', JSON.stringify(data.user)); + localStorage.setItem('role', data.role); // บันทึก Role ที่ถูกต้อง + + // 2. อัปเดต Redux State + dispatch(loginSuccess({ user: data.user, role: data.role })); + + // 3. นำทางผู้ใช้ + navigate('/dashboard', { replace: true }); + // Invalidating Query ที่เกี่ยวข้อง + queryClient.invalidateQueries({ queryKey: ['userData'] }); + queryClient.invalidateQueries({ queryKey: ['userProfile'] }); + queryClient.invalidateQueries({ queryKey: ['modelList'] }); + }, + onError: (error) => { + // error.message ถูกโยนมาจาก loginUser function + console.error('Login API Error:', error.message); + throw new Error(error.message); + }, + }); +}; + +// ---------------------------------------------------- +// Helper Function: Registration API Call +// ---------------------------------------------------- +const registerNewUser = async (userData) => { + // Djoser Endpoint: POST /api/v1/auth/users/ (รับ username, email, password, phone_number) + // Djoser /users/ Endpoint รับ JSON Body ได้โดยตรง (ไม่ใช้ x-www-form-urlencoded) + + // ลบ confirm_password ออกจาก payload ก่อนส่ง + // ใช้ _ นำหน้าเพื่อบอก ESLint ว่าตัวแปรนี้จะไม่ถูกใช้ + // ต้องการ confirm_password เพื่อให้ Yup (Validation) ทำงาน แต่เราไม่ต้องการส่งมันไปยัง API Backend (เพราะ Djoser API ไม่ได้รับ Field นี้) + const { confirm_password: _, ...payload } = userData; + + try { + const response = await axios.post(`${API_BASE_URL}/api/v1/auth/users/`, payload); + return response.data; + + } catch (error) { + // จัดการ Error เช่น Username/Email ซ้ำ + const errorDetail = error.response?.data; + let errorMessage = "การลงทะเบียนล้มเหลว โปรดตรวจสอบข้อมูลอีกครั้ง"; + + if (errorDetail) { + if (errorDetail.username) errorMessage = `ชื่อผู้ใช้งาน: ${errorDetail.username[0]}`; + else if (errorDetail.email) errorMessage = `อีเมล: ${errorDetail.email[0]}`; + else if (errorDetail.phone_number) errorMessage = `เบอร์โทรศัพท์: ${errorDetail.phone_number[0]}`; + } + + throw new Error(errorMessage); + } +}; + +// ---------------------------------------------------- +// Custom Hook สำหรับจัดการการลงทะเบียน +// ---------------------------------------------------- +export const useRegisterMutation = () => { + const dispatch = useDispatch(); + const navigate = useNavigate(); + + return useMutation({ + mutationFn: registerNewUser, + onSuccess: () => { + dispatch(addToast({ message: 'ลงทะเบียนสำเร็จ! คุณสามารถเข้าสู่ระบบได้ทันที', type: 'success' })); + navigate('/login'); + }, + onError: (error) => { + // ส่ง Toast แจ้งเตือนข้อผิดพลาดที่โยนมาจาก registerNewUser + dispatch(addToast({ message: `ลงทะเบียนล้มเหลว: ${error.message}`, type: 'error' })); + throw new Error(error.message); + }, + }); +}; + +// ---------------------------------------------------- +// Hook สำหรับส่งคำขอรีเซ็ตรหัสผ่าน (ขั้นตอน A) +// ---------------------------------------------------- +export const useRequestPasswordReset = () => { + const dispatch = useDispatch(); + + return useMutation({ + mutationFn: async ({ email }) => { + // Djoser Endpoint: รับ email/username เพื่อส่งอีเมล + const response = await axios.post( + `${API_BASE_URL}/api/v1/auth/users/reset_password/`, + { email: email } // Djoser รับ JSON Body + ); + return response.data; + }, + onSuccess: () => { + dispatch(addToast({ + message: 'คำขอรีเซ็ตถูกส่งไปยังอีเมลของคุณแล้ว', + type: 'success' + })); + }, + onError: (error) => { + const msg = error.response?.data?.detail || 'ไม่พบผู้ใช้งานด้วยอีเมลนี้'; + dispatch(addToast({ message: `ล้มเหลว: ${msg}`, type: 'error' })); + throw new Error(msg); + }, + }); +}; + + +// ---------------------------------------------------- +// Hook สำหรับยืนยันและตั้งรหัสผ่านใหม่ (ขั้นตอน B) +// ---------------------------------------------------- +export const useConfirmPasswordReset = () => { + const dispatch = useDispatch(); + const navigate = useNavigate(); + + return useMutation({ + mutationFn: async (data) => { + // Djoser Endpoint: รับ uid, token, new_password + const response = await axios.post( + `${API_BASE_URL}/api/v1/auth/users/reset_password_confirm/`, + data + ); + return response.data; + }, + onSuccess: () => { + dispatch(addToast({ + message: 'รหัสผ่านถูกตั้งค่าใหม่เรียบร้อยแล้ว!', + type: 'success' + })); + navigate('/login', { replace: true }); + }, + onError: (error) => { + const msg = error.response?.data?.detail || 'ลิงก์ไม่ถูกต้องหรือหมดอายุ'; + dispatch(addToast({ message: `ตั้งรหัสผ่านใหม่ล้มเหลว: ${msg}`, type: 'error' })); + throw new Error(msg); + }, + }); +}; + +/** + * ฟังก์ชันสำหรับเรียก API เพื่อต่ออายุ Access Token ด้วย Refresh Token + */ +export const refreshAccessToken = async () => { + const refresh = localStorage.getItem('refresh_token'); // เก็บ Refresh Token แยกต่างหาก + + if (!refresh) { + throw new Error("Refresh token not found."); + } + + const response = await axios.post(`${API_BASE_URL}/api/v1/auth/jwt/refresh/`, { + refresh: refresh, + }); + + // คืนค่า Access Token ใหม่ + return response.data.access; +}; + +// ---------------------------------------------------- +// Hook ดึงข้อมูลผู้ใช้ปัจจุบัน (GET /users/me/) +// ---------------------------------------------------- +export const useUserQuery = () => { + // ดึงสถานะปัจจุบันของ User จาก Redux Store + const userId = useSelector(state => state.auth.user?.id); + const isAuthenticated = useSelector(state => state.auth.isAuthenticated); + + return useQuery({ + // ทำให้ Query Key ขึ้นอยู่กับ User ID + queryKey: ['userProfile', userId], + + // ไม่รัน Query ถ้าผู้ใช้ไม่ได้ล็อกอิน + enabled: isAuthenticated && !!userId, + + queryFn: async () => { + const response = await axiosClient.get(`${API_BASE_URL}/api/v1/auth/users/me/`); + return response.data; + }, + staleTime: 60000, + }); +}; + +// ---------------------------------------------------- +// Hook อัปเดตข้อมูลผู้ใช้ (PATCH /users/me/) +// ---------------------------------------------------- +export const useUpdateProfileMutation = () => { + const queryClient = useQueryClient(); + const dispatch = useDispatch(); + + return useMutation({ + mutationFn: async (profileData) => { + // Djoser Endpoint: PATCH /users/me/ + const response = await axiosClient.patch(`${API_BASE_URL}/api/v1/auth/users/me/`, profileData); + return response.data; + }, + onSuccess: (updatedUser) => { + dispatch(addToast({ message: 'แก้ไขข้อมูลส่วนตัวสำเร็จแล้ว!', type: 'success' })); + + // อัปเดต Redux Store และ Local Storage ทันที + const newRole = determineRole(updatedUser); + dispatch(updateUser({ user: updatedUser, role: newRole })); + + // Invalidate Query เพื่อดึงข้อมูล Profile ใหม่ + queryClient.invalidateQueries({ queryKey: ['userProfile'] }); + }, + onError: (error) => { + const msg = error.response?.data?.email || error.response?.data?.detail || 'การอัปเดตล้มเหลว'; + dispatch(addToast({ message: `อัปเดต Profile ล้มเหลว: ${msg}`, type: 'error' })); + }, + }); +}; \ No newline at end of file diff --git a/web/src/services/axiosClient.js b/web/src/services/axiosClient.js new file mode 100644 index 0000000..907552d --- /dev/null +++ b/web/src/services/axiosClient.js @@ -0,0 +1,107 @@ +import axios from 'axios'; +import { getStore } from '../app/store'; +import { logout } from '../features/auth/authSlice'; +import { refreshAccessToken } from './authApi'; + +// REGEX ตรวจจับตัวเลขที่ใหญ่เกิน 15 หลัก (ซึ่งเกินขีดจำกัดความปลอดภัยของ JS) +const bigIntRegex = /"id":(\d{15,})/g; + +// 1. สร้าง Axios Instance โดยใช้ Base URL จาก .env +const axiosClient = axios.create({ + baseURL: import.meta.env.VITE_API_BASE_URL, + // กำหนด Timeout เพื่อป้องกันการค้าง + timeout: 15000, + transformResponse: [ + function (data) { + if (typeof data === 'string') { + // 1. ใช้ Regex เพื่อค้นหาฟิลด์ "id" ที่มีตัวเลขเกิน 15 หลัก + data = data.replace(bigIntRegex, (match, p1) => { + // 2. แปลงตัวเลขนั้นให้เป็น String ที่มีเครื่องหมายคำพูดล้อมรอบ + return `"id":"${p1}"`; + }); + } + // 3. เรียก JSON.parse หลังจากแปลงแล้ว + try { + return JSON.parse(data); + } catch { + return data; // คืนค่าเดิมถ้าไม่สามารถ Parse JSON ได้ (เช่น 404 text) + } + }, + ].concat(axios.defaults.transformResponse || []), +}); + + +// 2. เพิ่ม Interceptor เพื่อแนบ Token ใน Header +axiosClient.interceptors.request.use( + (config) => { + // ดึง Token จาก Local Storage + const token = localStorage.getItem('token'); + + // ถ้ามี Token ให้แนบไปใน Header 'Authorization' + if (token) { + // รูปแบบจากเป็น 'Bearer' + // ตามที่กำหนดใน Django DRF/Djoser settings (JWTAuthentication) + config.headers.Authorization = `Bearer ${token}`; + } + + return config; + }, + (error) => { + return Promise.reject(error); + } +); + + +// 3. (Optional) Interceptor สำหรับ Response (จัดการ Token Expired) + +axiosClient.interceptors.response.use( + (response) => response, + async (error) => { + const status = error.response ? error.response.status : null; + const originalRequest = error.config; + + // ถ้าเป็น 401 และ Request นั้นยังไม่ถูกลอง Refresh + if (status === 401 && !originalRequest._retry) { + + originalRequest._retry = true; // ตั้ง Flag ว่ากำลังจะลอง Refresh + + const storeInstance = getStore(); + + try { + // 1. เรียกฟังก์ชัน Refresh Token + const newAccessToken = await refreshAccessToken(); + + // 2. บันทึก Access Token ใหม่ + localStorage.setItem('token', newAccessToken); + + // 3. อัปเดต Header ของ Request เดิม + originalRequest.headers.Authorization = `Bearer ${newAccessToken}`; + + // 4. ลองเรียก Request เดิมซ้ำอีกครั้ง + return axiosClient(originalRequest); + + } catch (refreshError) { + // หาก Refresh Token ล้มเหลว (หมดอายุ 30 วันแล้ว) + console.error("JWT Refresh Failed. Logging out.", refreshError); + storeInstance.dispatch(logout()); // บังคับ Logout + return Promise.reject(error); + } + } + + // ถ้าได้รับ 401 หรือ 403 (Token หมดอายุ/ไม่มีสิทธิ์) + if (status === 401 || status === 403) { + // Logic สำหรับการจัดการ Token หมดอายุ (เช่น Redirect ไปหน้า Login) + console.error("Authorization Failed: Token expired or insufficient roles."); + + // บังคับ Logout + const storeInstance = getStore(); // เรียกใช้ store instance + if (storeInstance) { + storeInstance.dispatch(logout()); // เรียก Redux Action + } + } + return Promise.reject(error); + } +); + + +export default axiosClient; \ No newline at end of file diff --git a/web/src/services/healthApi.js b/web/src/services/healthApi.js new file mode 100644 index 0000000..9cf5228 --- /dev/null +++ b/web/src/services/healthApi.js @@ -0,0 +1,35 @@ +import { useQuery } from '@tanstack/react-query'; +import axiosClient from './axiosClient'; +import { addToast } from '../features/toast/toastSlice'; +import { useDispatch } from 'react-redux'; + +const REFETCH_INTERVAL = 15000; // ดึงข้อมูลใหม่ทุก 15 วินาที + +/** + * Hook สำหรับดึงสถานะ Health Check ของระบบทั้งหมด + * Endpoint: GET /api/v1/health/ + */ +export const useSystemHealth = () => { + const dispatch = useDispatch(); + + return useQuery({ + queryKey: ['systemHealth'], + queryFn: async () => { + const response = await axiosClient.get('/api/v1/health/'); + + // แจ้งเตือนเมื่อสถานะกลับมา UP จาก Degraded + if (response.data.status === 'Healthy') { + // dispatch(addToast({ message: 'System Health Status: Healthy', type: 'info' })); + } + return response.data; + }, + // ตั้งค่า Polling ให้ดึงข้อมูลใหม่ทุก 15 วินาที + refetchInterval: REFETCH_INTERVAL, + staleTime: 5000, + + // จัดการ Error เมื่อไม่สามารถเชื่อมต่อ API ได้เลย (เช่น 500 หรือ Network Failure) + onError: () => { + dispatch(addToast({ message: 'Network Error: Could not reach Health API', type: 'error' })); + } + }); +}; \ No newline at end of file diff --git a/web/src/services/inferenceApi.js b/web/src/services/inferenceApi.js new file mode 100644 index 0000000..cb1ca91 --- /dev/null +++ b/web/src/services/inferenceApi.js @@ -0,0 +1,38 @@ +import { useMutation } from '@tanstack/react-query'; +import axiosClient from './axiosClient'; +import { useDispatch } from 'react-redux'; +import { addToast } from '../features/toast/toastSlice'; + +/** + * Hook สำหรับสั่งรัน AI Inference ผ่าน Django DRF Proxy + * Endpoint: POST /api/v1/models/{modelId}/run-inference/ ⬅️ (ใหม่!) + */ +export const useRunInferenceMutation = () => { + const dispatch = useDispatch(); + + return useMutation({ + mutationFn: async ({ formData, modelId }) => { + + // ใช้ Template String เพื่อฝัง modelId เข้าไปใน URL + const response = await axiosClient.post( + `/api/v1/models/${modelId}/run-inference/`, + formData, + { + // ต้องระบุ Content-Type สำหรับการอัปโหลดไฟล์ + headers: { 'Content-Type': 'multipart/form-data' }, + // ตั้งค่า Timeout เผื่อการประมวลผล AI ที่นาน (10 นาที) + timeout: 600000, + } + ); + + return response.data; + }, + onSuccess: () => { + dispatch(addToast({ message: 'เริ่มกระบวนการ Inference แล้ว!', type: 'success' })); + }, + onError: (error) => { + const msg = error.response?.data?.detail || 'การประมวลผลล้มเหลว'; + dispatch(addToast({ message: `Inference Failed: ${msg}`, type: 'error' })); + }, + }); +}; \ No newline at end of file diff --git a/web/src/styles.css b/web/src/styles.css new file mode 100644 index 0000000..a54429f --- /dev/null +++ b/web/src/styles.css @@ -0,0 +1,5 @@ +@import url("https://fonts.googleapis.com/css2?family=Noto%20Sans%20Thai:wght@400;500;600;700;800;900&display=swap"); + +body { + font-family: 'Noto Sans Thai', sans-serif; +} diff --git a/web/vite.config.js b/web/vite.config.js new file mode 100644 index 0000000..b2c6fb0 --- /dev/null +++ b/web/vite.config.js @@ -0,0 +1,8 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import tailwindcss from '@tailwindcss/vite'; + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react(), tailwindcss()], +})
+ {/** Route header */} + setIsExpanded(!isExpanded)} + > +
+ {icon} + {name} +
+ +
+ + {/** Submenu list */} +
+
    + {submenu.map((m, k) => { + // กรองเมนูย่อยตามสิทธิ์ (RBAC) + if (!canAccess(m.requiredRole)) return null; + + return ( +
  • + {/* ใช้ NavLink เพื่อแสดงสถานะ Active และใช้ onClick เพื่อปิด Sidebar (สำหรับ Mobile) */} + + `text-base ${isActive ? 'bg-base-200 text-primary font-semibold' : 'hover:bg-base-400'}` + } + > + {m.icon} {m.name} + + {/* แถบสี Primary แสดงสถานะ Active */} + {location.pathname === m.path ? ( + + ) : null} + +
  • + ); + })} +
+
+