diff --git a/README.md b/README.md
index 74cf6e2ff..84a58ad48 100644
--- a/README.md
+++ b/README.md
@@ -22,10 +22,12 @@ Solution overview
The solution leverages Azure OpenAI Service, Azure Container Apps, Azure Cosmos DB, and Azure Container Registry to create an intelligent automation pipeline. It uses a multi-agent approach where specialized AI agents work together to plan, execute, and validate tasks based on user input.
### Solution architecture
-||
+||
|---|
-
+### Agentic architecture
+||
+|---|
### How to customize
If you'd like to customize the solution accelerator, here are some common areas to start:
@@ -111,7 +113,7 @@ either by deleting the resource group in the Portal or running `azd down`.
Business Scenario
-||
+||
|---|
diff --git a/__azurite_db_queue__.json b/__azurite_db_queue__.json
new file mode 100644
index 000000000..a4fcc30da
--- /dev/null
+++ b/__azurite_db_queue__.json
@@ -0,0 +1 @@
+{"filename":"c:\\src\\Multi-Agent-Custom-Automation-Engine-Solution-Accelerator\\__azurite_db_queue__.json","collections":[{"name":"$SERVICES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{},"constraints":null,"uniqueNames":["accountName"],"transforms":{},"objType":"$SERVICES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$QUEUES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[]},"name":{"name":"name","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$QUEUES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$MESSAGES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[]},"queueName":{"name":"queueName","dirty":false,"values":[]},"messageId":{"name":"messageId","dirty":false,"values":[]},"visibleTime":{"name":"visibleTime","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$MESSAGES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":5000,"autosaveHandle":null,"throttledSaves":true,"options":{"persistenceMethod":"fs","autosave":true,"autosaveInterval":5000,"serializationMethod":"normal","destructureDelimiter":"$<\n"},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}
\ No newline at end of file
diff --git a/__azurite_db_queue_extent__.json b/__azurite_db_queue_extent__.json
new file mode 100644
index 000000000..888954057
--- /dev/null
+++ b/__azurite_db_queue_extent__.json
@@ -0,0 +1 @@
+{"filename":"c:\\src\\Multi-Agent-Custom-Automation-Engine-Solution-Accelerator\\__azurite_db_queue_extent__.json","collections":[{"name":"$EXTENTS_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"id":{"name":"id","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$EXTENTS_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":5000,"autosaveHandle":null,"throttledSaves":true,"options":{"persistenceMethod":"fs","autosave":true,"autosaveInterval":5000,"serializationMethod":"normal","destructureDelimiter":"$<\n"},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}
\ No newline at end of file
diff --git a/docs/images/readme/agent_flow.png b/docs/images/readme/agent_flow.png
new file mode 100644
index 000000000..9e9c10daf
Binary files /dev/null and b/docs/images/readme/agent_flow.png differ
diff --git a/docs/images/readme/application.png b/docs/images/readme/application.png
new file mode 100644
index 000000000..ba6a90c1e
Binary files /dev/null and b/docs/images/readme/application.png differ
diff --git a/docs/images/readme/architecture.png b/docs/images/readme/architecture.png
new file mode 100644
index 000000000..6078f0f64
Binary files /dev/null and b/docs/images/readme/architecture.png differ
diff --git a/docs/images/readme/macae-application.png b/docs/images/readme/macae-application.png
deleted file mode 100644
index 923c3ad23..000000000
Binary files a/docs/images/readme/macae-application.png and /dev/null differ
diff --git a/docs/images/readme/macae-architecture.png b/docs/images/readme/macae-architecture.png
deleted file mode 100644
index 95826744e..000000000
Binary files a/docs/images/readme/macae-architecture.png and /dev/null differ
diff --git a/src/backend/app_kernel.py b/src/backend/app_kernel.py
index 217371d20..4467bbdfa 100644
--- a/src/backend/app_kernel.py
+++ b/src/backend/app_kernel.py
@@ -70,7 +70,7 @@
# Add this near the top of your app.py, after initializing the app
app.add_middleware(
CORSMiddleware,
- allow_origins=[frontend_url], # Add your frontend server URL
+ allow_origins=[frontend_url],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
@@ -519,10 +519,12 @@ async def approve_step_endpoint(
return {"status": "All steps approved"}
-@app.get("/api/plans", response_model=List[PlanWithSteps])
+@app.get("/api/plans")
async def get_plans(
- request: Request, session_id: Optional[str] = Query(None)
-) -> List[PlanWithSteps]:
+ request: Request,
+ session_id: Optional[str] = Query(None),
+ plan_id: Optional[str] = Query(None),
+):
"""
Retrieve plans for the current user.
@@ -607,6 +609,24 @@ async def get_plans(
plan_with_steps = PlanWithSteps(**plan.model_dump(), steps=steps)
plan_with_steps.update_step_counts()
return [plan_with_steps]
+ if plan_id:
+ plan = await memory_store.get_plan_by_plan_id(plan_id=plan_id)
+ if not plan:
+ track_event_if_configured(
+ "GetPlanBySessionNotFound",
+ {"status_code": 400, "detail": "Plan not found"},
+ )
+ raise HTTPException(status_code=404, detail="Plan not found")
+
+ # Use get_steps_by_plan to match the original implementation
+ steps = await memory_store.get_steps_by_plan(plan_id=plan.id)
+ messages = await memory_store.get_data_by_type_and_session_id(
+ "agent_message", session_id=plan.session_id
+ )
+
+ plan_with_steps = PlanWithSteps(**plan.model_dump(), steps=steps)
+ plan_with_steps.update_step_counts()
+ return [plan_with_steps, messages]
all_plans = await memory_store.get_all_plans()
# Fetch steps for all plans concurrently
@@ -756,6 +776,74 @@ async def get_agent_messages(session_id: str, request: Request) -> List[AgentMes
return agent_messages
+@app.get("/api/agent_messages_by_plan/{plan_id}", response_model=List[AgentMessage])
+async def get_agent_messages_by_plan(
+ plan_id: str, request: Request
+) -> List[AgentMessage]:
+ """
+ Retrieve agent messages for a specific session.
+
+ ---
+ tags:
+ - Agent Messages
+ parameters:
+ - name: session_id
+ in: path
+ type: string
+ required: true
+ in: path
+ type: string
+ required: true
+ description: The ID of the session to retrieve agent messages for
+ responses:
+ 200:
+ description: List of agent messages associated with the specified session
+ schema:
+ type: array
+ items:
+ type: object
+ properties:
+ id:
+ type: string
+ description: Unique ID of the agent message
+ session_id:
+ type: string
+ description: Session ID associated with the message
+ plan_id:
+ type: string
+ description: Plan ID related to the agent message
+ content:
+ type: string
+ description: Content of the message
+ source:
+ type: string
+ description: Source of the message (e.g., agent type)
+ timestamp:
+ type: string
+ format: date-time
+ description: Timestamp of the message
+ step_id:
+ type: string
+ description: Optional step ID associated with the message
+ 400:
+ description: Missing or invalid user information
+ 404:
+ description: Agent messages not found
+ """
+ authenticated_user = get_authenticated_user_details(request_headers=request.headers)
+ user_id = authenticated_user["user_principal_id"]
+ if not user_id:
+ track_event_if_configured(
+ "UserIdNotFound", {"status_code": 400, "detail": "no user"}
+ )
+ raise HTTPException(status_code=400, detail="no user")
+
+ # Initialize memory context
+ kernel, memory_store = await initialize_runtime_and_context("", user_id)
+ agent_messages = await memory_store.get_data_by_type_and_plan_id("agent_message")
+ return agent_messages
+
+
@app.delete("/api/messages")
async def delete_all_messages(request: Request) -> Dict[str, str]:
"""
diff --git a/src/backend/context/cosmos_memory_kernel.py b/src/backend/context/cosmos_memory_kernel.py
index 6a1b5a1c8..64f96d4f1 100644
--- a/src/backend/context/cosmos_memory_kernel.py
+++ b/src/backend/context/cosmos_memory_kernel.py
@@ -230,6 +230,17 @@ async def get_plan_by_session(self, session_id: str) -> Optional[Plan]:
plans = await self.query_items(query, parameters, Plan)
return plans[0] if plans else None
+ async def get_plan_by_plan_id(self, plan_id: str) -> Optional[Plan]:
+ """Retrieve a plan associated with a session."""
+ query = "SELECT * FROM c WHERE c.id=@id AND c.user_id=@user_id AND c.data_type=@data_type"
+ parameters = [
+ {"name": "@id", "value": plan_id},
+ {"name": "@data_type", "value": "plan"},
+ {"name": "@user_id", "value": self.user_id},
+ ]
+ plans = await self.query_items(query, parameters, Plan)
+ return plans[0] if plans else None
+
async def get_thread_by_session(self, session_id: str) -> Optional[Any]:
"""Retrieve a plan associated with a session."""
query = "SELECT * FROM c WHERE c.session_id=@session_id AND c.user_id=@user_id AND c.data_type=@data_type"
@@ -257,7 +268,7 @@ async def get_plan(self, plan_id: str) -> Optional[Plan]:
async def get_all_plans(self) -> List[Plan]:
"""Retrieve all plans."""
- query = "SELECT * FROM c WHERE c.user_id=@user_id AND c.data_type=@data_type ORDER BY c._ts DESC OFFSET 0 LIMIT 5"
+ query = "SELECT * FROM c WHERE c.user_id=@user_id AND c.data_type=@data_type ORDER BY c._ts DESC OFFSET 0 LIMIT 10"
parameters = [
{"name": "@data_type", "value": "plan"},
{"name": "@user_id", "value": self.user_id},
@@ -431,6 +442,27 @@ async def get_data_by_type(self, data_type: str) -> List[BaseDataModel]:
logging.exception(f"Failed to query data by type from Cosmos DB: {e}")
return []
+ async def get_data_by_type_and_session_id(
+ self, data_type: str, session_id: str
+ ) -> List[BaseDataModel]:
+ """Query the Cosmos DB for documents with the matching data_type, session_id and user_id."""
+ await self.ensure_initialized()
+ if self._container is None:
+ return []
+
+ model_class = self.MODEL_CLASS_MAPPING.get(data_type, BaseDataModel)
+ try:
+ query = "SELECT * FROM c WHERE c.session_id=@session_id AND c.user_id=@user_id AND c.data_type=@data_type ORDER BY c._ts ASC"
+ parameters = [
+ {"name": "@session_id", "value": session_id},
+ {"name": "@data_type", "value": data_type},
+ {"name": "@user_id", "value": self.user_id},
+ ]
+ return await self.query_items(query, parameters, model_class)
+ except Exception as e:
+ logging.exception(f"Failed to query data by type from Cosmos DB: {e}")
+ return []
+
async def delete_item(self, item_id: str, partition_key: str) -> None:
"""Delete an item from Cosmos DB."""
await self.ensure_initialized()
diff --git a/src/backend/kernel_agents/planner_agent.py b/src/backend/kernel_agents/planner_agent.py
index c87516542..97619d6ad 100644
--- a/src/backend/kernel_agents/planner_agent.py
+++ b/src/backend/kernel_agents/planner_agent.py
@@ -14,10 +14,17 @@
from kernel_tools.procurement_tools import ProcurementTools
from kernel_tools.product_tools import ProductTools
from kernel_tools.tech_support_tools import TechSupportTools
-from models.messages_kernel import (AgentMessage, AgentType,
- HumanFeedbackStatus, InputTask, Plan,
- PlannerResponsePlan, PlanStatus, Step,
- StepStatus)
+from models.messages_kernel import (
+ AgentMessage,
+ AgentType,
+ HumanFeedbackStatus,
+ InputTask,
+ Plan,
+ PlannerResponsePlan,
+ PlanStatus,
+ Step,
+ StepStatus,
+)
from semantic_kernel.functions import KernelFunction
from semantic_kernel.functions.kernel_arguments import KernelArguments
@@ -188,7 +195,7 @@ async def handle_input_task(self, input_task: InputTask) -> str:
session_id=input_task.session_id,
user_id=self._user_id,
plan_id=plan.id,
- content=f"Generated a plan with {len(steps)} steps. Click the blue check box beside each step to complete it, click the x to remove this step.",
+ content=f"Generated a plan with {len(steps)} steps. Click the checkmark beside each step to complete it, click the x to reject this step.",
source=AgentType.PLANNER.value,
step_id="",
)
@@ -200,7 +207,7 @@ async def handle_input_task(self, input_task: InputTask) -> str:
"session_id": input_task.session_id,
"user_id": self._user_id,
"plan_id": plan.id,
- "content": f"Generated a plan with {len(steps)} steps. Click the blue check box beside each step to complete it, click the x to remove this step.",
+ "content": f"Generated a plan with {len(steps)} steps. Click the checkmark beside each step to complete it, click the x to reject this step.",
"source": AgentType.PLANNER.value,
},
)
diff --git a/src/frontend/.env.sample b/src/frontend/.env.sample
new file mode 100644
index 000000000..3f56e3400
--- /dev/null
+++ b/src/frontend/.env.sample
@@ -0,0 +1,13 @@
+# This is a sample .env file for the frontend application.
+
+API_URL=http://localhost:8000
+ENABLE_AUTH=false
+# VITE_APP_MSAL_AUTH_CLIENTID=""
+# VITE_APP_MSAL_AUTH_AUTHORITY=""
+# VITE_APP_MSAL_REDIRECT_URL="/"
+# VITE_APP_MSAL_POST_REDIRECT_URL="/"
+# REACT_APP_MSAL_AUTH_CLIENTID=""
+# REACT_APP_MSAL_AUTH_AUTHORITY=""
+# REACT_APP_MSAL_REDIRECT_URL="/"
+# REACT_APP_MSAL_POST_REDIRECT_URL="/"
+
diff --git a/src/frontend/.eslintrc.js b/src/frontend/.eslintrc.js
new file mode 100644
index 000000000..9334061a4
--- /dev/null
+++ b/src/frontend/.eslintrc.js
@@ -0,0 +1,25 @@
+module.exports = {
+ root: true,
+ extends: [
+ 'react-app',
+ 'react-app/jest',
+ 'plugin:react/recommended',
+ ],
+ plugins: ['react', '@typescript-eslint'],
+ parserOptions: {
+ ecmaVersion: 2020,
+ sourceType: 'module',
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ settings: {
+ react: {
+ version: 'detect'
+ }
+ },
+ rules: {
+ // Add custom rules here
+ 'react/react-in-jsx-scope': 'off', // Not needed in React 17+
+ }
+};
diff --git a/src/frontend/.gitignore b/src/frontend/.gitignore
new file mode 100644
index 000000000..86e201c1c
--- /dev/null
+++ b/src/frontend/.gitignore
@@ -0,0 +1,28 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# production
+/build
+/dist
+
+# misc
+.DS_Store
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+# Vite
+.vite/
+*.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
diff --git a/src/frontend/Dockerfile b/src/frontend/Dockerfile
index c457c109e..c7cec24f0 100644
--- a/src/frontend/Dockerfile
+++ b/src/frontend/Dockerfile
@@ -1,29 +1,87 @@
-FROM mcr.microsoft.com/devcontainers/python:3.11-bullseye AS base
-WORKDIR /app
+# Multi-stage Dockerfile for React frontend with Python backend support using UV
+
+# Stage 1: Node build environment for React
+FROM node:18-alpine AS frontend-builder
+
+WORKDIR /app/frontend
+
+# Copy package files first for better caching
+COPY package*.json ./
+
+# Install dependencies
+RUN npm ci --silent
-FROM base AS builder
+# Copy source files
+COPY . ./
+
+# Build the React app
+RUN npm run build
+
+# Stage 2: Python build environment with UV
+FROM mcr.microsoft.com/devcontainers/python:3.11-bullseye AS python-builder
+
+# Copy UV from official image
COPY --from=ghcr.io/astral-sh/uv:0.6.3 /uv /uvx /bin/
+
+# Setup UV environment variables
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
WORKDIR /app
-COPY uv.lock pyproject.toml /app/
-# Install the project's dependencies using the lockfile and settings
+# Copy Python project definition files
+COPY pyproject.toml requirements.txt* uv.lock* ./
+
+# Install Python dependencies using UV
RUN --mount=type=cache,target=/root/.cache/uv \
- --mount=type=bind,source=uv.lock,target=uv.lock \
- --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
- uv sync --frozen --no-install-project --no-dev
+ if [ -f "requirements.txt" ]; then \
+ uv pip install --system -r requirements.txt && uv pip install --system "uvicorn[standard]"; \
+ else \
+ uv pip install --system pyproject.toml && uv pip install --system "uvicorn[standard]"; \
+ fi
-# Backend app setup
-COPY . /app
-RUN --mount=type=cache,target=/root/.cache/uv uv sync --frozen --no-dev
+# Stage 3: Final production image
+FROM python:3.11-slim-bullseye
-FROM base
+# Set production environment
+ENV NODE_ENV=production \
+ PYTHONDONTWRITEBYTECODE=1 \
+ PYTHONUNBUFFERED=1
-COPY --from=builder /app /app
-COPY --from=builder /bin/uv /bin/uv
+# Install curl for healthcheck
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends curl && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
-ENV PATH="/app/.venv/bin:$PATH"
+WORKDIR /app
+
+# Create a non-root user for security
+RUN adduser --disabled-password --gecos "" appuser && \
+ mkdir -p /app/static && \
+ chown -R appuser:appuser /app
+
+# Copy Python dependencies from builder
+COPY --from=python-builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
+COPY --from=python-builder /usr/local/bin /usr/local/bin
+
+# Copy React build artifacts
+COPY --from=frontend-builder --chown=appuser:appuser /app/frontend/build /app/build
+
+# Copy Python application code
+COPY --chown=appuser:appuser ./*.py /app/
+# Create log directory with correct permissions
+RUN mkdir -p /app/logs && chown -R appuser:appuser /app/logs
+
+# Use non-root user for security
+USER appuser
+
+# Expose port
EXPOSE 3000
-CMD ["uv","run","uvicorn", "frontend_server:app", "--host", "0.0.0.0", "--port", "3000"]
\ No newline at end of file
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
+ CMD curl -f http://localhost:3000/health || exit 1
+
+# Run the application with uvicorn
+CMD ["/usr/local/bin/uvicorn", "frontend_server:app", "--host", "0.0.0.0", "--port", "3000"]
\ No newline at end of file
diff --git a/src/frontend/README.md b/src/frontend/README.md
index 158f14533..b87cb0044 100644
--- a/src/frontend/README.md
+++ b/src/frontend/README.md
@@ -1,4 +1,46 @@
-## Execute frontend UI App
-```shell
-uv run uvicorn frontend_server:app --port 3000
-```
\ No newline at end of file
+# Getting Started with Create React App
+
+This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
+
+## Available Scripts
+
+In the project directory, you can run:
+
+### `npm start`
+
+Runs the app in the development mode.\
+Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
+
+The page will reload if you make edits.\
+You will also see any lint errors in the console.
+
+### `npm test`
+
+Launches the test runner in the interactive watch mode.\
+See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
+
+### `npm run build`
+
+Builds the app for production to the `build` folder.\
+It correctly bundles React in production mode and optimizes the build for the best performance.
+
+The build is minified and the filenames include the hashes.\
+Your app is ready to be deployed!
+
+See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
+
+### `npm run eject`
+
+**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
+
+If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
+
+Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
+
+You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
+
+## Learn More
+
+You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
+
+To learn React, check out the [React documentation](https://reactjs.org/).
diff --git a/src/frontend/frontend_server.py b/src/frontend/frontend_server.py
index db7356613..56651e0a1 100644
--- a/src/frontend/frontend_server.py
+++ b/src/frontend/frontend_server.py
@@ -1,74 +1,61 @@
+import html
import os
import uvicorn
+from dotenv import load_dotenv
from fastapi import FastAPI
-from fastapi.responses import (
- FileResponse,
- HTMLResponse,
- PlainTextResponse,
- RedirectResponse,
-)
+from fastapi.middleware.cors import CORSMiddleware
+from fastapi.responses import FileResponse, HTMLResponse
from fastapi.staticfiles import StaticFiles
-# Resolve wwwroot path relative to this script
-WWWROOT_PATH = os.path.join(os.path.dirname(__file__), "wwwroot")
-
-# Debugging information
-print(f"Current Working Directory: {os.getcwd()}")
-print(f"Absolute path to wwwroot: {WWWROOT_PATH}")
-if not os.path.exists(WWWROOT_PATH):
- raise FileNotFoundError(f"wwwroot directory not found at path: {WWWROOT_PATH}")
-print(f"Files in wwwroot: {os.listdir(WWWROOT_PATH)}")
+# Load environment variables from .env file
+load_dotenv()
app = FastAPI()
-import html
+app.add_middleware(
+ CORSMiddleware,
+ allow_origins=["*"],
+ allow_methods=["*"],
+ allow_headers=["*"],
+)
+# Build paths
+BUILD_DIR = os.path.join(os.path.dirname(__file__), "build")
+INDEX_HTML = os.path.join(BUILD_DIR, "index.html")
-@app.get("/config.js", response_class=PlainTextResponse)
-def get_config():
- backend_url = html.escape(os.getenv("BACKEND_API_URL", "http://localhost:8000"))
- auth_enabled = html.escape(os.getenv("AUTH_ENABLED", "True"))
- backend_url = backend_url + "/api"
- return f"""
- const BACKEND_API_URL = "{backend_url}";
- const AUTH_ENABLED = "{auth_enabled}";
- """
+# Serve static files from build directory
+app.mount(
+ "/assets", StaticFiles(directory=os.path.join(BUILD_DIR, "assets")), name="assets"
+)
-# Redirect root to app.html
@app.get("/")
-async def index_redirect():
- return RedirectResponse(url="/app.html?v=home")
-
+async def serve_index():
+ return FileResponse(INDEX_HTML)
-# Mount static files
-app.mount("/", StaticFiles(directory=WWWROOT_PATH, html=True), name="static")
+@app.get("/config")
+async def get_config():
+ backend_url = html.escape(os.getenv("BACKEND_API_URL", "http://localhost:8000"))
+ auth_enabled = html.escape(os.getenv("AUTH_ENABLED", "false"))
+ backend_url = backend_url + "/api"
-# Debugging route
-@app.get("/debug")
-async def debug_route():
- return {
- "message": "Frontend debug route working",
- "wwwroot_path": WWWROOT_PATH,
- "files": os.listdir(WWWROOT_PATH),
+ config = {
+ "API_URL": backend_url,
+ "ENABLE_AUTH": auth_enabled,
}
+ return config
-# Catch-all route for SPA
@app.get("/{full_path:path}")
-async def catch_all(full_path: str):
- print(f"Requested path: {full_path}")
- app_html_path = os.path.join(WWWROOT_PATH, "app.html")
-
- if os.path.exists(app_html_path):
- return FileResponse(app_html_path)
- else:
- return HTMLResponse(
- content=f"app.html not found. Current path: {app_html_path}",
- status_code=404,
- )
+async def serve_app(full_path: str):
+ # First check if file exists in build directory
+ file_path = os.path.join(BUILD_DIR, full_path)
+ if os.path.exists(file_path):
+ return FileResponse(file_path)
+ # Otherwise serve index.html for client-side routing
+ return FileResponse(INDEX_HTML)
if __name__ == "__main__":
diff --git a/src/frontend/index.html b/src/frontend/index.html
new file mode 100644
index 000000000..16d5b6dc7
--- /dev/null
+++ b/src/frontend/index.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+ Multi-Agent - Custom Automation Engine
+
+
+ You need to enable JavaScript to run this app.
+
+
+
+
diff --git a/src/frontend/migration-commands.txt b/src/frontend/migration-commands.txt
new file mode 100644
index 000000000..4a9822fed
--- /dev/null
+++ b/src/frontend/migration-commands.txt
@@ -0,0 +1,14 @@
+# Migration Script for React Scripts to Vite
+# Run these commands in PowerShell from your frontend directory
+
+# 1. Remove react-scripts
+npm uninstall react-scripts
+
+# 2. Install Vite and related plugins
+npm install --save-dev vite @vitejs/plugin-react @types/node
+
+# 3. Install additional Vite-specific dev dependencies
+npm install --save-dev vite-plugin-eslint
+
+# 4. Update testing dependencies (optional)
+npm install --save-dev @vitest/ui vitest jsdom
diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json
index aba25f735..db1c59f45 100644
--- a/src/frontend/package-lock.json
+++ b/src/frontend/package-lock.json
@@ -1,6 +1,10536 @@
{
- "name": "frontend",
+ "name": "Multi Agent frontend",
+ "version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
- "packages": {}
+ "packages": {
+ "": {
+ "name": "Multi Agent frontend",
+ "version": "0.1.0",
+ "dependencies": {
+ "@fluentui/merge-styles": "^8.6.14",
+ "@fluentui/react-components": "^9.64.0",
+ "@fluentui/react-icons": "^2.0.300",
+ "@testing-library/dom": "^10.4.0",
+ "@testing-library/jest-dom": "^6.6.3",
+ "@testing-library/react": "^16.3.0",
+ "@testing-library/user-event": "^13.5.0",
+ "@types/jest": "^27.5.2",
+ "@types/node": "^16.18.126",
+ "@types/react": "^18.3.23",
+ "@types/react-dom": "^18.3.7",
+ "axios": "^1.9.0",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "react-markdown": "^10.1.0",
+ "react-router-dom": "^7.6.0",
+ "rehype-prism": "^2.3.3",
+ "remark-gfm": "^4.0.1",
+ "web-vitals": "^2.1.4"
+ },
+ "devDependencies": {
+ "@types/node": "^20.0.0",
+ "@typescript-eslint/eslint-plugin": "^5.62.0",
+ "@typescript-eslint/parser": "^5.62.0",
+ "@vitejs/plugin-react": "^4.5.1",
+ "@vitest/ui": "^1.6.1",
+ "eslint": "^8.57.1",
+ "eslint-plugin-react": "^7.37.5",
+ "jsdom": "^24.1.3",
+ "typescript": "^5.8.3",
+ "vite": "^5.4.19",
+ "vitest": "^1.6.1"
+ }
+ },
+ "node_modules/@adobe/css-tools": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.3.tgz",
+ "integrity": "sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==",
+ "license": "MIT"
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@asamuzakjp/css-color": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz",
+ "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/css-calc": "^2.1.3",
+ "@csstools/css-color-parser": "^3.0.9",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "lru-cache": "^10.4.3"
+ }
+ },
+ "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@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/compat-data": {
+ "version": "7.27.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.5.tgz",
+ "integrity": "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.27.4",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.4.tgz",
+ "integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.27.3",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-module-transforms": "^7.27.3",
+ "@babel/helpers": "^7.27.4",
+ "@babel/parser": "^7.27.4",
+ "@babel/template": "^7.27.2",
+ "@babel/traverse": "^7.27.4",
+ "@babel/types": "^7.27.3",
+ "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/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.27.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz",
+ "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.27.5",
+ "@babel/types": "^7.27.3",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-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-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.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.27.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz",
+ "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "@babel/traverse": "^7.27.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.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
+ "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.27.6",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz",
+ "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.27.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.27.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz",
+ "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.27.3"
+ },
+ "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/runtime": {
+ "version": "7.27.6",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz",
+ "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==",
+ "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==",
+ "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.27.4",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz",
+ "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.27.3",
+ "@babel/parser": "^7.27.4",
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.27.3",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.27.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz",
+ "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@csstools/color-helpers": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz",
+ "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@csstools/css-calc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz",
+ "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-color-parser": {
+ "version": "3.0.10",
+ "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.10.tgz",
+ "integrity": "sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/color-helpers": "^5.0.2",
+ "@csstools/css-calc": "^2.1.4"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.5",
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-parser-algorithms": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
+ "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@csstools/css-tokenizer": "^3.0.4"
+ }
+ },
+ "node_modules/@csstools/css-tokenizer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz",
+ "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@ctrl/tinycolor": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
+ "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@emotion/hash": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
+ "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
+ "license": "MIT"
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
+ "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==",
+ "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/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@floating-ui/core": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.1.tgz",
+ "integrity": "sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.9"
+ }
+ },
+ "node_modules/@floating-ui/devtools": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/devtools/-/devtools-0.2.1.tgz",
+ "integrity": "sha512-8PHJLbD6VhBh+LJ1uty/Bz30qs02NXCE5u8WpOhSewlYXUWl03GNXknr9AS2yaAWJEQaY27x7eByJs44gODBcw==",
+ "peerDependencies": {
+ "@floating-ui/dom": ">=1.5.4"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.1.tgz",
+ "integrity": "sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/core": "^1.7.1",
+ "@floating-ui/utils": "^0.2.9"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
+ "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
+ "license": "MIT"
+ },
+ "node_modules/@fluentui/keyboard-keys": {
+ "version": "9.0.8",
+ "resolved": "https://registry.npmjs.org/@fluentui/keyboard-keys/-/keyboard-keys-9.0.8.tgz",
+ "integrity": "sha512-iUSJUUHAyTosnXK8O2Ilbfxma+ZyZPMua5vB028Ys96z80v+LFwntoehlFsdH3rMuPsA8GaC1RE7LMezwPBPdw==",
+ "license": "MIT",
+ "dependencies": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "node_modules/@fluentui/merge-styles": {
+ "version": "8.6.14",
+ "resolved": "https://registry.npmjs.org/@fluentui/merge-styles/-/merge-styles-8.6.14.tgz",
+ "integrity": "sha512-vghuHFAfQgS9WLIIs4kgDOCh/DHd5vGIddP4/bzposhlAVLZR6wUBqldm9AuCdY88r5LyCRMavVJLV+Up3xdvA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/set-version": "^8.2.24",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@fluentui/priority-overflow": {
+ "version": "9.1.15",
+ "resolved": "https://registry.npmjs.org/@fluentui/priority-overflow/-/priority-overflow-9.1.15.tgz",
+ "integrity": "sha512-/3jPBBq64hRdA416grVj+ZeMBUIaKZk2S5HiRg7CKCAV1JuyF84Do0rQI6ns8Vb9XOGuc4kurMcL/UEftoEVrg==",
+ "license": "MIT",
+ "dependencies": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "node_modules/@fluentui/react-accordion": {
+ "version": "9.7.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-accordion/-/react-accordion-9.7.0.tgz",
+ "integrity": "sha512-DzWK3RBWlREn9EUYEXdYZhC6cjJLAm2u21qqofovrIlU/LDUUCC1cPxJHycdi9KwP7mDZdhXSqQG6LLe9xIeMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-motion": "^9.8.0",
+ "@fluentui/react-motion-components-preview": "^0.6.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-alert": {
+ "version": "9.0.0-beta.124",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-alert/-/react-alert-9.0.0-beta.124.tgz",
+ "integrity": "sha512-yFBo3B5H9hnoaXxlkuz8wRz04DEyQ+ElYA/p5p+Vojf19Zuta8DmFZZ6JtWdtxcdnnQ4LvAfC5OYYlzdReozPA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-avatar": "^9.6.29",
+ "@fluentui/react-button": "^9.3.83",
+ "@fluentui/react-icons": "^2.0.239",
+ "@fluentui/react-jsx-runtime": "^9.0.39",
+ "@fluentui/react-tabster": "^9.21.5",
+ "@fluentui/react-theme": "^9.1.19",
+ "@fluentui/react-utilities": "^9.18.10",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-aria": {
+ "version": "9.15.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-aria/-/react-aria-9.15.0.tgz",
+ "integrity": "sha512-8cN9/5+XHL3mzp1gNIj0ZXuPTioYALO/1FCWugkOF5JP8PVkV3HDX3ezRq2Bk44PS2YK98tjffTiBzFeanHxug==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-avatar": {
+ "version": "9.8.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-avatar/-/react-avatar-9.8.1.tgz",
+ "integrity": "sha512-hLOFxN8oqRkO8lBqGhXLONtI4LRWf/16TJDiizWbfep33NMS/rpHl+PijwO873CXRxSDnR1z3sENHpVInILtug==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-badge": "^9.3.0",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-popover": "^9.11.1",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-tooltip": "^9.7.1",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-badge": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-badge/-/react-badge-9.3.0.tgz",
+ "integrity": "sha512-BFONtrI0SZmM+j+wR8tb5S43qodY5AydKMCJ35e02rR1/nyizg4tA3g/3iujGHAAsXPX04D20W4QMcy9LyRAXA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-breadcrumb": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-breadcrumb/-/react-breadcrumb-9.2.1.tgz",
+ "integrity": "sha512-xwrwLz8AbvfcbESviNOrQD4GZ8YeabDK/WLzVXPf+sWsnPnnYx+j/+EgnsbTjJ8FtYKkak1pMq6KwLC1mzWQnQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-button": "^9.5.0",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-link": "^9.5.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-button": {
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-button/-/react-button-9.5.0.tgz",
+ "integrity": "sha512-J4Tdxcey6cjyxKuRAQkUynAwBwLnuTmGry9APGddbnGPGXBDNqjHIqqMDua5lOSIINSIiQHTNdg7fZWoETSZ4Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-card": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-card/-/react-card-9.3.0.tgz",
+ "integrity": "sha512-ZvCuFta3X2HaLTU0fdpbHCz/j+jGYRhwC0CVcxK1u4cXb74r4V2DfXaNYI9vXw9ELGe3YoiOE7xmDdDL0sRUYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-text": "^9.5.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-checkbox": {
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-checkbox/-/react-checkbox-9.4.1.tgz",
+ "integrity": "sha512-lrf4I12fGMrodQODjrwTgDl5bOssXuEzg+ioMh/ldWQGD6xPjoqrznLusfjj+Ua1qR6k2bHnHuSDoH7E1vzlng==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-label": "^9.2.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-color-picker": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-color-picker/-/react-color-picker-9.1.0.tgz",
+ "integrity": "sha512-Tm85dMk0XPUZDCybjd0sa+1txR38ejLL+MG/Z03cpC41GxihDh5+4dPAqSfPzfezbENNoFsqfjKiKhw0Un96Rg==",
+ "license": "MIT",
+ "dependencies": {
+ "@ctrl/tinycolor": "^3.3.4",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-combobox": {
+ "version": "9.15.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-combobox/-/react-combobox-9.15.1.tgz",
+ "integrity": "sha512-/WmfxkrYwe3/XU4gan56tjEBVdBmG43tW247vqXHQiC/e3q/dsqwQNhCO/VVr2pTS/Y3xhorMML63Azh9WXJ4A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-portal": "^9.6.0",
+ "@fluentui/react-positioning": "^9.18.1",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-components": {
+ "version": "9.66.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-components/-/react-components-9.66.1.tgz",
+ "integrity": "sha512-Rzh+QL2reQEMaFLu+h314ic7w8W9TbDcyDpohb+CRODgT3YCw+Gt+SVbR3Yi+8Cf3kwtokDQIC3ki6iBQ9g/Tg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-accordion": "^9.7.0",
+ "@fluentui/react-alert": "9.0.0-beta.124",
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-avatar": "^9.8.1",
+ "@fluentui/react-badge": "^9.3.0",
+ "@fluentui/react-breadcrumb": "^9.2.1",
+ "@fluentui/react-button": "^9.5.0",
+ "@fluentui/react-card": "^9.3.0",
+ "@fluentui/react-carousel": "^9.7.1",
+ "@fluentui/react-checkbox": "^9.4.1",
+ "@fluentui/react-color-picker": "^9.1.0",
+ "@fluentui/react-combobox": "^9.15.1",
+ "@fluentui/react-dialog": "^9.13.1",
+ "@fluentui/react-divider": "^9.3.0",
+ "@fluentui/react-drawer": "^9.8.1",
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-image": "^9.2.0",
+ "@fluentui/react-infobutton": "9.0.0-beta.102",
+ "@fluentui/react-infolabel": "^9.3.1",
+ "@fluentui/react-input": "^9.6.1",
+ "@fluentui/react-label": "^9.2.0",
+ "@fluentui/react-link": "^9.5.0",
+ "@fluentui/react-list": "^9.2.1",
+ "@fluentui/react-menu": "^9.17.1",
+ "@fluentui/react-message-bar": "^9.5.0",
+ "@fluentui/react-motion": "^9.8.0",
+ "@fluentui/react-nav": "^9.1.1",
+ "@fluentui/react-overflow": "^9.4.1",
+ "@fluentui/react-persona": "^9.4.1",
+ "@fluentui/react-popover": "^9.11.1",
+ "@fluentui/react-portal": "^9.6.0",
+ "@fluentui/react-positioning": "^9.18.1",
+ "@fluentui/react-progress": "^9.3.1",
+ "@fluentui/react-provider": "^9.21.0",
+ "@fluentui/react-radio": "^9.4.1",
+ "@fluentui/react-rating": "^9.2.0",
+ "@fluentui/react-search": "^9.2.1",
+ "@fluentui/react-select": "^9.3.1",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-skeleton": "^9.3.1",
+ "@fluentui/react-slider": "^9.4.1",
+ "@fluentui/react-spinbutton": "^9.4.1",
+ "@fluentui/react-spinner": "^9.6.0",
+ "@fluentui/react-swatch-picker": "^9.3.1",
+ "@fluentui/react-switch": "^9.3.1",
+ "@fluentui/react-table": "^9.17.1",
+ "@fluentui/react-tabs": "^9.8.0",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-tag-picker": "^9.6.1",
+ "@fluentui/react-tags": "^9.6.1",
+ "@fluentui/react-teaching-popover": "^9.5.1",
+ "@fluentui/react-text": "^9.5.0",
+ "@fluentui/react-textarea": "^9.5.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-toast": "^9.5.0",
+ "@fluentui/react-toolbar": "^9.5.1",
+ "@fluentui/react-tooltip": "^9.7.1",
+ "@fluentui/react-tree": "^9.11.1",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@fluentui/react-virtualizer": "9.0.0-alpha.98",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-components/node_modules/@fluentui/react-carousel": {
+ "version": "9.7.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-carousel/-/react-carousel-9.7.1.tgz",
+ "integrity": "sha512-nmr1QCzH5vZHZ6KQ50YK+1obfKr/hejgqSMu1Ze/CwZ2/louEYzN2bhibtJfW6b3PpBeowL+S26jbdNWtI78yg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-button": "^9.5.0",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-tooltip": "^9.7.1",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1",
+ "embla-carousel": "^8.5.1",
+ "embla-carousel-autoplay": "^8.5.1",
+ "embla-carousel-fade": "^8.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-components/node_modules/@fluentui/react-drawer": {
+ "version": "9.8.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-drawer/-/react-drawer-9.8.1.tgz",
+ "integrity": "sha512-VjzG0qAXN7eXiBbFzM7YHpNes05YIdY3WHJD6V2FheHvmthzhw8GFqDnRHsZ581Wb9uB9xqi+WJ69vNJ9tS48Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-dialog": "^9.13.1",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-motion": "^9.8.0",
+ "@fluentui/react-portal": "^9.6.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-components/node_modules/@fluentui/react-tag-picker": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tag-picker/-/react-tag-picker-9.6.1.tgz",
+ "integrity": "sha512-eQJHWpc8IfA/D/tsJZ2LOrPsm3CykRrRwIOl4qmRpxGF7jpjc9TTgv/x65xhNAV1zlHkn/kdeF3c6fg51ZPZYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-combobox": "^9.15.1",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-portal": "^9.6.0",
+ "@fluentui/react-positioning": "^9.18.1",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-tags": "^9.6.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-components/node_modules/@fluentui/react-tags": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tags/-/react-tags-9.6.1.tgz",
+ "integrity": "sha512-h511CaowCakh1jXWFk7J2iy/7iXie0EafJqSYkES0fD/3whJOdos355veYkUqdD8G7BaMjL5n9Bkj3OjlxrMJw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-avatar": "^9.8.1",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-components/node_modules/@fluentui/react-teaching-popover": {
+ "version": "9.5.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-teaching-popover/-/react-teaching-popover-9.5.1.tgz",
+ "integrity": "sha512-4YUcfbu/y2uY/gJGwo8EwcqegGBaFc6Mt4pKHLgUJd3m+26YDuHFEwpWEN/gHZ1nKsAXg/zlPpaPuDOwzFZFtQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-button": "^9.5.0",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-popover": "^9.11.1",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1",
+ "use-sync-external-store": "^1.2.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-components/node_modules/@fluentui/react-virtualizer": {
+ "version": "9.0.0-alpha.98",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-virtualizer/-/react-virtualizer-9.0.0-alpha.98.tgz",
+ "integrity": "sha512-BXLXsQPOS+IXrOoH0ZFBbEH6HI7zwGjWoiCPCkqexQYa54flDI8jo2xU7FrvYKVLVNK5oa+UA9jxw5GqDah8QQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-context-selector": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.2.0.tgz",
+ "integrity": "sha512-s35dNhIcHGm6SmmQr04vATaogQZ2Wvl1zi4/xgZ4/6V8XAGPBqRRTkutjkWgW4u4WZDriWdWNL62ju3hGDpE9g==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.21.0",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-dialog": {
+ "version": "9.13.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-dialog/-/react-dialog-9.13.1.tgz",
+ "integrity": "sha512-YCGTh4IPaHQH1LTLoD5D5Ql7DK+1ytMHYL4kQ9O8CmSu3WntjUSmOKGxWDHqHLEX0gRz86fPy49/u5NDDhLfFA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-motion": "^9.8.0",
+ "@fluentui/react-motion-components-preview": "^0.6.0",
+ "@fluentui/react-portal": "^9.6.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-divider": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-divider/-/react-divider-9.3.0.tgz",
+ "integrity": "sha512-8MvWlNcYQBIpIH8d90PRLYvqTA53t0Folv1xf2isC+YWeTm5J1siZtPRiZ9+K0uqI9Y+RD4fnWN8HfMeyOAjlw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-field": {
+ "version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-field/-/react-field-9.3.1.tgz",
+ "integrity": "sha512-9bzicAbR5+AtboowO6akbJsoMWDGUtbGenQT81mXt7HGg6RP86gpodgcr/4f1OG1w5VtrfoA/aoNExP/XzUeGg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-label": "^9.2.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-icons": {
+ "version": "2.0.302",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-icons/-/react-icons-2.0.302.tgz",
+ "integrity": "sha512-NK8w51dvucc6bu9oNoFZTWhXVelZ93JKnQbUH4Po344NJiBnzblv5ey4Vxz2SJj7T2t3oYBE+kb/ixTxwbxlaQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@griffel/react": "^1.0.0",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-image": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-image/-/react-image-9.2.0.tgz",
+ "integrity": "sha512-vP26rQDNx5LevbEKbf6dLjTx4uOZWIopjx6HQYSLk8axGWmjXe21t6BXRa9iTiPfibwJmWwzXvqGHxYR/as/wA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-infobutton": {
+ "version": "9.0.0-beta.102",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-infobutton/-/react-infobutton-9.0.0-beta.102.tgz",
+ "integrity": "sha512-3kA4F0Vga8Ds6JGlBajLCCDOo/LmPuS786Wg7ui4ZTDYVIMzy1yp2XuVcZniifBFvEp0HQCUoDPWUV0VI3FfzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.237",
+ "@fluentui/react-jsx-runtime": "^9.0.36",
+ "@fluentui/react-label": "^9.1.68",
+ "@fluentui/react-popover": "^9.9.6",
+ "@fluentui/react-tabster": "^9.21.0",
+ "@fluentui/react-theme": "^9.1.19",
+ "@fluentui/react-utilities": "^9.18.7",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-infolabel": {
+ "version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-infolabel/-/react-infolabel-9.3.1.tgz",
+ "integrity": "sha512-fL2J3PJy6ylPQrFFwAJgFoACxRk5d/PtzjL7JlmM1OCaUmUD2FuUovDYpubw9r36OemVOHTB/oXhpitlS3BoPQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-label": "^9.2.0",
+ "@fluentui/react-popover": "^9.11.1",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-input": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-input/-/react-input-9.6.1.tgz",
+ "integrity": "sha512-IMwJxKjZYznlKFrZ6MoKpFXJxfGoJBJux4hDZzqDWyDafDSvjmTpiiutJbQmMRQpxQ4pPuaHBwcSScfExAf69g==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-jsx-runtime": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-jsx-runtime/-/react-jsx-runtime-9.1.0.tgz",
+ "integrity": "sha512-HB4+1ofzmweSWrFPZeoeepzNNHu54jplCfPLlppBoHx1MZ11RR9w2uIsLjfSDrEPIZnXbQxVBItvDh9ZrU9new==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.21.0",
+ "@swc/helpers": "^0.5.1",
+ "react-is": "^17.0.2"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-label": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-label/-/react-label-9.2.0.tgz",
+ "integrity": "sha512-WDaBR9AmdPvJ0vXN9WicOlHFhI6BKgQXULl0YjMXuL51tl37txyvY2crv+YNeVsfykI18h6LOPxltPeEdAsxag==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-link": {
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-link/-/react-link-9.5.0.tgz",
+ "integrity": "sha512-bdEFARlbnTyzrKHKv7wvLMRua7/gUX1dOzBG+1tfmJFuFkE2gz7rxABBVdlaI1PHsgAbGnzQnSzl6C5DOPgqcA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-list": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-list/-/react-list-9.2.1.tgz",
+ "integrity": "sha512-UGRD+oBNtSRA+GH7n3qC07AatNvRLBQwSCoaza9ElYWsh4eWQzbp/zkurLWIM0PrAUd4JHuMswHARRBlJeY5gg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-checkbox": "^9.4.1",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-menu": {
+ "version": "9.17.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-menu/-/react-menu-9.17.1.tgz",
+ "integrity": "sha512-aygFQRa6Zt8sZ6aBnR+OiNaFOmykg+X5BTPBiu2m6IlJs1Z42S2AuSj8OuBUjrFQ3LnxT579AHDZuTXBngCsEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-portal": "^9.6.0",
+ "@fluentui/react-positioning": "^9.18.1",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-message-bar": {
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-message-bar/-/react-message-bar-9.5.0.tgz",
+ "integrity": "sha512-rsJUrXQWazdQ8gUX+l4XzToA8BMOJ+8t6WjXYr48Ztp7E9oROKaralavF78yihwY3t1ceacSbKa4bQLNqONlDw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-button": "^9.5.0",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-link": "^9.5.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1",
+ "react-transition-group": "^4.4.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-motion": {
+ "version": "9.8.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-motion/-/react-motion-9.8.0.tgz",
+ "integrity": "sha512-TTwJV4iw7LHesPNtQpPmEb77YplC89Vh2+ru2vWS+f5YJbmduN4V/WH/ViakHjRGj/m03jRaQruTpg3rKGUCZw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-motion-components-preview": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-motion-components-preview/-/react-motion-components-preview-0.6.0.tgz",
+ "integrity": "sha512-9PBaI25VGIuVKYE8Q4gew4/tsFmsOD4F1ZzHdEVkUS984pCZjC3LD5+6wrxpoJajDGk4cpWRRGl8x3DcO5CgHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-motion": "*",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-nav": {
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-nav/-/react-nav-9.1.1.tgz",
+ "integrity": "sha512-kn+5KVDCoY/xPrpEegJv9SEVofqLOPLDWk2C5YBR0zZItzZ7cHfNxABsZ3fD0RM15ro5BaaHm6mfuDxERHluHA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-button": "^9.5.0",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-divider": "^9.3.0",
+ "@fluentui/react-drawer": "^9.8.1",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-tooltip": "^9.7.1",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-nav/node_modules/@fluentui/react-drawer": {
+ "version": "9.8.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-drawer/-/react-drawer-9.8.1.tgz",
+ "integrity": "sha512-VjzG0qAXN7eXiBbFzM7YHpNes05YIdY3WHJD6V2FheHvmthzhw8GFqDnRHsZ581Wb9uB9xqi+WJ69vNJ9tS48Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-dialog": "^9.13.1",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-motion": "^9.8.0",
+ "@fluentui/react-portal": "^9.6.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-overflow": {
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-overflow/-/react-overflow-9.4.1.tgz",
+ "integrity": "sha512-qToEgEuyBWN2Te+9gg56fib/jCDwi3gBJhvZQSL8Ywgg3nNhmyAnOfGEdaMHrVL4DpFaNEOzxoC2C9vrzCx5bQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/priority-overflow": "^9.1.15",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-persona": {
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-persona/-/react-persona-9.4.1.tgz",
+ "integrity": "sha512-+1LLEfSEsZqcYLKt80BPT7hPXwbP49SiOb5PSHvOM58HtruWtD+rx7xLFVcR9BnlJK/oZkRjisfQlAM3zuZ3Yw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-avatar": "^9.8.1",
+ "@fluentui/react-badge": "^9.3.0",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-popover": {
+ "version": "9.11.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-popover/-/react-popover-9.11.1.tgz",
+ "integrity": "sha512-f+/K+8zHAlrUR16NSEtZ4rYArPtm+PpEuC9qd7+PjrlI/GytZHqVlNA8X4ddHWQy+fJoqTSA6cbB+SEYK8/yPw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-portal": "^9.6.0",
+ "@fluentui/react-positioning": "^9.18.1",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-portal": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-portal/-/react-portal-9.6.0.tgz",
+ "integrity": "sha512-FiA3eM/1Um/3HZvfaGisdL7pLV4idWzlmDUIFBUOlzXsy57mIY9IwV5nDHYiJdEMkW0UstRVJB4oRaHoHGSqUg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-positioning": {
+ "version": "9.18.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-positioning/-/react-positioning-9.18.1.tgz",
+ "integrity": "sha512-+ueJus7IaezMAEDrlo3G/ihd+8Voa1W4dWrswH7Jknulggp8Mfaz1wMdZq8GvMuBnifMLJ33M9svsrJJahscPw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/devtools": "0.2.1",
+ "@floating-ui/dom": "^1.6.12",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1",
+ "use-sync-external-store": "^1.2.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-progress": {
+ "version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-progress/-/react-progress-9.3.1.tgz",
+ "integrity": "sha512-2+jMPtuANnU7mUVEyUhhLh2LJmZNHrH4sin5rjSlsipr3ifhCoFUOoOloHw+cuVFzHeQNxIV9AuzOODii6cU3g==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-provider": {
+ "version": "9.21.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-provider/-/react-provider-9.21.0.tgz",
+ "integrity": "sha512-mADFjeZKN5e6AJJ45Nc99yDMmvzDPZea7G0PznByC4H/+JuZO3oExTve2SYSmj4KECyjv3wQVlMe7os9sCLZ6w==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/core": "^1.16.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-radio": {
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-radio/-/react-radio-9.4.1.tgz",
+ "integrity": "sha512-uQ+BeJeESBpC+MOC1coeiUlLVshpz2fjme3SKPuGDZv1x919Mh2e8OG5R1EcNGLJBMSVrU/LT8sqAV9WJ4k2cQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-label": "^9.2.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-rating": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-rating/-/react-rating-9.2.0.tgz",
+ "integrity": "sha512-GjEE6XmxDc8zTiQWZmiRJgXqKzreREQRUOimuBrG4exxKcoXj11Ah+oOrLJ/z/KmPyu0JGk5yHJ+VMuJeJh6gw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-search": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-search/-/react-search-9.2.1.tgz",
+ "integrity": "sha512-tFfo72YnBLK4nIIpaL8IE0Qu1hHGOjbbl2TxM6NN9qddp0s+5WeUHtpE1auyMeY4s1UQNbZbtjmsBpzicCAlaQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-input": "^9.6.1",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-select": {
+ "version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-select/-/react-select-9.3.1.tgz",
+ "integrity": "sha512-BvylsBcUzH8t/miTo/kesuv6GgTW6AiipFkTFsoeKqXS4kWYOZx3+ufVytdU9Pcowr0WrSBy6s/206JCQR3nVg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-shared-contexts": {
+ "version": "9.23.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-shared-contexts/-/react-shared-contexts-9.23.1.tgz",
+ "integrity": "sha512-mP+7talxLz7n0G36o7Asdvst+JPzUbqbnoMKUWRVB5YwzlOXumEgaQDgL1BkRUJYaDGOjIiSTUjHOEkBt7iSdg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-theme": "^9.1.24",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-skeleton": {
+ "version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-skeleton/-/react-skeleton-9.3.1.tgz",
+ "integrity": "sha512-gI05SgPkrACHH7dy2ZM5had1/Px99Wpvsxl+gzBCzloqeNlm0Eh1H/TH5UdFOm+0IA/Lit/8crwqSNRmHL/Viw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-slider": {
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-slider/-/react-slider-9.4.1.tgz",
+ "integrity": "sha512-pJeh2gRXV4/uDbT2HAcWmp7zxq3Bwr48/LHzsPngwKP6W8Pgw7NysMZimJVs3B5nL4KXZyyH/ArDy6IV7pl/Aw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-spinbutton": {
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-spinbutton/-/react-spinbutton-9.4.1.tgz",
+ "integrity": "sha512-dUj4XEocE5Uy0TWFxFNVGyRZpNJCHNl/VNWwJcDPNf6Jb5ThqGcXZ4IgWO00GoucwTkUzIHE37SSBGatL3ANsA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-spinner": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-spinner/-/react-spinner-9.6.0.tgz",
+ "integrity": "sha512-yRUozOphh92DMM/hZLp2aF12vWGpz70M7ya//E0PVhwXMD2zJf7EvK/HvgdtMNoiSkM9nYrEoe4HuEialn2WQQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-label": "^9.2.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-swatch-picker": {
+ "version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-swatch-picker/-/react-swatch-picker-9.3.1.tgz",
+ "integrity": "sha512-W7Dz9pF39KdNdYLFR6ySa13et/i+5LLkY6HrGg9k3LxtAYwCeooy++4FBYpWE87i+FcuiAGKmzhy6vHM5i2TBA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-switch": {
+ "version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-switch/-/react-switch-9.3.1.tgz",
+ "integrity": "sha512-QxmTGQQdUWpfGe40RafooeHeM8evAz6dItDsEEenu4h8KbrD0fztBjDG51fjuAPsrbYzoPS1o684+dD8pl2tNw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-label": "^9.2.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-table": {
+ "version": "9.17.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-table/-/react-table-9.17.1.tgz",
+ "integrity": "sha512-iDaX/wK4UmxYoqUPNK84553UTiYBB3YwPPjIkpxoxlv+RnjnPDshmDRT4KzCDNI2NvuhinwaKtj+b8DvMnFwHA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-avatar": "^9.8.1",
+ "@fluentui/react-checkbox": "^9.4.1",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-radio": "^9.4.1",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-tabs": {
+ "version": "9.8.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tabs/-/react-tabs-9.8.0.tgz",
+ "integrity": "sha512-0dwF8v2rSRd7c3XV+LiHlf4eetXf79S2iBmLUZKmi+BQHWZv9NhmDLOw6DE8yidcHvlKlvXcUz+UNmVLXdmsCw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-tabster": {
+ "version": "9.25.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tabster/-/react-tabster-9.25.0.tgz",
+ "integrity": "sha512-V0f0lWt/PZZ0ZDTz47qdvf4vQ5v0W2EZwhZlE2DTSiQ2U5hLAZhXKwCoM6T0nN+mviplQshNWBenbI6HS1RKgg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1",
+ "keyborg": "^2.6.0",
+ "tabster": "^8.5.5"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-text": {
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-text/-/react-text-9.5.0.tgz",
+ "integrity": "sha512-mT//jeZDafU2zEBkSsRjLWtwJ6jyj/f5DPRZQ7/sA9yeQ4YDoXoJ2+x5IoG4VX4tkK1CRvmR4LA/V8JvrWjVyg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-textarea": {
+ "version": "9.5.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-textarea/-/react-textarea-9.5.1.tgz",
+ "integrity": "sha512-wGl2rHdv1ZONOSyIjjjbTI/SDRKV89rWF6yVS2qcCI5TFC5SoxadqG+u/9Fuy3kpv69WwRU8Op3mDSz+GYFa/A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.3.1",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-theme": {
+ "version": "9.1.24",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-theme/-/react-theme-9.1.24.tgz",
+ "integrity": "sha512-OhVKYD7CMYHxzJEn4PtIszledj8hbQJNWBMfIZsp4Sytdp9vCi0txIQUx4BhS1WqtQPhNGCF16eW9Q3NRrnIrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/tokens": "1.0.0-alpha.21",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "node_modules/@fluentui/react-toast": {
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-toast/-/react-toast-9.5.0.tgz",
+ "integrity": "sha512-TPgNNxfP5X80Pl/H7jVgreGKfDdEkN/L6G1rnjM18emsIw0DYB+B46JoBwmrPCvISZJNnLstSftwwDSqQEO2hg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-motion": "^9.8.0",
+ "@fluentui/react-motion-components-preview": "^0.6.0",
+ "@fluentui/react-portal": "^9.6.0",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-toolbar": {
+ "version": "9.5.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-toolbar/-/react-toolbar-9.5.1.tgz",
+ "integrity": "sha512-8lI8lrRMdm3q9K31iKrOXbC+65OnSi+GtO06FjcKd413x0fBAYbWweRciAh3IyIAiU38RdjIvLKiIs92TuqUpg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-button": "^9.5.0",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-divider": "^9.3.0",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-radio": "^9.4.1",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-tooltip": {
+ "version": "9.7.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tooltip/-/react-tooltip-9.7.1.tgz",
+ "integrity": "sha512-LiIQDOGEsGeuAbiQItOL/OvSiX9gY5wKgUCduv1cSqQ2J/f3FbsPudBlQJs8UhukdT1jTqF7sjoNel6rMg/rNQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-portal": "^9.6.0",
+ "@fluentui/react-positioning": "^9.18.1",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-tree": {
+ "version": "9.11.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tree/-/react-tree-9.11.1.tgz",
+ "integrity": "sha512-ORRyUoDZzo0GOmiZKwnFlompCjVDi++5tBzf0o/8YQ0xOIlyuCp12oK0UI0AKATXC3lldTupmk0XSorbI4z4qg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.15.0",
+ "@fluentui/react-avatar": "^9.8.1",
+ "@fluentui/react-button": "^9.5.0",
+ "@fluentui/react-checkbox": "^9.4.1",
+ "@fluentui/react-context-selector": "^9.2.0",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.1.0",
+ "@fluentui/react-motion": "^9.8.0",
+ "@fluentui/react-motion-components-preview": "^0.6.0",
+ "@fluentui/react-radio": "^9.4.1",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@fluentui/react-tabster": "^9.25.0",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.21.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-utilities": {
+ "version": "9.21.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-utilities/-/react-utilities-9.21.0.tgz",
+ "integrity": "sha512-xViS1WwKIdPza+syMsfh1i3hNgssWgLtbevEeGb6DS/q13UKXaw9P/vezPUs6kSolnSD/juWZGP6u8ytkI1W7g==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-shared-contexts": "^9.23.1",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/set-version": {
+ "version": "8.2.24",
+ "resolved": "https://registry.npmjs.org/@fluentui/set-version/-/set-version-8.2.24.tgz",
+ "integrity": "sha512-8uNi2ThvNgF+6d3q2luFVVdk/wZV0AbRfJ85kkvf2+oSRY+f6QVK0w13vMorNhA5puumKcZniZoAfUF02w7NSg==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@fluentui/tokens": {
+ "version": "1.0.0-alpha.21",
+ "resolved": "https://registry.npmjs.org/@fluentui/tokens/-/tokens-1.0.0-alpha.21.tgz",
+ "integrity": "sha512-xQ1T56sNgDFGl+kJdIwhz67mHng8vcwO7Dvx5Uja4t+NRULQBgMcJ4reUo4FGF3TjufHj08pP0/OnKQgnOaSVg==",
+ "license": "MIT",
+ "dependencies": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "node_modules/@griffel/core": {
+ "version": "1.19.2",
+ "resolved": "https://registry.npmjs.org/@griffel/core/-/core-1.19.2.tgz",
+ "integrity": "sha512-WkB/QQkjy9dE4vrNYGhQvRRUHFkYVOuaznVOMNTDT4pS9aTJ9XPrMTXXlkpcwaf0D3vNKoerj4zAwnU2lBzbOg==",
+ "license": "MIT",
+ "dependencies": {
+ "@emotion/hash": "^0.9.0",
+ "@griffel/style-types": "^1.3.0",
+ "csstype": "^3.1.3",
+ "rtl-css-js": "^1.16.1",
+ "stylis": "^4.2.0",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@griffel/react": {
+ "version": "1.5.30",
+ "resolved": "https://registry.npmjs.org/@griffel/react/-/react-1.5.30.tgz",
+ "integrity": "sha512-1q4ojbEVFY5YA0j1NamP0WWF4BKh+GHsVugltDYeEgEaVbH3odJ7tJabuhQgY+7Nhka0pyEFWSiHJev0K3FSew==",
+ "license": "MIT",
+ "dependencies": {
+ "@griffel/core": "^1.19.2",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0 <20.0.0"
+ }
+ },
+ "node_modules/@griffel/style-types": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@griffel/style-types/-/style-types-1.3.0.tgz",
+ "integrity": "sha512-bHwD3sUE84Xwv4dH011gOKe1jul77M1S6ZFN9Tnq8pvZ48UMdY//vtES6fv7GRS5wXYT4iqxQPBluAiYAfkpmw==",
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "^3.1.3"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
+ "deprecated": "Use @eslint/config-array instead",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^2.0.3",
+ "debug": "^4.3.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.27.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@polka/url": {
+ "version": "1.0.0-next.29",
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
+ "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-beta.11",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.11.tgz",
+ "integrity": "sha512-L/gAA/hyCSuzTF1ftlzUSI/IKr2POHsv1Dd78GfqkR83KMNuswWD61JxGV2L7nRwBBBSDr6R1gCkdTmoN7W4ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.43.0.tgz",
+ "integrity": "sha512-Krjy9awJl6rKbruhQDgivNbD1WuLb8xAclM4IR4cN5pHGAs2oIMMQJEiC3IC/9TZJ+QZkmZhlMO/6MBGxPidpw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.43.0.tgz",
+ "integrity": "sha512-ss4YJwRt5I63454Rpj+mXCXicakdFmKnUNxr1dLK+5rv5FJgAxnN7s31a5VchRYxCFWdmnDWKd0wbAdTr0J5EA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.43.0.tgz",
+ "integrity": "sha512-eKoL8ykZ7zz8MjgBenEF2OoTNFAPFz1/lyJ5UmmFSz5jW+7XbH1+MAgCVHy72aG59rbuQLcJeiMrP8qP5d/N0A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.43.0.tgz",
+ "integrity": "sha512-SYwXJgaBYW33Wi/q4ubN+ldWC4DzQY62S4Ll2dgfr/dbPoF50dlQwEaEHSKrQdSjC6oIe1WgzosoaNoHCdNuMg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.43.0.tgz",
+ "integrity": "sha512-SV+U5sSo0yujrjzBF7/YidieK2iF6E7MdF6EbYxNz94lA+R0wKl3SiixGyG/9Klab6uNBIqsN7j4Y/Fya7wAjQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.43.0.tgz",
+ "integrity": "sha512-J7uCsiV13L/VOeHJBo5SjasKiGxJ0g+nQTrBkAsmQBIdil3KhPnSE9GnRon4ejX1XDdsmK/l30IYLiAaQEO0Cg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.43.0.tgz",
+ "integrity": "sha512-gTJ/JnnjCMc15uwB10TTATBEhK9meBIY+gXP4s0sHD1zHOaIh4Dmy1X9wup18IiY9tTNk5gJc4yx9ctj/fjrIw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.43.0.tgz",
+ "integrity": "sha512-ZJ3gZynL1LDSIvRfz0qXtTNs56n5DI2Mq+WACWZ7yGHFUEirHBRt7fyIk0NsCKhmRhn7WAcjgSkSVVxKlPNFFw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.43.0.tgz",
+ "integrity": "sha512-8FnkipasmOOSSlfucGYEu58U8cxEdhziKjPD2FIa0ONVMxvl/hmONtX/7y4vGjdUhjcTHlKlDhw3H9t98fPvyA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.43.0.tgz",
+ "integrity": "sha512-KPPyAdlcIZ6S9C3S2cndXDkV0Bb1OSMsX0Eelr2Bay4EsF9yi9u9uzc9RniK3mcUGCLhWY9oLr6er80P5DE6XA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.43.0.tgz",
+ "integrity": "sha512-HPGDIH0/ZzAZjvtlXj6g+KDQ9ZMHfSP553za7o2Odegb/BEfwJcR0Sw0RLNpQ9nC6Gy8s+3mSS9xjZ0n3rhcYg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.43.0.tgz",
+ "integrity": "sha512-gEmwbOws4U4GLAJDhhtSPWPXUzDfMRedT3hFMyRAvM9Mrnj+dJIFIeL7otsv2WF3D7GrV0GIewW0y28dOYWkmw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.43.0.tgz",
+ "integrity": "sha512-XXKvo2e+wFtXZF/9xoWohHg+MuRnvO29TI5Hqe9xwN5uN8NKUYy7tXUG3EZAlfchufNCTHNGjEx7uN78KsBo0g==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.43.0.tgz",
+ "integrity": "sha512-ruf3hPWhjw6uDFsOAzmbNIvlXFXlBQ4nk57Sec8E8rUxs/AI4HD6xmiiasOOx/3QxS2f5eQMKTAwk7KHwpzr/Q==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.43.0.tgz",
+ "integrity": "sha512-QmNIAqDiEMEvFV15rsSnjoSmO0+eJLoKRD9EAa9rrYNwO/XRCtOGM3A5A0X+wmG+XRrw9Fxdsw+LnyYiZWWcVw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.40.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.0.tgz",
+ "integrity": "sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.43.0.tgz",
+ "integrity": "sha512-3yATWgdeXyuHtBhrLt98w+5fKurdqvs8B53LaoKD7P7H7FKOONLsBVMNl9ghPQZQuYcceV5CDyPfyfGpMWD9mQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.43.0.tgz",
+ "integrity": "sha512-wVzXp2qDSCOpcBCT5WRWLmpJRIzv23valvcTwMHEobkjippNf+C3ys/+wf07poPkeNix0paTNemB2XrHr2TnGw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.43.0.tgz",
+ "integrity": "sha512-fYCTEyzf8d+7diCw8b+asvWDCLMjsCEA8alvtAutqJOJp/wL5hs1rWSqJ1vkjgW0L2NB4bsYJrpKkiIPRR9dvw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.43.0.tgz",
+ "integrity": "sha512-SnGhLiE5rlK0ofq8kzuDkM0g7FN1s5VYY+YSMTibP7CqShxCQvqtNxTARS4xX4PFJfHjG0ZQYX9iGzI3FQh5Aw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.17",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
+ "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@testing-library/dom": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
+ "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/runtime": "^7.12.5",
+ "@types/aria-query": "^5.0.1",
+ "aria-query": "5.3.0",
+ "chalk": "^4.1.0",
+ "dom-accessibility-api": "^0.5.9",
+ "lz-string": "^1.5.0",
+ "pretty-format": "^27.0.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@testing-library/jest-dom": {
+ "version": "6.6.3",
+ "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz",
+ "integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==",
+ "license": "MIT",
+ "dependencies": {
+ "@adobe/css-tools": "^4.4.0",
+ "aria-query": "^5.0.0",
+ "chalk": "^3.0.0",
+ "css.escape": "^1.5.1",
+ "dom-accessibility-api": "^0.6.3",
+ "lodash": "^4.17.21",
+ "redent": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14",
+ "npm": ">=6",
+ "yarn": ">=1"
+ }
+ },
+ "node_modules/@testing-library/jest-dom/node_modules/chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
+ "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
+ "license": "MIT"
+ },
+ "node_modules/@testing-library/react": {
+ "version": "16.3.0",
+ "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.0.tgz",
+ "integrity": "sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@testing-library/dom": "^10.0.0",
+ "@types/react": "^18.0.0 || ^19.0.0",
+ "@types/react-dom": "^18.0.0 || ^19.0.0",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@testing-library/user-event": {
+ "version": "13.5.0",
+ "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz",
+ "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5"
+ },
+ "engines": {
+ "node": ">=10",
+ "npm": ">=6"
+ },
+ "peerDependencies": {
+ "@testing-library/dom": ">=7.21.4"
+ }
+ },
+ "node_modules/@types/aria-query": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
+ "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
+ "license": "MIT"
+ },
+ "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.20.7",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz",
+ "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "node_modules/@types/debug": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
+ "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/ms": "*"
+ }
+ },
+ "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/estree-jsx": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz",
+ "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/hast": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
+ "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/jest": {
+ "version": "27.5.2",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz",
+ "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==",
+ "license": "MIT",
+ "dependencies": {
+ "jest-matcher-utils": "^27.0.0",
+ "pretty-format": "^27.0.0"
+ }
+ },
+ "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/mdast": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
+ "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/ms": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
+ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "20.19.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.0.tgz",
+ "integrity": "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.15",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
+ "license": "MIT"
+ },
+ "node_modules/@types/react": {
+ "version": "18.3.23",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
+ "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.3.7",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
+ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^18.0.0"
+ }
+ },
+ "node_modules/@types/semver": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz",
+ "integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/unist": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
+ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
+ "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.4.0",
+ "@typescript-eslint/scope-manager": "5.62.0",
+ "@typescript-eslint/type-utils": "5.62.0",
+ "@typescript-eslint/utils": "5.62.0",
+ "debug": "^4.3.4",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "natural-compare-lite": "^1.4.0",
+ "semver": "^7.3.7",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^5.0.0",
+ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz",
+ "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "5.62.0",
+ "@typescript-eslint/types": "5.62.0",
+ "@typescript-eslint/typescript-estree": "5.62.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
+ "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "5.62.0",
+ "@typescript-eslint/visitor-keys": "5.62.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz",
+ "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "5.62.0",
+ "@typescript-eslint/utils": "5.62.0",
+ "debug": "^4.3.4",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
+ "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz",
+ "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@typescript-eslint/types": "5.62.0",
+ "@typescript-eslint/visitor-keys": "5.62.0",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "semver": "^7.3.7",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz",
+ "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@types/json-schema": "^7.0.9",
+ "@types/semver": "^7.3.12",
+ "@typescript-eslint/scope-manager": "5.62.0",
+ "@typescript-eslint/types": "5.62.0",
+ "@typescript-eslint/typescript-estree": "5.62.0",
+ "eslint-scope": "^5.1.1",
+ "semver": "^7.3.7"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "5.62.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
+ "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "5.62.0",
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "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/@vitejs/plugin-react": {
+ "version": "4.5.2",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.5.2.tgz",
+ "integrity": "sha512-QNVT3/Lxx99nMQWJWF7K4N6apUEuT0KlZA3mx/mVaoGj3smm/8rc8ezz15J1pcbcjDK0V15rpHetVfya08r76Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.27.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.11",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.17.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0"
+ }
+ },
+ "node_modules/@vitest/expect": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.1.tgz",
+ "integrity": "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "1.6.1",
+ "@vitest/utils": "1.6.1",
+ "chai": "^4.3.10"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.1.tgz",
+ "integrity": "sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "1.6.1",
+ "p-limit": "^5.0.0",
+ "pathe": "^1.1.1"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner/node_modules/p-limit": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz",
+ "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@vitest/runner/node_modules/yocto-queue": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz",
+ "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@vitest/snapshot": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.1.tgz",
+ "integrity": "sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "magic-string": "^0.30.5",
+ "pathe": "^1.1.1",
+ "pretty-format": "^29.7.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot/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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@vitest/snapshot/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==",
+ "dev": true,
+ "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/@vitest/snapshot/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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vitest/spy": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.1.tgz",
+ "integrity": "sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyspy": "^2.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/ui": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-1.6.1.tgz",
+ "integrity": "sha512-xa57bCPGuzEFqGjPs3vVLyqareG8DX0uMkr5U/v5vLv5/ZUrBrPL7gzxzTJedEyZxFMfsozwTIbbYfEQVo3kgg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "1.6.1",
+ "fast-glob": "^3.3.2",
+ "fflate": "^0.8.1",
+ "flatted": "^3.2.9",
+ "pathe": "^1.1.1",
+ "picocolors": "^1.0.0",
+ "sirv": "^2.0.4"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "vitest": "1.6.1"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.1.tgz",
+ "integrity": "sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "diff-sequences": "^29.6.3",
+ "estree-walker": "^3.0.3",
+ "loupe": "^2.3.7",
+ "pretty-format": "^29.7.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/utils/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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@vitest/utils/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==",
+ "dev": true,
+ "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/@vitest/utils/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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/acorn-walk": {
+ "version": "8.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
+ "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
+ "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "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/aria-query": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
+ "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "dequal": "^2.0.3"
+ }
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.9",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz",
+ "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.24.0",
+ "es-object-atoms": "^1.1.1",
+ "get-intrinsic": "^1.3.0",
+ "is-string": "^1.1.1",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/array.prototype.findlast": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz",
+ "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz",
+ "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
+ "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.tosorted": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
+ "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3",
+ "es-errors": "^1.3.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/assertion-error": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/async-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
+ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/axios": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
+ "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/bail": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
+ "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "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/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "license": "ISC"
+ },
+ "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/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.25.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz",
+ "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001718",
+ "electron-to-chromium": "^1.5.160",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.3"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001723",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz",
+ "integrity": "sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==",
+ "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/ccount": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+ "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/chai": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz",
+ "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assertion-error": "^1.1.0",
+ "check-error": "^1.0.3",
+ "deep-eql": "^4.1.3",
+ "get-func-name": "^2.0.2",
+ "loupe": "^2.3.6",
+ "pathval": "^1.1.1",
+ "type-detect": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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/character-entities": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
+ "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-html4": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
+ "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-reference-invalid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
+ "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/check-error": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
+ "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-func-name": "^2.0.2"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "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/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/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/comma-separated-tokens": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
+ "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "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/confbox": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
+ "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
+ "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/css-selector-parser": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.1.2.tgz",
+ "integrity": "sha512-WfUcL99xWDs7b3eZPoRszWVfbNo8ErCF15PTvVROjkShGlAfjIkG6hlfj/sl6/rfo5Q9x9ryJ3VqVnAZDA+gcw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/mdevils"
+ },
+ {
+ "type": "patreon",
+ "url": "https://patreon.com/mdevils"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/css.escape": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
+ "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
+ "license": "MIT"
+ },
+ "node_modules/cssstyle": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.4.0.tgz",
+ "integrity": "sha512-W0Y2HOXlPkb2yaKrCVRjinYKciu/qSLEmK0K9mcfDei3zwlnHFEHAs/Du3cIRwPqY+J4JsiBzUjoHyc8RsJ03A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@asamuzakjp/css-color": "^3.2.0",
+ "rrweb-cssom": "^0.8.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cssstyle/node_modules/rrweb-cssom": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
+ "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "license": "MIT"
+ },
+ "node_modules/data-urls": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
+ "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/data-view-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/inspect-js"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decimal.js": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz",
+ "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/decode-named-character-reference": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz",
+ "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==",
+ "license": "MIT",
+ "dependencies": {
+ "character-entities": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/deep-eql": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz",
+ "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-detect": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/devlop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+ "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/diff-sequences": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
+ "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/dom-accessibility-api": {
+ "version": "0.5.16",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
+ "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
+ "license": "MIT"
+ },
+ "node_modules/dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
+ "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.167",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.167.tgz",
+ "integrity": "sha512-LxcRvnYO5ez2bMOFpbuuVuAI5QNeY1ncVytE/KXaL6ZNfzX1yPlAO0nSOyIHx2fVAuUprMqPs/TdVhUFZy7SIQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/embla-carousel": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz",
+ "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==",
+ "license": "MIT"
+ },
+ "node_modules/embla-carousel-autoplay": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/embla-carousel-autoplay/-/embla-carousel-autoplay-8.6.0.tgz",
+ "integrity": "sha512-OBu5G3nwaSXkZCo1A6LTaFMZ8EpkYbwIaH+bPqdBnDGQ2fh4+NbzjXjs2SktoPNKCtflfVMc75njaDHOYXcrsA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "embla-carousel": "8.6.0"
+ }
+ },
+ "node_modules/embla-carousel-fade": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/embla-carousel-fade/-/embla-carousel-fade-8.6.0.tgz",
+ "integrity": "sha512-qaYsx5mwCz72ZrjlsXgs1nKejSrW+UhkbOMwLgfRT7w2LtdEB03nPRI06GHuHv5ac2USvbEiX2/nAHctcDwvpg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "embla-carousel": "8.6.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.24.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz",
+ "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.2",
+ "arraybuffer.prototype.slice": "^1.0.4",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "data-view-buffer": "^1.0.2",
+ "data-view-byte-length": "^1.0.2",
+ "data-view-byte-offset": "^1.0.1",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "get-symbol-description": "^1.1.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.5",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.2",
+ "is-negative-zero": "^2.0.3",
+ "is-regex": "^1.2.1",
+ "is-set": "^2.0.3",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.1",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.4",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.4",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "stop-iteration-iterator": "^1.1.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-length": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.1.0",
+ "which-typed-array": "^1.1.19"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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-iterator-helpers": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz",
+ "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.6",
+ "es-errors": "^1.3.0",
+ "es-set-tostringtag": "^2.0.3",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.6",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "internal-slot": "^1.1.0",
+ "iterator.prototype": "^1.1.4",
+ "safe-array-concat": "^1.1.3"
+ },
+ "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/es-shim-unscopables": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz",
+ "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+ "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.0.5",
+ "is-symbol": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-plugin-react": {
+ "version": "7.37.5",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz",
+ "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-includes": "^3.1.8",
+ "array.prototype.findlast": "^1.2.5",
+ "array.prototype.flatmap": "^1.3.3",
+ "array.prototype.tosorted": "^1.1.4",
+ "doctrine": "^2.1.0",
+ "es-iterator-helpers": "^1.2.1",
+ "estraverse": "^5.3.0",
+ "hasown": "^2.0.2",
+ "jsx-ast-utils": "^2.4.1 || ^3.0.0",
+ "minimatch": "^3.1.2",
+ "object.entries": "^1.1.9",
+ "object.fromentries": "^2.0.8",
+ "object.values": "^1.2.1",
+ "prop-types": "^15.8.1",
+ "resolve": "^2.0.0-next.5",
+ "semver": "^6.3.1",
+ "string.prototype.matchall": "^4.0.12",
+ "string.prototype.repeat": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/eslint-scope/node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/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/node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-util-is-identifier-name": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz",
+ "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/execa": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+ "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^8.0.1",
+ "human-signals": "^5.0.0",
+ "is-stream": "^3.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^5.1.0",
+ "onetime": "^6.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "license": "MIT"
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fflate": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
+ "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
+ "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.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.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz",
+ "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==",
+ "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/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
+ "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "functions-have-names": "^1.2.3",
+ "hasown": "^2.0.2",
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-func-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
+ "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.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/get-stream": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+ "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/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/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has-bigints": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/hast-util-from-html": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz",
+ "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "devlop": "^1.1.0",
+ "hast-util-from-parse5": "^8.0.0",
+ "parse5": "^7.0.0",
+ "vfile": "^6.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-from-parse5": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz",
+ "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "devlop": "^1.0.0",
+ "hastscript": "^9.0.0",
+ "property-information": "^7.0.0",
+ "vfile": "^6.0.0",
+ "vfile-location": "^5.0.0",
+ "web-namespaces": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-from-parse5/node_modules/hastscript": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz",
+ "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-parse-selector": "^4.0.0",
+ "property-information": "^7.0.0",
+ "space-separated-tokens": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-parse-selector": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz",
+ "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-to-jsx-runtime": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz",
+ "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "devlop": "^1.0.0",
+ "estree-util-is-identifier-name": "^3.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "mdast-util-mdx-expression": "^2.0.0",
+ "mdast-util-mdx-jsx": "^3.0.0",
+ "mdast-util-mdxjs-esm": "^2.0.0",
+ "property-information": "^7.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "style-to-js": "^1.0.0",
+ "unist-util-position": "^5.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-whitespace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
+ "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hastscript": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz",
+ "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-parse-selector": "^4.0.0",
+ "property-information": "^6.0.0",
+ "space-separated-tokens": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hastscript/node_modules/property-information": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz",
+ "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/html-encoding-sniffer": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
+ "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-encoding": "^3.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/html-url-attributes": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz",
+ "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
+ "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.17.0"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.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/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/inline-style-parser": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz",
+ "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==",
+ "license": "MIT"
+ },
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-alphabetical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
+ "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphanumerical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
+ "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
+ "license": "MIT",
+ "dependencies": {
+ "is-alphabetical": "^2.0.0",
+ "is-decimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-async-function": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
+ "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "async-function": "^1.0.0",
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-decimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
+ "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz",
+ "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.0",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-hexadecimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
+ "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+ "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+ "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz",
+ "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/iterator.prototype": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz",
+ "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.6",
+ "get-proto": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/jest-diff": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz",
+ "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^27.5.1",
+ "jest-get-type": "^27.5.1",
+ "pretty-format": "^27.5.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-diff/node_modules/diff-sequences": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz",
+ "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==",
+ "license": "MIT",
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-get-type": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz",
+ "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==",
+ "license": "MIT",
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz",
+ "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==",
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "jest-diff": "^27.5.1",
+ "jest-get-type": "^27.5.1",
+ "pretty-format": "^27.5.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsdom": {
+ "version": "24.1.3",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.3.tgz",
+ "integrity": "sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssstyle": "^4.0.1",
+ "data-urls": "^5.0.0",
+ "decimal.js": "^10.4.3",
+ "form-data": "^4.0.0",
+ "html-encoding-sniffer": "^4.0.0",
+ "http-proxy-agent": "^7.0.2",
+ "https-proxy-agent": "^7.0.5",
+ "is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.12",
+ "parse5": "^7.1.2",
+ "rrweb-cssom": "^0.7.1",
+ "saxes": "^6.0.0",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^4.1.4",
+ "w3c-xmlserializer": "^5.0.0",
+ "webidl-conversions": "^7.0.0",
+ "whatwg-encoding": "^3.1.1",
+ "whatwg-mimetype": "^4.0.0",
+ "whatwg-url": "^14.0.0",
+ "ws": "^8.18.0",
+ "xml-name-validator": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "canvas": "^2.11.2"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "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/jsx-ast-utils": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
+ "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-includes": "^3.1.6",
+ "array.prototype.flat": "^1.3.1",
+ "object.assign": "^4.1.4",
+ "object.values": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/keyborg": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/keyborg/-/keyborg-2.6.0.tgz",
+ "integrity": "sha512-o5kvLbuTF+o326CMVYpjlaykxqYP9DphFQZ2ZpgrvBouyvOxyEB7oqe8nOLFpiV5VCtz0D3pt8gXQYWpLpBnmA==",
+ "license": "MIT"
+ },
+ "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/local-pkg": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz",
+ "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mlly": "^1.7.3",
+ "pkg-types": "^1.2.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "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": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "license": "MIT"
+ },
+ "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/longest-streak": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
+ "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/loupe": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
+ "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-func-name": "^2.0.1"
+ }
+ },
+ "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/lz-string": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
+ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
+ "license": "MIT",
+ "bin": {
+ "lz-string": "bin/bin.js"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.17",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "node_modules/markdown-table": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz",
+ "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "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/mdast-util-find-and-replace": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz",
+ "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "escape-string-regexp": "^5.0.0",
+ "unist-util-is": "^6.0.0",
+ "unist-util-visit-parents": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mdast-util-from-markdown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz",
+ "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-to-string": "^4.0.0",
+ "micromark": "^4.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-decode-string": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz",
+ "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==",
+ "license": "MIT",
+ "dependencies": {
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-gfm-autolink-literal": "^2.0.0",
+ "mdast-util-gfm-footnote": "^2.0.0",
+ "mdast-util-gfm-strikethrough": "^2.0.0",
+ "mdast-util-gfm-table": "^2.0.0",
+ "mdast-util-gfm-task-list-item": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-autolink-literal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz",
+ "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "ccount": "^2.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-find-and-replace": "^3.0.0",
+ "micromark-util-character": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-footnote": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz",
+ "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.1.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-strikethrough": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz",
+ "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-table": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz",
+ "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "markdown-table": "^3.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-task-list-item": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz",
+ "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdx-expression": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz",
+ "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdx-jsx": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz",
+ "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "devlop": "^1.1.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0",
+ "parse-entities": "^4.0.0",
+ "stringify-entities": "^4.0.0",
+ "unist-util-stringify-position": "^4.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdxjs-esm": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz",
+ "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-phrasing": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz",
+ "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-hast": {
+ "version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz",
+ "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@ungap/structured-clone": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "trim-lines": "^3.0.0",
+ "unist-util-position": "^5.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-markdown": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz",
+ "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "longest-streak": "^3.0.0",
+ "mdast-util-phrasing": "^4.0.0",
+ "mdast-util-to-string": "^4.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-decode-string": "^2.0.0",
+ "unist-util-visit": "^5.0.0",
+ "zwitch": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
+ "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromark": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
+ "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@types/debug": "^4.0.0",
+ "debug": "^4.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-combine-extensions": "^2.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-core-commonmark": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz",
+ "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-factory-destination": "^2.0.0",
+ "micromark-factory-label": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-factory-title": "^2.0.0",
+ "micromark-factory-whitespace": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-html-tag-name": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-extension-gfm": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz",
+ "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark-extension-gfm-autolink-literal": "^2.0.0",
+ "micromark-extension-gfm-footnote": "^2.0.0",
+ "micromark-extension-gfm-strikethrough": "^2.0.0",
+ "micromark-extension-gfm-table": "^2.0.0",
+ "micromark-extension-gfm-tagfilter": "^2.0.0",
+ "micromark-extension-gfm-task-list-item": "^2.0.0",
+ "micromark-util-combine-extensions": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-autolink-literal": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz",
+ "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-footnote": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz",
+ "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==",
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-strikethrough": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz",
+ "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==",
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-table": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz",
+ "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==",
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-tagfilter": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz",
+ "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-task-list-item": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz",
+ "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==",
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-factory-destination": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
+ "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-label": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
+ "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-space": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-title": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
+ "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-whitespace": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
+ "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-character": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-chunked": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
+ "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-classify-character": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
+ "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-combine-extensions": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
+ "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-decode-numeric-character-reference": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
+ "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-decode-string": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz",
+ "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "decode-named-character-reference": "^1.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-encode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
+ "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-html-tag-name": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
+ "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-normalize-identifier": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
+ "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-resolve-all": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
+ "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-sanitize-uri": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
+ "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-subtokenize": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz",
+ "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-symbol": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
+ "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+ "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/min-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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/mlly": {
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz",
+ "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.14.0",
+ "pathe": "^2.0.1",
+ "pkg-types": "^1.3.0",
+ "ufo": "^1.5.4"
+ }
+ },
+ "node_modules/mlly/node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mrmime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
+ "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "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==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/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/natural-compare-lite": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
+ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/npm-run-path": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
+ "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-run-path/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/nwsapi": {
+ "version": "2.2.20",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.20.tgz",
+ "integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==",
+ "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/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.entries": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz",
+ "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.fromentries": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
+ "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+ "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/own-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
+ "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.6",
+ "object-keys": "^1.1.1",
+ "safe-push-apply": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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/parse-entities": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz",
+ "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "character-entities-legacy": "^3.0.0",
+ "character-reference-invalid": "^2.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "is-alphanumerical": "^2.0.0",
+ "is-decimal": "^2.0.0",
+ "is-hexadecimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/parse-entities/node_modules/@types/unist": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
+ "license": "MIT"
+ },
+ "node_modules/parse5": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^6.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pathe": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
+ "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pathval": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
+ "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pkg-types": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
+ "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "confbox": "^0.1.8",
+ "mlly": "^1.7.4",
+ "pathe": "^2.0.1"
+ }
+ },
+ "node_modules/pkg-types/node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.5",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.5.tgz",
+ "integrity": "sha512-d/jtm+rdNT8tpXuHY5MMtcbJFBkhXE6593XVR9UoGCH8jSFGci7jGvMGH5RYd5PBJW+00NZQt6gf7CbagJCrhg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.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/pretty-format": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.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/prismjs": {
+ "version": "1.30.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
+ "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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/prop-types/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/property-information": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz",
+ "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
+ },
+ "node_modules/psl": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
+ "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/lupomontero"
+ }
+ },
+ "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/querystringify": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/react": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.2"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1"
+ }
+ },
+ "node_modules/react-dom/node_modules/scheduler": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "license": "MIT"
+ },
+ "node_modules/react-markdown": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz",
+ "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "hast-util-to-jsx-runtime": "^2.0.0",
+ "html-url-attributes": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "remark-parse": "^11.0.0",
+ "remark-rehype": "^11.0.0",
+ "unified": "^11.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18",
+ "react": ">=18"
+ }
+ },
+ "node_modules/react-refresh": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
+ "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-router": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.2.tgz",
+ "integrity": "sha512-U7Nv3y+bMimgWjhlT5CRdzHPu2/KVmqPwKUCChW8en5P3znxUqwlYFlbmyj8Rgp1SF6zs5X4+77kBVknkg6a0w==",
+ "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.6.2",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.6.2.tgz",
+ "integrity": "sha512-Q8zb6VlTbdYKK5JJBLQEN06oTUa/RAbG/oQS1auK1I0TbJOXktqm+QENEVJU6QvWynlXPRBXI3fiOQcSEA78rA==",
+ "license": "MIT",
+ "dependencies": {
+ "react-router": "7.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
+ "node_modules/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.6.0",
+ "react-dom": ">=16.6.0"
+ }
+ },
+ "node_modules/redent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
+ "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
+ "license": "MIT",
+ "dependencies": {
+ "indent-string": "^4.0.0",
+ "strip-indent": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.9",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.1",
+ "which-builtin-type": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/rehype-parse": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz",
+ "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "hast-util-from-html": "^2.0.0",
+ "unified": "^11.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/rehype-prism": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/rehype-prism/-/rehype-prism-2.3.3.tgz",
+ "integrity": "sha512-J9mhio/CwcJRDyIhsp5hgXmyGeQsFN+/1eNEKnBRxfdJAx2CqH41kV0dqn/k2OgMdjk21IoGFgar0MfVtGYTSg==",
+ "license": "MIT",
+ "dependencies": {
+ "hastscript": "^8.0.0",
+ "prismjs": "^1.29.0",
+ "rehype-parse": "^9.0.1",
+ "unist-util-is": "^6.0.0",
+ "unist-util-select": "^5.1.0",
+ "unist-util-visit": "^5.0.0"
+ },
+ "peerDependencies": {
+ "unified": "^10 || ^11"
+ }
+ },
+ "node_modules/remark-gfm": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz",
+ "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-gfm": "^3.0.0",
+ "micromark-extension-gfm": "^3.0.0",
+ "remark-parse": "^11.0.0",
+ "remark-stringify": "^11.0.0",
+ "unified": "^11.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-parse": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
+ "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "unified": "^11.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-rehype": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz",
+ "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "unified": "^11.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-stringify": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz",
+ "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-to-markdown": "^2.0.0",
+ "unified": "^11.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/resolve": {
+ "version": "2.0.0-next.5",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
+ "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/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/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.43.0.tgz",
+ "integrity": "sha512-wdN2Kd3Twh8MAEOEJZsuxuLKCsBEo4PVNLK6tQWAn10VhsVewQLzcucMgLolRlhFybGxfclbPeEYBaP6RvUFGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.7"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.43.0",
+ "@rollup/rollup-android-arm64": "4.43.0",
+ "@rollup/rollup-darwin-arm64": "4.43.0",
+ "@rollup/rollup-darwin-x64": "4.43.0",
+ "@rollup/rollup-freebsd-arm64": "4.43.0",
+ "@rollup/rollup-freebsd-x64": "4.43.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.43.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.43.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.43.0",
+ "@rollup/rollup-linux-arm64-musl": "4.43.0",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.43.0",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.43.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.43.0",
+ "@rollup/rollup-linux-riscv64-musl": "4.43.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.43.0",
+ "@rollup/rollup-linux-x64-gnu": "4.43.0",
+ "@rollup/rollup-linux-x64-musl": "4.43.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.43.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.43.0",
+ "@rollup/rollup-win32-x64-msvc": "4.43.0",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.43.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.43.0.tgz",
+ "integrity": "sha512-jAHr/S0iiBtFyzjhOkAics/2SrXE092qyqEg96e90L3t9Op8OTzS6+IX0Fy5wCt2+KqeHAkti+eitV0wvblEoQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/rollup/node_modules/@types/estree": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
+ "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rrweb-cssom": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz",
+ "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rtl-css-js": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz",
+ "integrity": "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.1.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-array-concat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
+ "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "has-symbols": "^1.1.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-push-apply": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/saxes": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
+ "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "xmlchars": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=v12.22.7"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
+ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
+ "license": "MIT"
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
+ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/siginfo": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
+ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/sirv": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz",
+ "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polka/url": "^1.0.0-next.24",
+ "mrmime": "^2.0.0",
+ "totalist": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/space-separated-tokens": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+ "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/stackback": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
+ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/std-env": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz",
+ "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/stop-iteration-iterator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
+ "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "internal-slot": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/string.prototype.matchall": {
+ "version": "4.0.12",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
+ "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.6",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.6",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "internal-slot": "^1.1.0",
+ "regexp.prototype.flags": "^1.5.3",
+ "set-function-name": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.repeat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz",
+ "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
+ "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-data-property": "^1.1.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-object-atoms": "^1.0.0",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
+ "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/stringify-entities": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
+ "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
+ "license": "MIT",
+ "dependencies": {
+ "character-entities-html4": "^2.0.0",
+ "character-entities-legacy": "^3.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+ "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-indent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
+ "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "min-indent": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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/strip-literal": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.1.tgz",
+ "integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^9.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/strip-literal/node_modules/js-tokens": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
+ "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/style-to-js": {
+ "version": "1.1.16",
+ "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz",
+ "integrity": "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==",
+ "license": "MIT",
+ "dependencies": {
+ "style-to-object": "1.0.8"
+ }
+ },
+ "node_modules/style-to-object": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz",
+ "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==",
+ "license": "MIT",
+ "dependencies": {
+ "inline-style-parser": "0.2.4"
+ }
+ },
+ "node_modules/stylis": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz",
+ "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==",
+ "license": "MIT"
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tabster": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/tabster/-/tabster-8.5.6.tgz",
+ "integrity": "sha512-2vfrRGrx8O9BjdrtSlVA5fvpmbq5HQBRN13XFRg6LAvZ1Fr3QdBnswgT4YgFS5Bhoo5nxwgjRaRueI2Us/dv7g==",
+ "license": "MIT",
+ "dependencies": {
+ "keyborg": "2.6.0",
+ "tslib": "^2.8.1"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-linux-x64-gnu": "4.40.0"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinybench": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinypool": {
+ "version": "0.8.4",
+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz",
+ "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tinyspy": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz",
+ "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/totalist": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
+ "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
+ "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.2.0",
+ "url-parse": "^1.5.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/trim-lines": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
+ "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/trough": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz",
+ "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/tsutils": {
+ "version": "3.21.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+ "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^1.8.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "peerDependencies": {
+ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
+ }
+ },
+ "node_modules/tsutils/node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true,
+ "license": "0BSD"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
+ "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "reflect.getprototypeof": "^1.0.9"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
+ "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0",
+ "reflect.getprototypeof": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/ufo": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz",
+ "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unified": {
+ "version": "11.0.5",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
+ "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "bail": "^2.0.0",
+ "devlop": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-plain-obj": "^4.0.0",
+ "trough": "^2.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-is": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
+ "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-position": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
+ "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-select": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/unist-util-select/-/unist-util-select-5.1.0.tgz",
+ "integrity": "sha512-4A5mfokSHG/rNQ4g7gSbdEs+H586xyd24sdJqF1IWamqrLHvYb+DH48fzxowyOhOfK7YSqX+XlCojAyuuyyT2A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "css-selector-parser": "^3.0.0",
+ "devlop": "^1.1.0",
+ "nth-check": "^2.0.0",
+ "zwitch": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-stringify-position": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
+ "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
+ "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0",
+ "unist-util-visit-parents": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit-parents": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",
+ "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
+ "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/url-parse": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+ "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
+ "node_modules/use-sync-external-store": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
+ "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/vfile": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
+ "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vfile-location": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz",
+ "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vfile-message": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz",
+ "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vite": {
+ "version": "5.4.19",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz",
+ "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-node": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.1.tgz",
+ "integrity": "sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cac": "^6.7.14",
+ "debug": "^4.3.4",
+ "pathe": "^1.1.1",
+ "picocolors": "^1.0.0",
+ "vite": "^5.0.0"
+ },
+ "bin": {
+ "vite-node": "vite-node.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/vitest": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.1.tgz",
+ "integrity": "sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/expect": "1.6.1",
+ "@vitest/runner": "1.6.1",
+ "@vitest/snapshot": "1.6.1",
+ "@vitest/spy": "1.6.1",
+ "@vitest/utils": "1.6.1",
+ "acorn-walk": "^8.3.2",
+ "chai": "^4.3.10",
+ "debug": "^4.3.4",
+ "execa": "^8.0.1",
+ "local-pkg": "^0.5.0",
+ "magic-string": "^0.30.5",
+ "pathe": "^1.1.1",
+ "picocolors": "^1.0.0",
+ "std-env": "^3.5.0",
+ "strip-literal": "^2.0.0",
+ "tinybench": "^2.5.1",
+ "tinypool": "^0.8.3",
+ "vite": "^5.0.0",
+ "vite-node": "1.6.1",
+ "why-is-node-running": "^2.2.2"
+ },
+ "bin": {
+ "vitest": "vitest.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@edge-runtime/vm": "*",
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "@vitest/browser": "1.6.1",
+ "@vitest/ui": "1.6.1",
+ "happy-dom": "*",
+ "jsdom": "*"
+ },
+ "peerDependenciesMeta": {
+ "@edge-runtime/vm": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@vitest/browser": {
+ "optional": true
+ },
+ "@vitest/ui": {
+ "optional": true
+ },
+ "happy-dom": {
+ "optional": true
+ },
+ "jsdom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/w3c-xmlserializer": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
+ "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xml-name-validator": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/web-namespaces": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz",
+ "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/web-vitals": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz",
+ "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/whatwg-encoding": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "^5.1.0",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.19",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
+ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/why-is-node-running": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "siginfo": "^2.0.0",
+ "stackback": "0.0.2"
+ },
+ "bin": {
+ "why-is-node-running": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ws": {
+ "version": "8.18.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz",
+ "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xml-name-validator": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
+ "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/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/zwitch": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+ "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ }
+ }
}
diff --git a/src/frontend/package.json b/src/frontend/package.json
new file mode 100644
index 000000000..64e4c2c11
--- /dev/null
+++ b/src/frontend/package.json
@@ -0,0 +1,70 @@
+{
+ "name": "Multi Agent frontend",
+ "version": "0.1.0",
+ "private": true,
+ "dependencies": {
+ "@fluentui/merge-styles": "^8.6.14",
+ "@fluentui/react-components": "^9.64.0",
+ "@fluentui/react-icons": "^2.0.300",
+ "@testing-library/dom": "^10.4.0",
+ "@testing-library/jest-dom": "^6.6.3",
+ "@testing-library/react": "^16.3.0",
+ "@testing-library/user-event": "^13.5.0",
+ "@types/jest": "^27.5.2",
+ "@types/node": "^16.18.126",
+ "@types/react": "^18.3.23",
+ "@types/react-dom": "^18.3.7",
+ "axios": "^1.9.0",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "react-markdown": "^10.1.0",
+ "react-router-dom": "^7.6.0",
+ "rehype-prism": "^2.3.3",
+ "remark-gfm": "^4.0.1",
+ "web-vitals": "^2.1.4"
+ },
+ "scripts": {
+ "dev": "vite",
+ "start": "vite",
+ "build": "tsc && vite build",
+ "preview": "vite preview",
+ "test": "vitest",
+ "test:ui": "vitest --ui",
+ "lint": "eslint src --ext .js,.jsx,.ts,.tsx",
+ "lint:fix": "eslint src --ext .js,.jsx,.ts,.tsx --fix"
+ },
+ "eslintConfig": {
+ "extends": [
+ "react-app",
+ "react-app/jest"
+ ],
+ "rules": {
+ "react-hooks/exhaustive-deps": "warn"
+ }
+ },
+ "browserslist": {
+ "production": [
+ ">0.2%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ]
+ },
+ "devDependencies": {
+ "@types/node": "^20.0.0",
+ "@typescript-eslint/eslint-plugin": "^5.62.0",
+ "@typescript-eslint/parser": "^5.62.0",
+ "@vitejs/plugin-react": "^4.5.1",
+ "@vitest/ui": "^1.6.1",
+ "eslint": "^8.57.1",
+ "eslint-plugin-react": "^7.37.5",
+ "jsdom": "^24.1.3",
+ "typescript": "^5.8.3",
+ "vite": "^5.4.19",
+ "vitest": "^1.6.1"
+ }
+}
\ No newline at end of file
diff --git a/src/frontend/public/favicon-96x96.png b/src/frontend/public/favicon-96x96.png
new file mode 100644
index 000000000..da387aacf
Binary files /dev/null and b/src/frontend/public/favicon-96x96.png differ
diff --git a/src/frontend/public/favicon.ico b/src/frontend/public/favicon.ico
new file mode 100644
index 000000000..a42bfb576
Binary files /dev/null and b/src/frontend/public/favicon.ico differ
diff --git a/src/frontend/public/index.html b/src/frontend/public/index.html
new file mode 100644
index 000000000..77b294ca3
--- /dev/null
+++ b/src/frontend/public/index.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+ MACAE
+
+
+ You need to enable JavaScript to run this app.
+
+
+
+
diff --git a/src/frontend/public/logo192.png b/src/frontend/public/logo192.png
new file mode 100644
index 000000000..2145e9030
Binary files /dev/null and b/src/frontend/public/logo192.png differ
diff --git a/src/frontend/public/logo512.png b/src/frontend/public/logo512.png
new file mode 100644
index 000000000..b0d71e280
Binary files /dev/null and b/src/frontend/public/logo512.png differ
diff --git a/src/frontend/public/manifest.json b/src/frontend/public/manifest.json
new file mode 100644
index 000000000..089211216
--- /dev/null
+++ b/src/frontend/public/manifest.json
@@ -0,0 +1,15 @@
+{
+ "short_name": "MACAE",
+ "name": "Multi-Agent-Custom-Automation-Engine",
+ "icons": [
+ {
+ "src": "favicon.ico",
+ "sizes": "64x64 32x32 24x24 16x16",
+ "type": "image/x-icon"
+ }
+ ],
+ "start_url": ".",
+ "display": "standalone",
+ "theme_color": "#000000",
+ "background_color": "#ffffff"
+}
\ No newline at end of file
diff --git a/src/frontend/public/robots.txt b/src/frontend/public/robots.txt
new file mode 100644
index 000000000..e9e57dc4d
--- /dev/null
+++ b/src/frontend/public/robots.txt
@@ -0,0 +1,3 @@
+# https://www.robotstxt.org/robotstxt.html
+User-agent: *
+Disallow:
diff --git a/src/frontend/pyproject.toml b/src/frontend/pyproject.toml
index 5b7102281..76b7e8d31 100644
--- a/src/frontend/pyproject.toml
+++ b/src/frontend/pyproject.toml
@@ -1,14 +1,7 @@
[project]
-name = "frontend"
+name = "frontend-react"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
-dependencies = [
- "azure-identity>=1.21.0",
- "fastapi>=0.115.12",
- "jinja2>=3.1.6",
- "python-dotenv>=1.1.0",
- "python-multipart>=0.0.20",
- "uvicorn>=0.34.2",
-]
+dependencies = []
diff --git a/src/frontend/requirements.txt b/src/frontend/requirements.txt
index 335a4afcb..35c4db535 100644
--- a/src/frontend/requirements.txt
+++ b/src/frontend/requirements.txt
@@ -1,5 +1,6 @@
fastapi
-uvicorn
+uvicorn[standard]
+# uvicorn removed and added above to allow websocket support
jinja2
azure-identity
python-dotenv
diff --git a/src/frontend/src/App.css b/src/frontend/src/App.css
new file mode 100644
index 000000000..a38bc87e0
--- /dev/null
+++ b/src/frontend/src/App.css
@@ -0,0 +1,76 @@
+/* APP */
+
+
+.tab {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ color: var(--colorNeutralForeground2);
+ padding: 8px 16px;
+ border-radius: 6px;
+ font-size: 14px;
+ text-decoration: none;
+ cursor: pointer;
+ transition: background-color 0.2s ease-in-out;
+}
+
+.tab:hover {
+ background-color: var(--colorSubtleBackgroundHover);
+}
+
+.tab:active {
+ background-color: var(--colorSubtleBackgroundPressed);
+}
+
+
+/* TASKLIST */
+
+.task-tab {
+ display: flex;
+ align-items: center;
+ padding: 8px 8px 8px 0;
+ color: var(--colorNeutralForeground2);
+ border-radius: 6px;
+ cursor: pointer;
+ transition: background-color 0.2s ease-in-out;
+ font-size: var(--fontSizeBase00);
+ gap: 14px;
+
+}
+
+.task-tab:hover {
+ background-color: var(--colorSubtleBackgroundHover);
+}
+
+.task-tab.active {
+ background-color: var(--colorNeutralBackground1Pressed);
+ color: var(--colorNeutralForeground1);
+ font-weight: 500;
+
+}
+
+.task-tab .sideNavTick {
+ width: 2px;
+ height: 100%;
+ min-height: 32px;
+ background-color: var(--colorCompoundBrandStroke);
+ opacity: 0;
+ flex-shrink: 0;
+ transition: opacity 0.2s ease-in-out;
+ margin-left: -8px;
+
+}
+
+.task-tab.active .sideNavTick {
+ opacity: 1;
+}
+
+.task-tab .task-menu-button {
+ opacity: 0;
+ transition: opacity 0.2s ease-in-out;
+}
+
+.task-tab:hover .task-menu-button {
+ opacity: 1;
+}
+
diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx
new file mode 100644
index 000000000..40bce4581
--- /dev/null
+++ b/src/frontend/src/App.tsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import './App.css';
+import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
+import { HomePage, PlanPage } from './pages';
+
+function App() {
+ return (
+
+
+ } />
+ } />
+ } />
+
+
+ );
+}
+
+export default App;
\ No newline at end of file
diff --git a/src/frontend/src/api/apiClient.tsx b/src/frontend/src/api/apiClient.tsx
new file mode 100644
index 000000000..8d574fb18
--- /dev/null
+++ b/src/frontend/src/api/apiClient.tsx
@@ -0,0 +1,110 @@
+import { headerBuilder, getApiUrl } from './config';
+
+// Helper function to build URL with query parameters
+const buildUrl = (url: string, params?: Record): string => {
+ if (!params) return url;
+
+ const searchParams = new URLSearchParams();
+ Object.entries(params).forEach(([key, value]) => {
+ if (value !== undefined && value !== null) {
+ searchParams.append(key, String(value));
+ }
+ });
+
+ const queryString = searchParams.toString();
+ return queryString ? `${url}?${queryString}` : url;
+};
+
+// Fetch with Authentication Headers
+const fetchWithAuth = async (url: string, method: string = "GET", body: BodyInit | null = null) => {
+ const token = localStorage.getItem('token'); // Get the token from localStorage
+ const authHeaders = headerBuilder(); // Get authentication headers
+
+ const headers: Record = {
+ ...authHeaders, // Include auth headers from headerBuilder
+ };
+
+ if (token) {
+ headers['Authorization'] = `Bearer ${token}`; // Add the token to the Authorization header
+ }
+
+ // If body is FormData, do not set Content-Type header
+ if (body && body instanceof FormData) {
+ delete headers['Content-Type'];
+ } else {
+ headers['Content-Type'] = 'application/json';
+ body = body ? JSON.stringify(body) : null;
+ }
+
+ const options: RequestInit = {
+ method,
+ headers,
+ body: body || undefined,
+ };
+
+ try {
+ const apiUrl = getApiUrl();
+ const finalUrl = `${apiUrl}${url}`;
+ console.log('Final URL:', finalUrl);
+ console.log('Request Options:', options);
+ // Log the request details
+ const response = await fetch(finalUrl, options);
+ console.log('response', response);
+
+ if (!response.ok) {
+ const errorText = await response.text();
+ throw new Error(errorText || 'Something went wrong');
+ }
+
+ const isJson = response.headers.get('content-type')?.includes('application/json');
+ const responseData = isJson ? await response.json() : null;
+
+ console.log('Response JSON:', responseData);
+ return responseData;
+ } catch (error) {
+ console.info('API Error:', (error as Error).message);
+ throw error;
+ }
+};
+
+// Vanilla Fetch without Auth for Login
+const fetchWithoutAuth = async (url: string, method: string = "POST", body: BodyInit | null = null) => {
+ const headers: Record = {
+ 'Content-Type': 'application/json',
+ };
+
+ const options: RequestInit = {
+ method,
+ headers,
+ body: body ? JSON.stringify(body) : undefined,
+ };
+
+ try {
+ const apiUrl = getApiUrl();
+ const response = await fetch(`${apiUrl}${url}`, options);
+
+ if (!response.ok) {
+ const errorText = await response.text();
+ throw new Error(errorText || 'Login failed');
+ }
+ console.log('response', response);
+ const isJson = response.headers.get('content-type')?.includes('application/json');
+ return isJson ? await response.json() : null;
+ } catch (error) {
+ console.log('Login Error:', (error as Error).message);
+ throw error;
+ }
+};
+
+// Authenticated requests (with token) and login (without token)
+export const apiClient = {
+ get: (url: string, config?: { params?: Record }) => {
+ const finalUrl = buildUrl(url, config?.params);
+ return fetchWithAuth(finalUrl, 'GET');
+ },
+ post: (url: string, body?: any) => fetchWithAuth(url, 'POST', body),
+ put: (url: string, body?: any) => fetchWithAuth(url, 'PUT', body),
+ delete: (url: string) => fetchWithAuth(url, 'DELETE'),
+ upload: (url: string, formData: FormData) => fetchWithAuth(url, 'POST', formData),
+ login: (url: string, body?: any) => fetchWithoutAuth(url, 'POST', body), // For login without auth
+};
diff --git a/src/frontend/src/api/apiService.tsx b/src/frontend/src/api/apiService.tsx
new file mode 100644
index 000000000..9367b1fec
--- /dev/null
+++ b/src/frontend/src/api/apiService.tsx
@@ -0,0 +1,506 @@
+import { apiClient } from './apiClient';
+import {
+ AgentMessage,
+ HumanClarification,
+ InputTask,
+ InputTaskResponse,
+ PlanWithSteps,
+ Plan,
+ Step,
+ StepStatus,
+ AgentType,
+ PlanMessage
+} from '../models';
+
+// Constants for endpoints
+const API_ENDPOINTS = {
+ INPUT_TASK: '/input_task',
+ PLANS: '/plans',
+ STEPS: '/steps',
+ HUMAN_FEEDBACK: '/human_feedback',
+ APPROVE_STEPS: '/approve_step_or_steps',
+ HUMAN_CLARIFICATION: '/human_clarification_on_plan',
+ AGENT_MESSAGES: '/agent_messages',
+ MESSAGES: '/messages'
+};
+
+// Simple cache implementation
+interface CacheEntry {
+ data: T;
+ timestamp: number;
+ ttl: number; // Time to live in ms
+}
+
+class APICache {
+ private cache: Map> = new Map();
+
+ set(key: string, data: T, ttl = 60000): void { // Default TTL: 1 minute
+ this.cache.set(key, {
+ data,
+ timestamp: Date.now(),
+ ttl
+ });
+ }
+
+ get(key: string): T | null {
+ const entry = this.cache.get(key);
+ if (!entry) return null;
+
+ // Check if entry is expired
+ if (Date.now() - entry.timestamp > entry.ttl) {
+ this.cache.delete(key);
+ return null;
+ }
+
+ return entry.data;
+ }
+
+ clear(): void {
+ this.cache.clear();
+ }
+
+ invalidate(pattern: RegExp): void {
+ for (const key of this.cache.keys()) {
+ if (pattern.test(key)) {
+ this.cache.delete(key);
+ }
+ }
+ }
+}
+
+// Request tracking to prevent duplicate requests
+class RequestTracker {
+ private pendingRequests: Map> = new Map();
+
+ async trackRequest(key: string, requestFn: () => Promise): Promise {
+ // If request is already pending, return the existing promise
+ if (this.pendingRequests.has(key)) {
+ return this.pendingRequests.get(key)!;
+ }
+
+ // Create new request
+ const requestPromise = requestFn();
+
+ // Track the request
+ this.pendingRequests.set(key, requestPromise);
+
+ try {
+ const result = await requestPromise;
+ return result;
+ } finally {
+ // Remove from tracking when done (success or failure)
+ this.pendingRequests.delete(key);
+ }
+ }
+}
+
+export class APIService {
+ private _cache = new APICache();
+ private _requestTracker = new RequestTracker();
+
+ /**
+ * Submit a new input task to generate a plan
+ * @param inputTask The task description and optional session ID
+ * @returns Promise with the response containing session and plan IDs
+ */
+ async submitInputTask(inputTask: InputTask): Promise {
+ return apiClient.post(API_ENDPOINTS.INPUT_TASK, inputTask);
+ }
+
+ /**
+ * Get all plans, optionally filtered by session ID
+ * @param sessionId Optional session ID to filter plans
+ * @param useCache Whether to use cached data or force fresh fetch
+ * @returns Promise with array of plans with their steps
+ */
+ async getPlans(sessionId?: string, useCache = true): Promise {
+ const cacheKey = `plans_${sessionId || 'all'}`;
+ const params = sessionId ? { session_id: sessionId } : {};
+
+ const fetcher = async () => {
+ const data = await apiClient.get(API_ENDPOINTS.PLANS, { params });
+ if (useCache) {
+ this._cache.set(cacheKey, data, 30000); // Cache for 30 seconds
+ }
+ return data;
+ };
+
+ if (useCache) {
+ return this._requestTracker.trackRequest(cacheKey, fetcher);
+ }
+
+ return fetcher();
+ }
+
+ /**
+ * Get a single plan by plan ID
+ * @param planId Plan ID to fetch
+ * @param useCache Whether to use cached data or force fresh fetch
+ * @returns Promise with the plan and its steps
+ */
+ async getPlanById(planId: string, useCache = true): Promise<{ plan_with_steps: PlanWithSteps; messages: PlanMessage[] }> {
+ const cacheKey = `plan_by_id_${planId}`;
+ const params = { plan_id: planId };
+
+ const fetcher = async () => {
+ const data = await apiClient.get(API_ENDPOINTS.PLANS, { params });
+
+ // The API returns an array, but with plan_id filter it should have only one item
+ if (!data) {
+ throw new Error(`Plan with ID ${planId} not found`);
+ }
+
+ const plan = data[0] as PlanWithSteps;
+ const messages = data[1] || [];
+ if (useCache) {
+ this._cache.set(cacheKey, { plan_with_steps: plan, messages }, 30000); // Cache for 30 seconds
+ }
+ return { plan_with_steps: plan, messages };
+ };
+
+ if (useCache) {
+ const cachedPlan = this._cache.get<{ plan_with_steps: PlanWithSteps; messages: PlanMessage[] }>(cacheKey);
+ //if (cachedPlan) return cachedPlan;
+
+ return this._requestTracker.trackRequest(cacheKey, fetcher);
+ }
+
+ return fetcher();
+ }
+
+ /**
+ * Get a specific plan with its steps
+ * @param sessionId Session ID
+ * @param planId Plan ID
+ * @param useCache Whether to use cached data or force fresh fetch
+ * @returns Promise with the plan and its steps
+ */
+ async getPlanWithSteps(sessionId: string, planId: string, useCache = true): Promise {
+ const cacheKey = `plan_${sessionId}_${planId}`;
+
+ if (useCache) {
+ const cachedPlan = this._cache.get(cacheKey);
+ if (cachedPlan) return cachedPlan;
+ }
+
+ const fetcher = async () => {
+ const plans = await this.getPlans(sessionId, useCache);
+ const plan = plans.find(p => p.id === planId);
+
+ if (!plan) {
+ throw new Error(`Plan with ID ${planId} not found`);
+ }
+
+ if (useCache) {
+ this._cache.set(cacheKey, plan, 30000); // Cache for 30 seconds
+ }
+
+ return plan;
+ };
+
+ if (useCache) {
+ return this._requestTracker.trackRequest(cacheKey, fetcher);
+ }
+
+ return fetcher();
+ }
+
+ /**
+ * Get steps for a specific plan
+ * @param planId Plan ID
+ * @param useCache Whether to use cached data or force fresh fetch
+ * @returns Promise with array of steps
+ */
+ async getSteps(planId: string, useCache = true): Promise {
+ const cacheKey = `steps_${planId}`;
+
+ const fetcher = async () => {
+ const data = await apiClient.get(`${API_ENDPOINTS.STEPS}/${planId}`);
+ if (useCache) {
+ this._cache.set(cacheKey, data, 30000); // Cache for 30 seconds
+ }
+ return data;
+ };
+
+ if (useCache) {
+ return this._requestTracker.trackRequest(cacheKey, fetcher);
+ }
+
+ return fetcher();
+ }
+
+ /**
+ * Update a step with new status and optional feedback
+ * @param sessionId Session ID
+ * @param planId Plan ID
+ * @param stepId Step ID
+ * @param update Update object with status and optional feedback
+ * @returns Promise with the updated step
+ */
+ async updateStep(
+ sessionId: string,
+ planId: string,
+ stepId: string,
+ update: {
+ status: StepStatus;
+ human_feedback?: string;
+ updated_action?: string;
+ }
+ ): Promise {
+ const response = await this.provideStepFeedback(
+ stepId,
+ planId,
+ sessionId,
+ update.status === StepStatus.APPROVED,
+ update.human_feedback,
+ update.updated_action
+ );
+
+ // Invalidate cached data
+ this._cache.invalidate(new RegExp(`^(plan|steps)_${planId}`));
+ this._cache.invalidate(new RegExp(`^plans_`));
+
+ // Get fresh step data
+ const steps = await this.getSteps(planId, false); // Force fresh data
+ const updatedStep = steps.find(step => step.id === stepId);
+
+ if (!updatedStep) {
+ throw new Error(`Step with ID ${stepId} not found after update`);
+ }
+
+ return updatedStep;
+ }
+
+ /**
+ * Provide feedback for a specific step
+ * @param stepId Step ID
+ * @param planId Plan ID
+ * @param sessionId Session ID
+ * @param approved Whether the step is approved
+ * @param humanFeedback Optional human feedback
+ * @param updatedAction Optional updated action
+ * @returns Promise with response object
+ */
+ async provideStepFeedback(
+ stepId: string,
+ planId: string,
+ sessionId: string,
+ approved: boolean,
+ humanFeedback?: string,
+ updatedAction?: string
+ ): Promise<{ status: string; session_id: string; step_id: string }> {
+ const response = await apiClient.post(
+ API_ENDPOINTS.HUMAN_FEEDBACK,
+ {
+ step_id: stepId,
+ plan_id: planId,
+ session_id: sessionId,
+ approved,
+ human_feedback: humanFeedback,
+ updated_action: updatedAction
+ }
+ );
+
+ // Invalidate cached data
+ this._cache.invalidate(new RegExp(`^(plan|steps)_${planId}`));
+ this._cache.invalidate(new RegExp(`^plans_`));
+
+ return response;
+ }
+
+ /**
+ * Approve one or more steps
+ * @param planId Plan ID
+ * @param sessionId Session ID
+ * @param approved Whether the step(s) are approved
+ * @param stepId Optional specific step ID
+ * @param humanFeedback Optional human feedback
+ * @param updatedAction Optional updated action
+ * @returns Promise with response object
+ */
+ async stepStatus(
+ planId: string,
+ sessionId: string,
+ approved: boolean,
+ stepId?: string,
+ ): Promise<{ status: string }> {
+ const response = await apiClient.post(
+ API_ENDPOINTS.APPROVE_STEPS,
+ {
+ step_id: stepId,
+ plan_id: planId,
+ session_id: sessionId,
+ approved
+ }
+ );
+
+ // Invalidate cached data
+ this._cache.invalidate(new RegExp(`^(plan|steps)_${planId}`));
+ this._cache.invalidate(new RegExp(`^plans_`));
+
+ return response;
+ }
+
+ /**
+ * Submit clarification for a plan
+ * @param planId Plan ID
+ * @param sessionId Session ID
+ * @param clarification Clarification text
+ * @returns Promise with response object
+ */
+ async submitClarification(
+ planId: string,
+ sessionId: string,
+ clarification: string
+ ): Promise<{ status: string; session_id: string }> {
+ const clarificationData: HumanClarification = {
+ plan_id: planId,
+ session_id: sessionId,
+ human_clarification: clarification
+ };
+
+ const response = await apiClient.post(
+ API_ENDPOINTS.HUMAN_CLARIFICATION,
+ clarificationData
+ );
+
+ // Invalidate cached data
+ this._cache.invalidate(new RegExp(`^(plan|steps)_${planId}`));
+ this._cache.invalidate(new RegExp(`^plans_`));
+
+ return response;
+ }
+
+ /**
+ * Get agent messages for a session
+ * @param sessionId Session ID
+ * @param useCache Whether to use cached data or force fresh fetch
+ * @returns Promise with array of agent messages
+ */
+ async getAgentMessages(sessionId: string, useCache = true): Promise {
+ const cacheKey = `agent_messages_${sessionId}`;
+
+ const fetcher = async () => {
+ const data = await apiClient.get(`${API_ENDPOINTS.AGENT_MESSAGES}/${sessionId}`);
+ if (useCache) {
+ this._cache.set(cacheKey, data, 30000); // Cache for 30 seconds
+ }
+ return data;
+ };
+
+ if (useCache) {
+ return this._requestTracker.trackRequest(cacheKey, fetcher);
+ }
+
+ return fetcher();
+ }
+
+ /**
+ * Delete all messages
+ * @returns Promise with response object
+ */
+ async deleteAllMessages(): Promise<{ status: string }> {
+ const response = await apiClient.delete(API_ENDPOINTS.MESSAGES);
+
+ // Clear all cached data
+ this._cache.clear();
+
+ return response;
+ }
+
+ /**
+ * Get all messages
+ * @param useCache Whether to use cached data or force fresh fetch
+ * @returns Promise with array of messages
+ */
+ async getAllMessages(useCache = true): Promise {
+ const cacheKey = 'all_messages';
+
+ const fetcher = async () => {
+ const data = await apiClient.get(API_ENDPOINTS.MESSAGES);
+ if (useCache) {
+ this._cache.set(cacheKey, data, 30000); // Cache for 30 seconds
+ }
+ return data;
+ };
+
+ if (useCache) {
+ return this._requestTracker.trackRequest(cacheKey, fetcher);
+ }
+
+ return fetcher();
+ }
+
+ // Utility methods
+
+ /**
+ * Check if a plan is complete (all steps are completed or failed)
+ * @param plan Plan with steps
+ * @returns Boolean indicating if plan is complete
+ */
+ isPlanComplete(plan: PlanWithSteps): boolean {
+ return plan.steps.every(step =>
+ [StepStatus.COMPLETED, StepStatus.FAILED].includes(step.status)
+ );
+ }
+
+ /**
+ * Get steps that are awaiting human feedback
+ * @param plan Plan with steps
+ * @returns Array of steps awaiting feedback
+ */
+ getStepsAwaitingFeedback(plan: PlanWithSteps): Step[] {
+ return plan.steps.filter(step => step.status === StepStatus.AWAITING_FEEDBACK);
+ } /**
+ * Get steps assigned to a specific agent type
+ * @param plan Plan with steps
+ * @param agentType Agent type to filter by
+ * @returns Array of steps for the specified agent
+ */
+ getStepsForAgent(plan: PlanWithSteps, agentType: AgentType): Step[] {
+ return plan.steps.filter(step => step.agent === agentType);
+ }
+
+ /**
+ * Clear all cached data
+ */
+ clearCache(): void {
+ this._cache.clear();
+ }
+
+ /**
+ * Get progress status counts for a plan
+ * @param plan Plan with steps
+ * @returns Object with counts for each step status
+ */
+ getPlanProgressStatus(plan: PlanWithSteps): Record {
+ const result = Object.values(StepStatus).reduce((acc, status) => {
+ acc[status] = 0;
+ return acc;
+ }, {} as Record);
+
+ plan.steps.forEach(step => {
+ result[step.status]++;
+ });
+
+ return result;
+ }
+
+ /**
+ * Get completion percentage for a plan
+ * @param plan Plan with steps
+ * @returns Completion percentage (0-100)
+ */
+ getPlanCompletionPercentage(plan: PlanWithSteps): number {
+ if (!plan.steps.length) return 0;
+
+ const completedSteps = plan.steps.filter(
+ step => [StepStatus.COMPLETED, StepStatus.FAILED].includes(step.status)
+ ).length;
+
+ return Math.round((completedSteps / plan.steps.length) * 100);
+ }
+}
+
+// Export a singleton instance
+export const apiService = new APIService();
diff --git a/src/frontend/src/api/config.tsx b/src/frontend/src/api/config.tsx
new file mode 100644
index 000000000..bf99d97f7
--- /dev/null
+++ b/src/frontend/src/api/config.tsx
@@ -0,0 +1,151 @@
+// src/config.js
+
+import { UserInfo, claim } from "@/models";
+
+
+declare global {
+ interface Window {
+ appConfig?: Record;
+ activeUserId?: string;
+ userInfo?: UserInfo;
+ }
+}
+
+export let API_URL: string | null = null;
+export let USER_ID: string | null = null;
+export let USER_INFO: UserInfo | null = null;
+
+export let config = {
+ API_URL: "http://localhost:8000/api",
+ ENABLE_AUTH: false,
+};
+
+export function setApiUrl(url: string | null) {
+ if (url) {
+ API_URL = url.includes('/api') ? url : `${url}/api`;
+ }
+}
+export function setUserInfoGlobal(userInfo: UserInfo | null) {
+ if (userInfo) {
+ USER_ID = userInfo.user_id || null;
+ USER_INFO = userInfo;
+ }
+}
+export function setEnvData(configData: Record) {
+ if (configData) {
+ config.API_URL = configData.API_URL || "";
+ config.ENABLE_AUTH = configData.ENABLE_AUTH || false;
+ }
+}
+
+export function getConfigData() {
+ if (!config.API_URL || !config.ENABLE_AUTH) {
+ // Check if window.appConfig exists
+ if (window.appConfig) {
+ setEnvData(window.appConfig);
+ }
+ }
+
+ return { ...config };
+}
+export async function getUserInfo(): Promise {
+ try {
+ const response = await fetch("/.auth/me");
+ console.log("Fetching user info from: ", "/.auth/me");
+ console.log("Response ", response);
+ if (!response.ok) {
+ console.log(
+ "No identity provider found. Access to chat will be blocked."
+ );
+ return {} as UserInfo;
+ }
+ const payload = await response.json();
+ console.log("User info payload: ", payload[0]);
+ const userInfo: UserInfo = {
+ access_token: payload[0].access_token || "",
+ expires_on: payload[0].expires_on || "",
+ id_token: payload[0].id_token || "",
+ provider_name: payload[0].provider_name || "",
+ user_claims: payload[0].user_claims || [],
+ user_email: payload[0].user_id || "",
+ user_first_last_name: payload[0].user_claims?.find((claim: claim) => claim.typ === 'name')?.val || "",
+ user_id: payload[0].user_claims?.find((claim: claim) => claim.typ === 'http://schemas.microsoft.com/identity/claims/objectidentifier')?.val || '',
+ };
+ console.log("User info: ", userInfo);
+ return userInfo;
+ } catch (e) {
+ return {} as UserInfo;
+ }
+}
+export function getApiUrl() {
+ if (!API_URL) {
+ // Check if window.appConfig exists
+ if (window.appConfig && window.appConfig.API_URL) {
+ setApiUrl(window.appConfig.API_URL);
+ }
+ }
+
+ if (!API_URL) {
+ console.info('API URL not yet configured');
+ return null;
+ }
+
+ return API_URL;
+}
+export function getUserInfoGlobal() {
+ if (!USER_INFO) {
+ // Check if window.userInfo exists
+ if (window.userInfo) {
+ setUserInfoGlobal(window.userInfo);
+ }
+ }
+
+ if (!USER_INFO) {
+ console.info('User info not yet configured');
+ return null;
+ }
+
+ return USER_INFO;
+}
+
+export function getUserId(): string {
+ // USER_ID = getUserInfoGlobal()?.user_id || null;
+ if (!USER_ID) {
+ USER_ID = getUserInfoGlobal()?.user_id || null;
+ }
+ const userId = USER_ID ?? "00000000-0000-0000-0000-000000000000";
+ return userId;
+}
+
+/**
+ * Build headers with authentication information
+ * @param headers Optional additional headers to merge
+ * @returns Combined headers object with authentication
+ */
+export function headerBuilder(headers?: Record): Record {
+ let userId = getUserId();
+ let defaultHeaders = {
+ "x-ms-client-principal-id": String(userId) || "", // Custom header
+ };
+ return {
+ ...defaultHeaders,
+ ...(headers ? headers : {})
+ };
+}
+export const toBoolean = (value: any): boolean => {
+ if (typeof value !== 'string') {
+ return false;
+ }
+ return value.trim().toLowerCase() === 'true';
+};
+export default {
+ setApiUrl,
+ getApiUrl,
+ toBoolean,
+ getUserId,
+ getConfigData,
+ setEnvData,
+ config,
+ USER_ID,
+ API_URL
+};
\ No newline at end of file
diff --git a/src/frontend/src/api/index.tsx b/src/frontend/src/api/index.tsx
new file mode 100644
index 000000000..462775bee
--- /dev/null
+++ b/src/frontend/src/api/index.tsx
@@ -0,0 +1,5 @@
+// Export our API services and utilities
+export * from './apiClient';
+
+// Unified API service - recommended for all new code
+export { apiService } from './apiService';
diff --git a/src/frontend/src/components/content/HomeInput.tsx b/src/frontend/src/components/content/HomeInput.tsx
new file mode 100644
index 000000000..4e2c140de
--- /dev/null
+++ b/src/frontend/src/components/content/HomeInput.tsx
@@ -0,0 +1,153 @@
+import {
+ Body1Strong,
+ Button,
+ Caption1,
+ Title2,
+} from "@fluentui/react-components";
+import React, { useRef, useEffect, useState } from "react";
+import { useNavigate, useLocation } from "react-router-dom";
+
+import "./../../styles/Chat.css";
+import "../../styles/prism-material-oceanic.css";
+import "./../../styles/HomeInput.css";
+
+import { HomeInputProps, quickTasks, QuickTask } from "../../models/homeInput";
+import { TaskService } from "../../services/TaskService";
+import { NewTaskService } from "../../services/NewTaskService";
+
+import ChatInput from "@/coral/modules/ChatInput";
+import InlineToaster, { useInlineToaster } from "../toast/InlineToaster";
+import PromptCard from "@/coral/components/PromptCard";
+import { Send } from "@/coral/imports/bundleicons";
+
+const HomeInput: React.FC = ({
+ onInputSubmit,
+ onQuickTaskSelect,
+}) => {
+ const [submitting, setSubmitting] = useState(false);
+ const [input, setInput] = useState("");
+
+ const textareaRef = useRef(null);
+ const navigate = useNavigate();
+ const location = useLocation(); // ✅ location.state used to control focus
+ const { showToast, dismissToast } = useInlineToaster();
+
+ useEffect(() => {
+ if (location.state?.focusInput) {
+ textareaRef.current?.focus();
+ }
+ }, [location]);
+
+ const resetTextarea = () => {
+ setInput("");
+ if (textareaRef.current) {
+ textareaRef.current.style.height = "auto";
+ textareaRef.current.focus();
+ }
+ };
+
+ useEffect(() => {
+ const cleanup = NewTaskService.addResetListener(resetTextarea);
+ return cleanup;
+ }, []);
+
+ const handleSubmit = async () => {
+ if (input.trim()) {
+ setSubmitting(true);
+ let id = showToast("Creating a plan", "progress");
+
+ try {
+ const response = await TaskService.submitInputTask(input.trim());
+ setInput("");
+
+ if (textareaRef.current) {
+ textareaRef.current.style.height = "auto";
+ }
+
+ if (response.plan_id && response.plan_id !== null) {
+ showToast("Plan created!", "success");
+ dismissToast(id);
+ navigate(`/plan/${response.plan_id}`);
+ } else {
+ console.log("Invalid plan:", response.status);
+ showToast("Failed to create plan", "error");
+ dismissToast(id);
+ }
+ } catch (error) {
+ console.log("Failed to create plan:", error);
+ dismissToast(id);
+ showToast("Something went wrong", "error");
+ } finally {
+ setInput("");
+ setSubmitting(false);
+ }
+ }
+ };
+
+ const handleQuickTaskClick = (task: QuickTask) => {
+ setInput(task.description);
+ if (textareaRef.current) {
+ textareaRef.current.focus();
+ }
+ onQuickTaskSelect(task.description);
+ };
+
+ useEffect(() => {
+ if (textareaRef.current) {
+ textareaRef.current.style.height = "auto";
+ textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
+ }
+ }, [input]);
+
+ return (
+
+
+
+
+ How can I help?
+
+
+
+ }
+ />
+
+
+
+
+
+
+ Quick tasks
+
+
+
+ {quickTasks.map((task) => (
+
handleQuickTaskClick(task)}
+ disabled={submitting}
+ />
+ ))}
+
+
+
+
+
+ );
+};
+
+export default HomeInput;
diff --git a/src/frontend/src/components/content/PlanChat.tsx b/src/frontend/src/components/content/PlanChat.tsx
new file mode 100644
index 000000000..62cf4dc8e
--- /dev/null
+++ b/src/frontend/src/components/content/PlanChat.tsx
@@ -0,0 +1,187 @@
+import HeaderTools from "@/coral/components/Header/HeaderTools";
+import { Copy, Send } from "@/coral/imports/bundleicons";
+import ChatInput from "@/coral/modules/ChatInput";
+import remarkGfm from "remark-gfm";
+import rehypePrism from "rehype-prism";
+import { AgentType, PlanChatProps, role } from "@/models";
+import {
+ Body1,
+ Button,
+ Spinner,
+ Tag,
+ ToolbarDivider,
+} from "@fluentui/react-components";
+import { DiamondRegular, HeartRegular } from "@fluentui/react-icons";
+import { useEffect, useRef, useState } from "react";
+import ReactMarkdown from "react-markdown";
+import "../../styles/PlanChat.css";
+import "../../styles/Chat.css";
+import "../../styles/prism-material-oceanic.css";
+import { TaskService } from "@/services/TaskService";
+import InlineToaster from "../toast/InlineToaster";
+
+const PlanChat: React.FC = ({
+ planData,
+ input,
+ loading,
+ setInput,
+ submittingChatDisableInput,
+ OnChatSubmit,
+}) => {
+ const messages = planData?.messages || [];
+ const [showScrollButton, setShowScrollButton] = useState(false);
+ const [inputHeight, setInputHeight] = useState(0);
+
+ const messagesContainerRef = useRef(null);
+ const inputContainerRef = useRef(null);
+
+ // Scroll to Bottom useEffect
+
+ useEffect(() => {
+ scrollToBottom();
+ }, [messages]);
+
+ //Scroll to Bottom Buttom
+
+ useEffect(() => {
+ const container = messagesContainerRef.current;
+ if (!container) return;
+
+ const handleScroll = () => {
+ const { scrollTop, scrollHeight, clientHeight } = container;
+ setShowScrollButton(scrollTop + clientHeight < scrollHeight - 100);
+ };
+
+ container.addEventListener("scroll", handleScroll);
+ return () => container.removeEventListener("scroll", handleScroll);
+ }, []);
+
+ useEffect(() => {
+ if (inputContainerRef.current) {
+ setInputHeight(inputContainerRef.current.offsetHeight);
+ }
+ }, [input]); // or [inputValue, submittingChatDisableInput]
+
+
+
+ const scrollToBottom = () => {
+ messagesContainerRef.current?.scrollTo({
+ top: messagesContainerRef.current.scrollHeight,
+ behavior: "smooth",
+ });
+ setShowScrollButton(false);
+ };
+
+ if (!planData) return ;
+ return (
+
+
+
+ {messages.map((msg, index) => {
+ const isHuman = msg.source === AgentType.HUMAN;
+
+ return (
+
+ {!isHuman && (
+
+
+
+ {TaskService.cleanTextToSpaces(msg.source)}
+
+
+ BOT
+
+
+
+ )}
+
+
+
+
+ {TaskService.cleanHRAgent(msg.content) || ""}
+
+
+ {!isHuman && (
+
+
+
+
+ msg.content &&
+ navigator.clipboard.writeText(msg.content)
+ }
+ title="Copy Response"
+ appearance="subtle"
+ style={{ height: 28, width: 28 }}
+ icon={ }
+ />
+
+
+
+
} appearance="filled" size="extra-small">
+ Sample data for demonstration purposes only.
+
+
+
+ )}
+
+
+
+ );
+ })}
+
+
+
+ {showScrollButton && (
+
+ Back to bottom
+
+
+ )}
+
+
+
+ OnChatSubmit(input)}
+ disabledChat={
+ planData.enableChat ? submittingChatDisableInput : true
+ }
+ placeholder="Add more info to this task..."
+ >
+ OnChatSubmit(input)}
+ icon={ }
+ disabled={planData.enableChat ? submittingChatDisableInput : true}
+ />
+
+
+
+
+ );
+};
+
+export default PlanChat;
diff --git a/src/frontend/src/components/content/PlanPanelLeft.tsx b/src/frontend/src/components/content/PlanPanelLeft.tsx
new file mode 100644
index 000000000..5e0d9f7e3
--- /dev/null
+++ b/src/frontend/src/components/content/PlanPanelLeft.tsx
@@ -0,0 +1,157 @@
+import PanelLeft from "@/coral/components/Panels/PanelLeft";
+import PanelLeftToolbar from "@/coral/components/Panels/PanelLeftToolbar";
+import {
+ Body1Strong,
+ Button,
+ Subtitle1,
+ Subtitle2,
+ Toast,
+ ToastBody,
+ ToastTitle,
+ Tooltip,
+ useToastController,
+} from "@fluentui/react-components";
+import {
+ Add20Regular,
+ ChatAdd20Regular,
+ ErrorCircle20Regular,
+} from "@fluentui/react-icons";
+import TaskList from "./TaskList";
+import { useCallback, useEffect, useState } from "react";
+import { useNavigate, useParams } from "react-router-dom";
+import { PlanPanelLefProps, PlanWithSteps, Task, UserInfo } from "@/models";
+import { apiService } from "@/api";
+import { TaskService } from "@/services";
+import MsftColor from "@/coral/imports/MsftColor";
+import ContosoLogo from "../../coral/imports/ContosoLogo";
+import "../../styles/PlanPanelLeft.css";
+import PanelFooter from "@/coral/components/Panels/PanelFooter";
+import PanelUserCard from "../../coral/components/Panels/UserCard";
+import { getUserInfoGlobal } from "@/api/config";
+
+const PlanPanelLeft: React.FC = ({ reloadTasks }) => {
+ const { dispatchToast } = useToastController("toast");
+ const navigate = useNavigate();
+ const { planId } = useParams<{ planId: string }>();
+
+ const [inProgressTasks, setInProgressTasks] = useState([]);
+ const [completedTasks, setCompletedTasks] = useState([]);
+ const [plans, setPlans] = useState(null);
+ const [plansLoading, setPlansLoading] = useState(false);
+ const [plansError, setPlansError] = useState(null);
+ const [userInfo, setUserInfo] = useState(
+ getUserInfoGlobal()
+ );
+ // Fetch plans
+ const loadPlansData = useCallback(async (forceRefresh = false) => {
+ try {
+ setPlansLoading(true);
+ setPlansError(null);
+ const plansData = await apiService.getPlans(undefined, !forceRefresh);
+ setPlans(plansData);
+ } catch (error) {
+ console.log("Failed to load plans:", error);
+ setPlansError(
+ error instanceof Error ? error : new Error("Failed to load plans")
+ );
+ } finally {
+ setPlansLoading(false);
+ }
+ }, []);
+
+ useEffect(() => {
+ loadPlansData();
+ }, [loadPlansData]);
+
+ useEffect(() => {
+ if (plans) {
+ const { inProgress, completed } =
+ TaskService.transformPlansToTasks(plans);
+ setInProgressTasks(inProgress);
+ setCompletedTasks(completed);
+ }
+ }, [plans]);
+
+ useEffect(() => {
+ if (plansError) {
+ dispatchToast(
+
+
+
+ Failed to load tasks
+
+ {plansError.message}
+ ,
+ { intent: "error" }
+ );
+ }
+ }, [plansError, dispatchToast]);
+
+ // Get the session_id that matches the current URL's planId
+ const selectedTaskId =
+ plans?.find((plan) => plan.id === planId)?.session_id ?? null;
+
+ const handleTaskSelect = useCallback(
+ (taskId: string) => {
+ const selectedPlan = plans?.find(
+ (plan: PlanWithSteps) => plan.session_id === taskId
+ );
+ if (selectedPlan) {
+ navigate(`/plan/${selectedPlan.id}`);
+ }
+ },
+ [plans, navigate]
+ );
+
+ return (
+
+
+ }
+ >
+
+
+
+
+ navigate("/", { state: { focusInput: true } })}
+ tabIndex={0} // ✅ allows tab focus
+ role="button" // ✅ announces as button
+ onKeyDown={(e) => {
+ if (e.key === "Enter" || e.key === " ") {
+ e.preventDefault();
+ navigate("/", { state: { focusInput: true } });
+ }
+ }}
+ >
+
+
+
+
New task
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default PlanPanelLeft;
diff --git a/src/frontend/src/components/content/PlanPanelRight.tsx b/src/frontend/src/components/content/PlanPanelRight.tsx
new file mode 100644
index 000000000..671337f97
--- /dev/null
+++ b/src/frontend/src/components/content/PlanPanelRight.tsx
@@ -0,0 +1,36 @@
+import React from "react";
+import PanelRight from "@/coral/components/Panels/PanelRight";
+import TaskDetails from "./TaskDetails";
+import { TaskDetailsProps } from "@/models";
+
+const PlanPanelRight: React.FC = ({
+ planData,
+ loading,
+ submittingChatDisableInput,
+ OnApproveStep,
+ processingSubtaskId
+}) => {
+ if (!planData) return null;
+
+ return (
+
+
+
+
+
+
+ );
+};
+
+export default PlanPanelRight;
diff --git a/src/frontend/src/components/content/TaskDetails.tsx b/src/frontend/src/components/content/TaskDetails.tsx
new file mode 100644
index 000000000..9026339c3
--- /dev/null
+++ b/src/frontend/src/components/content/TaskDetails.tsx
@@ -0,0 +1,220 @@
+// TaskDetails.tsx - Merged TSX + Styles
+
+import { HumanFeedbackStatus, Step, TaskDetailsProps } from "@/models";
+import {
+ Text,
+ Avatar,
+ Body1,
+ Body1Strong,
+ Caption1,
+ Button,
+ Tooltip,
+} from "@fluentui/react-components";
+import {
+ Dismiss20Regular,
+ CheckmarkCircle20Filled,
+ DismissCircle20Filled,
+ Checkmark20Regular,
+ CircleHint20Filled,
+} from "@fluentui/react-icons";
+import React, { useState } from "react";
+import { TaskService } from "@/services";
+import PanelRightToolbar from "@/coral/components/Panels/PanelRightToolbar";
+import "../../styles/TaskDetails.css";
+import ProgressCircle from "@/coral/components/Progress/ProgressCircle";
+
+const TaskDetails: React.FC = ({
+ planData,
+ loading,
+ OnApproveStep,
+}) => {
+ const [steps, setSteps] = useState(planData.steps || []);
+ const [completedCount, setCompletedCount] = useState(
+ planData?.plan.completed || 0
+ );
+ const [total, setTotal] = useState(planData?.plan.total_steps || 1);
+ const [progress, setProgress] = useState(
+ (planData?.plan.completed || 0) / (planData?.plan.total_steps || 1)
+ );
+ const agents = planData?.agents || [];
+
+ const renderStatusIcon = (status: string) => {
+ switch (status) {
+ case "completed":
+ case "accepted":
+ return ;
+
+ case "rejected":
+ return ;
+ case "planned":
+ default:
+ return ;
+ }
+ };
+ // Pre-step function for approval
+ const preOnApproved = async (step: Step) => {
+ try {
+ // Update the specific step's human_approval_status
+ const updatedStep = {
+ ...step,
+ human_approval_status: "accepted" as HumanFeedbackStatus,
+ };
+
+ // Create a new array with the updated step
+ const updatedSteps = steps.map((s) =>
+ s.id === step.id ? updatedStep : s
+ );
+
+ // Update local state to reflect changes immediately
+
+ setSteps(updatedSteps);
+ setCompletedCount(completedCount + 1); // Increment completed count
+ setProgress((completedCount + 1) / total); // Update progress
+ // Then call the main approval function
+ // This could be your existing OnApproveStep function that handles API calls, etc.
+ await OnApproveStep(updatedStep, total, completedCount + 1, true);
+ } catch (error) {
+ console.log("Error in pre-approval step:", error);
+ throw error; // Re-throw to allow caller to handle
+ }
+ };
+
+ // Pre-step function for rejection
+ const preOnRejected = async (step: Step) => {
+ try {
+ // Update the specific step's human_approval_status
+ const updatedStep = {
+ ...step,
+ human_approval_status: "rejected" as HumanFeedbackStatus,
+ };
+
+ // Create a new array with the updated step
+ const updatedSteps = steps.map((s) =>
+ s.id === step.id ? updatedStep : s
+ );
+
+ // Update local state to reflect changes immediately
+ setSteps(updatedSteps);
+ setCompletedCount(completedCount + 1); // Increment completed count
+ setProgress((completedCount + 1) / total); // Update progress
+ // Then call the main rejection function
+ // This could be your existing OnRejectStep function that handles API calls, etc.
+ await OnApproveStep(updatedStep, total, completedCount + 1, false);
+ } catch (error) {
+ console.log("Error in pre-rejection step:", error);
+ throw error; // Re-throw to allow caller to handle
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+ {planData.plan.initial_goal}
+
+
+ {completedCount} of {total} completed
+
+
+
+
+
+
+ {steps.map((step) => {
+ const { description, functionOrDetails } =
+ TaskService.splitSubtaskAction(step.action);
+ const canInteract = planData.enableStepButtons;
+
+ return (
+
+
+ {renderStatusIcon(step.human_approval_status || step.status)}
+
+
+
+ {description}{" "}
+ {functionOrDetails && (
+ {functionOrDetails}
+ )}
+
+
+ {step.human_approval_status !== "accepted" &&
+ step.human_approval_status !== "rejected" && (
+ <>
+ }
+ appearance="subtle"
+ onClick={
+ canInteract
+ ? () => preOnApproved(step)
+ : undefined
+ }
+ className={
+ canInteract
+ ? "task-details-action-button"
+ : "task-details-action-button-disabled"
+ }
+ />
+
+
+
+ }
+ appearance="subtle"
+ onClick={
+ canInteract
+ ? () => preOnRejected(step)
+ : undefined
+ }
+ className={
+ canInteract
+ ? "task-details-action-button"
+ : "task-details-action-button-disabled"
+ }
+ />
+ >
+
+ )}
+
+
+
+ );
+ })}
+
+
+
+
+
+ Agents
+
+
+ {agents.map((agent) => (
+
+
+
+
+ {TaskService.cleanTextToSpaces(agent)}
+
+
+
+ ))}
+
+
+
+ );
+};
+
+export default TaskDetails;
diff --git a/src/frontend/src/components/content/TaskList.tsx b/src/frontend/src/components/content/TaskList.tsx
new file mode 100644
index 000000000..a4c8afac1
--- /dev/null
+++ b/src/frontend/src/components/content/TaskList.tsx
@@ -0,0 +1,109 @@
+import {
+ Button,
+ Menu,
+ MenuTrigger,
+ Caption1,
+ Skeleton,
+ SkeletonItem,
+} from "@fluentui/react-components";
+import { MoreHorizontal20Regular } from "@fluentui/react-icons";
+import React from "react";
+import "../../styles/TaskList.css";
+import { Task, TaskListProps } from "@/models";
+import CoralAccordion from "@/coral/components/CoralAccordion/CoralAccordion";
+import CoralAccordionItem from "@/coral/components/CoralAccordion/CoralAccordionItem";
+import CoralAccordionHeader from "@/coral/components/CoralAccordion/CoralAccordionHeader";
+import CoralAccordionPanel from "@/coral/components/CoralAccordion/CoralAccordionPanel";
+
+const TaskList: React.FC = ({
+ inProgressTasks,
+ completedTasks,
+ onTaskSelect,
+ loading,
+ selectedTaskId,
+}) => {
+ const renderTaskItem = (task: Task) => {
+ const isActive = task.id === selectedTaskId;
+
+ return (
+ onTaskSelect(task.id)}
+ onKeyDown={(e) => {
+ if (e.key === "Enter" || e.key === " ") {
+ e.preventDefault();
+ onTaskSelect(task.id);
+ }
+ }}
+ >
+
+
+
+
+ {task.name}
+
+
+
+ {task.date && (
+
{task.date}
+ )}
+
+
+
+ }
+ onClick={(e: React.MouseEvent) => e.stopPropagation()}
+ className="task-menu-button"
+ />
+
+
+
+ );
+ };
+
+ const renderSkeleton = (key: string) => (
+
+ );
+
+ return (
+
+
+ In progress
+
+
+ {loading && inProgressTasks.length === 0
+ ? [...Array(3)].map((_, i) =>
+ renderSkeleton(`inprogress-skel-${i}`)
+ )
+ : inProgressTasks.map(renderTaskItem)}
+
+
+
+
+ Completed
+
+
+ {loading && completedTasks.length === 0
+ ? [...Array(2)].map((_, i) => renderSkeleton(`completed-skel-${i}`))
+ : completedTasks.map(renderTaskItem)}
+
+
+
+ );
+};
+
+export default TaskList;
diff --git a/src/frontend/src/components/content/contoso.tsx b/src/frontend/src/components/content/contoso.tsx
new file mode 100644
index 000000000..0a72809c5
--- /dev/null
+++ b/src/frontend/src/components/content/contoso.tsx
@@ -0,0 +1,18 @@
+const ContosoLogo: React.FC = () => {
+ return (
+
+
+
+
+
+
+ );
+}
+
+export default ContosoLogo;
\ No newline at end of file
diff --git a/src/frontend/src/components/toast/InlineToaster.tsx b/src/frontend/src/components/toast/InlineToaster.tsx
new file mode 100644
index 000000000..769611870
--- /dev/null
+++ b/src/frontend/src/components/toast/InlineToaster.tsx
@@ -0,0 +1,195 @@
+import React, { useEffect, useState } from "react";
+import {
+ CheckmarkCircle20Regular,
+ Info20Regular,
+ Warning20Regular,
+ DismissCircle20Regular,
+ Dismiss20Regular,
+} from "@fluentui/react-icons";
+import { Body1, Button, Spinner } from "@fluentui/react-components";
+
+// Toast type
+export type ToastIntent = "info" | "success" | "warning" | "error" | "progress";
+
+type Toast = {
+ id: number;
+ content: React.ReactNode;
+ intent: ToastIntent;
+ visible: boolean;
+ dismissible?: boolean;
+};
+
+let _setToasts: React.Dispatch> | null = null;
+
+export const useInlineToaster = () => {
+ const showToast = (
+ content: React.ReactNode,
+ intent: ToastIntent = "info",
+ options?: {
+ dismissible?: boolean;
+ timeoutMs?: number | null;
+ }
+ ) => {
+ const id = Date.now();
+ const timeout = options?.timeoutMs ?? (intent === "progress" ? null : 3000);
+
+ if (_setToasts) {
+ _setToasts((prev) => [
+ ...prev,
+ {
+ id,
+ content,
+ intent,
+ visible: false,
+ dismissible: options?.dismissible,
+ },
+ ]);
+
+ setTimeout(() => {
+ _setToasts?.((prev) =>
+ prev.map((t) => (t.id === id ? { ...t, visible: true } : t))
+ );
+ }, 10);
+
+ if (timeout !== null) {
+ setTimeout(() => {
+ _setToasts?.((prev) =>
+ prev.map((t) => (t.id === id ? { ...t, visible: false } : t))
+ );
+ }, timeout);
+
+ setTimeout(() => {
+ _setToasts?.((prev) => prev.filter((t) => t.id !== id));
+ }, timeout + 500);
+ }
+ }
+
+ return id;
+ };
+
+ const dismissToast = (id: number) => {
+ _setToasts?.((prev) =>
+ prev.map((t) => (t.id === id ? { ...t, visible: false } : t))
+ );
+ setTimeout(() => {
+ _setToasts?.((prev) => prev.filter((t) => t.id !== id));
+ }, 500);
+ };
+
+ return { showToast, dismissToast };
+};
+
+const getIconForIntent = (intent: ToastIntent) => {
+ switch (intent) {
+ case "success":
+ return ;
+ case "info":
+ return ;
+ case "warning":
+ return ;
+ case "error":
+ return ;
+ case "progress":
+ return ;
+ default:
+ return null;
+ }
+};
+
+const InlineToaster: React.FC = () => {
+ const [toasts, setToasts] = useState([]);
+
+ useEffect(() => {
+ _setToasts = setToasts;
+ return () => {
+ _setToasts = null;
+ };
+ }, []);
+
+ return (
+
+ {toasts.map((toast) => (
+
+ {getIconForIntent(toast.intent)}
+
+
+ {toast.content}
+
+
+ {(toast.dismissible || toast.intent === "progress") && (
+
+ _setToasts?.((prev) => prev.filter((t) => t.id !== toast.id))
+ }
+ style={{
+ background: "transparent",
+ border: "none",
+ cursor: "pointer",
+ color: "var(--colorNeutralForeground1)",
+ display: "flex",
+ alignItems: "center",
+ justifyContent: "center",
+ flexShrink: 0,
+ }}
+ aria-label="Dismiss"
+ icon={ }
+ appearance="subtle"
+ shape="circular"
+ >
+
+
+
+ )}
+
+ ))}
+
+ );
+};
+
+export default InlineToaster;
diff --git a/src/frontend/src/coral/SYSTEM_OVERVIEW.md b/src/frontend/src/coral/SYSTEM_OVERVIEW.md
new file mode 100644
index 000000000..271383427
--- /dev/null
+++ b/src/frontend/src/coral/SYSTEM_OVERVIEW.md
@@ -0,0 +1,38 @@
+# coral.config
+
+**Coral Config** defines the application’s structural baseline — component scaffolding, prebuilt modules, import bundling, and system-wide utilities.
+
+> This folder is not intended for feature development.
+
+---
+
+## What Lives Here
+
+- `components/` – Stateless layout primitives like `Header`, `PanelLeft`, `PanelRight`, `Content`, etc. These are styled and functional, but intentionally generic.
+- `modules/` – Composite UI blocks that encapsulate common layouts and logic (e.g., a full-width `ChatPanel`, or a `PanelLeft` with navigation baked in). These are production-ready and reusable
+- `imports/` – Centralized icon and asset imports to streamline DX and reduce boilerplate.
+- `eventbus.ts` – Shared event system for cross-component communication.
+- `PanelRegistry.ts` – Central config for registering and referencing dynamic panel zones.
+
+---
+
+## When Should You Modify This?
+
+Only when you're:
+- Creating or updating shared UI primitives
+- Building new reusable modules
+- Extending foundational architecture
+
+Avoid editing directly unless your change impacts system-level behavior. When in doubt, route it through the Coral steward or log it in the dev sync.
+
+---
+
+## Design Philosophy
+
+Coral isolates **infrastructure from implementation** — keeping base components clean and predictable, while enabling rapid development through composable modules.
+
+This layer isn’t for experiments. It’s for the architecture that lets experiments happen without breaking production.
+
+---
+
+🐙
\ No newline at end of file
diff --git a/src/frontend/src/coral/components/Content/Chat.css b/src/frontend/src/coral/components/Content/Chat.css
new file mode 100644
index 000000000..66da2d143
--- /dev/null
+++ b/src/frontend/src/coral/components/Content/Chat.css
@@ -0,0 +1,249 @@
+Chat container and layout
+.chat-container {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ background-color: var(--colorNeutralBackground1);
+}
+
+/* Messages area */
+.messages-container {
+ flex: 1;
+ overflow-y: auto;
+ padding: 24px;
+}
+
+/* Input area */
+.input-wrapper {
+ position: sticky;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background-color: var(--colorNeutralBackground1);
+ border-top: 1px solid var(--colorNeutralStroke1);
+ padding: 16px 24px;
+}
+
+.input-container {
+ display: flex;
+ gap: 8px;
+ align-items: flex-start;
+ max-width: 800px;
+ margin: 0 auto;
+}
+
+/* Message styling */
+.message {
+ display: flex;
+ flex-direction: column;
+ margin-bottom: 24px;
+ max-width: 800px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.message-content {
+ line-height: 1.5;
+ white-space: pre-wrap;
+ padding: 12px 16px;
+ border-radius: 8px;
+ margin-top: 4px;
+}
+
+.message-header {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 4px;
+}
+
+.message-role {
+ font-weight: 600;
+ font-size: 14px;
+}
+
+.bot-tag {
+ font-size: 11px;
+ color: var(--colorNeutralForeground2);
+ background-color: var(--colorNeutralBackground2);
+ padding: 2px 6px;
+ border-radius: 4px;
+ text-transform: uppercase;
+}
+
+/* User message */
+.message.user .message-content {
+ background-color: var(--colorBrandBackground);
+ color: var(--colorNeutralForegroundInverted);
+ align-self: flex-end;
+}
+
+/* Assistant/bot message */
+.message.assistant .message-content {
+ background-color: var(--colorNeutralBackground2);
+ color: var(--colorNeutralForeground1);
+ align-self: flex-start;
+}
+
+/* Message actions */
+.message-actions {
+ display: flex;
+ gap: 8px;
+ margin-top: 8px;
+}
+
+.action-button {
+ background: none;
+ border: none;
+ cursor: pointer;
+ color: var(--colorNeutralForeground3);
+ padding: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 4px;
+}
+
+.action-button:hover {
+ background-color: var(--colorNeutralBackground2);
+}
+
+.message-content p {
+ margin: 0 0 16px 0;
+}
+
+.message-content p:last-child {
+ margin-bottom: 0;
+}
+
+/* System message / action */
+.message.system {
+ display: flex;
+ justify-content: center;
+ margin: 16px 0;
+}
+
+.system-message {
+ background-color: var(--colorNeutralBackground2);
+ padding: 8px 16px;
+ border-radius: 16px;
+ font-size: 14px;
+ color: var(--colorNeutralForeground2);
+ display: inline-block;
+}
+
+/* Code block styling */
+.message-content pre {
+ background-color: rgba(0, 0, 0, 0.05);
+ padding: 16px;
+ border-radius: 4px;
+ overflow-x: auto;
+ margin: 16px 0;
+}
+
+.message.assistant .message-content pre {
+ background-color: rgba(0, 0, 0, 0.1);
+}
+
+.message.user .message-content pre {
+ background-color: rgba(255, 255, 255, 0.1);
+}
+
+.message-content code {
+ font-family: var(--fontFamilyMonospace);
+ font-size: 14px;
+}
+
+/* Typing indicator */
+.typing-indicator {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ color: var(--colorNeutralForeground2);
+ font-size: 14px;
+}
+
+/* Scroll to bottom button */
+.scroll-button {
+ position: fixed;
+ bottom: 100px;
+ right: 24px;
+ z-index: 1;
+}
+
+/* Input field */
+.input-field {
+ flex: 1;
+ padding: 12px 16px;
+ border: 1px solid var(--colorNeutralStroke1);
+ border-radius: 8px;
+ resize: none;
+ font-family: var(--fontFamilyBase);
+ font-size: var(--fontSizeBase300);
+ line-height: 1.5;
+ background-color: var(--colorNeutralBackground1);
+ color: var(--colorNeutralForeground1);
+ min-height: 44px;
+ overflow-y: auto;
+ max-height: 200px;
+}
+
+.input-field:focus {
+ outline: none;
+ border-color: var(--colorBrandStroke1);
+}
+
+.input-field::placeholder {
+ color: var(--colorNeutralForeground3);
+}
+
+/* Send button */
+.send-button {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ border-radius: 8px;
+ background-color: var(--colorBrandBackground);
+ color: var(--colorNeutralForegroundInverted);
+ border: none;
+ cursor: pointer;
+ font-size: 16px;
+}
+
+.send-button svg {
+ width: 20px;
+ height: 20px;
+ fill: currentColor;
+}
+
+.send-button:disabled {
+ background-color: var(--colorNeutralBackground3);
+ color: var(--colorNeutralForeground3);
+ cursor: not-allowed;
+}
+
+/* Input footer */
+.input-footer {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 8px;
+ padding: 0 16px;
+ font-size: 12px;
+ color: var(--colorNeutralForeground3);
+}
+
+/* Markdown content */
+.markdown-content {
+ width: 100%;
+}
+
+.markdown-content > *:first-child {
+ margin-top: 0;
+}
+
+.markdown-content > *:last-child {
+ margin-bottom: 0;
+}
\ No newline at end of file
diff --git a/src/frontend/src/coral/components/Content/Content.tsx b/src/frontend/src/coral/components/Content/Content.tsx
new file mode 100644
index 000000000..2eb5d3d5d
--- /dev/null
+++ b/src/frontend/src/coral/components/Content/Content.tsx
@@ -0,0 +1,52 @@
+import React, { useState, ReactNode, ReactElement } from "react";
+import PanelToolbar from "../Panels/PanelLeftToolbar.js"; // Import to identify toolbar
+
+interface ContentProps {
+ children?: ReactNode;
+}
+
+const Content: React.FC = ({ children }) => {
+ const childrenArray = React.Children.toArray(children) as ReactElement[];
+ const toolbar = childrenArray.find(
+ (child) => React.isValidElement(child) && child.type === PanelToolbar
+ );
+ const content = childrenArray.filter(
+ (child) => !(React.isValidElement(child) && child.type === PanelToolbar)
+ );
+
+ return (
+
+ {toolbar &&
{toolbar}
}
+
+
+ {content}
+
+
+ );
+};
+
+export default Content;
diff --git a/src/frontend/src/coral/components/Content/ContentToolbar.tsx b/src/frontend/src/coral/components/Content/ContentToolbar.tsx
new file mode 100644
index 000000000..ec5d75f43
--- /dev/null
+++ b/src/frontend/src/coral/components/Content/ContentToolbar.tsx
@@ -0,0 +1,76 @@
+import React, { ReactNode } from "react";
+import { Body1Strong } from "@fluentui/react-components";
+
+interface ContentToolbarProps {
+ panelIcon?: ReactNode;
+ panelTitle?: string | null;
+ children?: ReactNode;
+}
+
+const ContentToolbar: React.FC = ({
+ panelIcon,
+ panelTitle,
+ children,
+}) => {
+ return (
+
+ {(panelIcon || panelTitle) && (
+
+ {panelIcon && (
+
+ {panelIcon}
+
+ )}
+ {panelTitle && (
+
+ {panelTitle}
+
+ )}
+
+ )}
+
+ {children}
+
+
+ );
+};
+
+export default ContentToolbar;
diff --git a/src/frontend/src/coral/components/Content/README.md b/src/frontend/src/coral/components/Content/README.md
new file mode 100644
index 000000000..443aa15f8
--- /dev/null
+++ b/src/frontend/src/coral/components/Content/README.md
@@ -0,0 +1,330 @@
+# Content Components
+
+The Content components create the main workspace of your Coral application, providing the primary display area for your application's features and interfaces.
+
+## Components Overview
+
+- `Content`: Main container for application content
+- `ContentToolbar`: Header area for the content section with title and controls
+- `Chat`: Component for displaying and interacting with chat interfaces
+
+## Phase 1: UI Customization
+
+### Content Component
+
+The `Content` component creates the main workspace area:
+
+```jsx
+
+ } />
+ {/* Main content goes here */}
+
+```
+
+Customization options:
+
+```jsx
+
+ {/* Content */}
+
+```
+
+### ContentToolbar Component
+
+The `ContentToolbar` component provides a header for the content area:
+
+```jsx
+ }
+>
+ {/* Optional toolbar actions */}
+ } />
+
+ } />
+
+```
+
+### Chat Component
+
+The `Chat` component provides a conversation interface:
+
+```jsx
+
+ {/* Optional chat actions */}
+ } />
+ } />
+
+```
+
+## Phase 2: Data Population (Mock Data)
+
+The Content components can be populated with dynamic data to display various types of content.
+
+### Chat with Mock Messages
+
+```jsx
+import { useState } from 'react';
+
+function MockChat() {
+ // Mock chat history
+ const initialHistory = [
+ { role: 'assistant', content: 'Hello! How can I help you today?' },
+ { role: 'user', content: 'I need information about your services.' },
+ { role: 'assistant', content: 'We offer a variety of services including...' },
+ ];
+
+ const [messages, setMessages] = useState(initialHistory);
+
+ // Mock send message handler
+ const handleSendMessage = async (input, history) => {
+ // In a real app, this would call a service
+ const response = `Thanks for your message: "${input}". This is a mock response.`;
+ setMessages([...history, { role: 'user', content: input }, { role: 'assistant', content: response }]);
+ return response;
+ };
+
+ // Mock load history handler
+ const handleLoadHistory = (userId) => {
+ // In a real app, this would fetch from a service
+ console.log(`Loading history for user ${userId}`);
+ return Promise.resolve(initialHistory);
+ };
+
+ // Mock clear history handler
+ const handleClearHistory = (userId) => {
+ // In a real app, this would call a service
+ console.log(`Clearing history for user ${userId}`);
+ setMessages([]);
+ return Promise.resolve();
+ };
+
+ return (
+
+ }>
+ } onClick={() => handleClearHistory('user123')} />
+
+
+
+ } />
+
+
+ );
+}
+```
+
+### Content with Custom Interface
+
+```jsx
+import { useState } from 'react';
+import {
+ Card,
+ CardHeader,
+ CardPreview,
+ CardFooter,
+ Button,
+ Text
+} from '@fluentui/react-components';
+
+function CustomContent() {
+ // Mock data
+ const items = [
+ { id: '1', title: 'Item One', description: 'Description for item one', image: 'item1.jpg' },
+ { id: '2', title: 'Item Two', description: 'Description for item two', image: 'item2.jpg' },
+ { id: '3', title: 'Item Three', description: 'Description for item three', image: 'item3.jpg' },
+ ];
+
+ return (
+
+ } />
+
+
+ {items.map(item => (
+
+ {item.title}} />
+
+
+
+ {item.description}
+
+ View Details
+
+
+ ))}
+
+
+ );
+}
+```
+
+## Phase 3: Service Integration & Event Handling
+
+Connect your content components to services and event handling to make them fully interactive.
+
+### Chat with Real Service
+
+```jsx
+import { useState, useEffect } from 'react';
+import { chatService } from '../../services/chatService';
+
+function ServiceConnectedChat() {
+ const [userId] = useState('user123');
+ const [messages, setMessages] = useState([]);
+
+ // Load initial history
+ useEffect(() => {
+ chatService.getUserHistory(userId)
+ .then(history => setMessages(history))
+ .catch(err => console.error('Failed to load chat history:', err));
+ }, [userId]);
+
+ // Send message handler
+ const handleSendMessage = async (input, history) => {
+ try {
+ // Get last conversation ID if available
+ const lastAssistantMessage = history.filter(msg => msg.role === 'assistant').pop();
+ const conversationId = lastAssistantMessage ? (lastAssistantMessage).conversation_id : undefined;
+
+ // Call the service
+ const response = await chatService.sendMessage(userId, input, conversationId);
+ return response.assistant_response;
+ } catch (error) {
+ console.error('Error sending message:', error);
+ return "Sorry, there was an error processing your request.";
+ }
+ };
+
+ // Load history handler
+ const handleLoadHistory = async (id) => {
+ try {
+ return await chatService.getUserHistory(id);
+ } catch (error) {
+ console.error('Error loading history:', error);
+ return [];
+ }
+ };
+
+ // Clear history handler
+ const handleClearHistory = async (id) => {
+ try {
+ await chatService.clearChatHistory(id);
+ setMessages([]);
+ } catch (error) {
+ console.error('Error clearing history:', error);
+ }
+ };
+
+ return (
+
+ } />
+
+
+ } />
+ } />
+
+
+ );
+}
+```
+
+### EventBus Integration
+
+```jsx
+import { useState, useEffect } from 'react';
+import eventBus from '../eventbus';
+
+function EventAwareContent() {
+ const [selectedItem, setSelectedItem] = useState(null);
+
+ useEffect(() => {
+ // Subscribe to item selection events
+ const handleItemSelected = (item) => {
+ setSelectedItem(item);
+ };
+
+ eventBus.on('itemSelected', handleItemSelected);
+
+ // Cleanup
+ return () => {
+ eventBus.off('itemSelected', handleItemSelected);
+ };
+ }, []);
+
+ return (
+
+ } />
+
+ {selectedItem ? (
+
+
{selectedItem.name}
+
ID: {selectedItem.id}
+
Category: {selectedItem.category}
+ {/* More item details */}
+
+ ) : (
+
+
Select an item from the left panel to view details
+
+ )}
+
+ );
+}
+```
+
+## Props API
+
+### Content Props
+
+This component primarily acts as a container and accepts standard React props like:
+- `children`: React nodes to render inside the content area
+- `className`: CSS class to apply to the content area
+- `style`: Inline styles to apply to the content area
+
+### ContentToolbar Props
+
+| Prop | Type | Default | Description |
+|------|------|---------|-------------|
+| panelTitle | string | "" | Title text to display in the toolbar |
+| panelIcon | ReactNode | null | Icon to display next to the title |
+| children | ReactNode | null | Additional content for the toolbar (buttons, etc.) |
+
+### Chat Props
+
+| Prop | Type | Default | Description |
+|------|------|---------|-------------|
+| userId | string | required | Identifier for the current user |
+| onSendMessage | function | required | Function to call when sending a message: (input, history) => Promise |
+| onLoadHistory | function | required | Function to call when loading chat history: (userId) => Promise |
+| onClearHistory | function | required | Function to call when clearing chat history: (userId) => Promise |
+| children | ReactNode | null | Additional content for chat actions (buttons, etc.) |
+
+## Best Practices
+
+1. **Maintain Focus**: Keep the main content area focused on the primary task.
+2. **Responsive Design**: Ensure content adapts to different screen sizes.
+3. **Loading States**: Show loading indicators when fetching data.
+4. **Error Handling**: Implement user-friendly error messages.
+5. **Accessibility**: Maintain proper heading hierarchy and ensure all interactive elements are accessible.
+6. **Performance**: For content with large data sets, implement pagination or virtualization.
\ No newline at end of file
diff --git a/src/frontend/src/coral/components/CoralAccordion/CoralAccordion.tsx b/src/frontend/src/coral/components/CoralAccordion/CoralAccordion.tsx
new file mode 100644
index 000000000..61afcfbc6
--- /dev/null
+++ b/src/frontend/src/coral/components/CoralAccordion/CoralAccordion.tsx
@@ -0,0 +1,7 @@
+import React from "react";
+
+const CoralAccordion: React.FC<{ children: React.ReactNode }> = ({ children }) => {
+ return {children}
; // Just a semantic wrapper
+};
+
+export default CoralAccordion;
diff --git a/src/frontend/src/coral/components/CoralAccordion/CoralAccordionContext.tsx b/src/frontend/src/coral/components/CoralAccordion/CoralAccordionContext.tsx
new file mode 100644
index 000000000..f82dc13e3
--- /dev/null
+++ b/src/frontend/src/coral/components/CoralAccordion/CoralAccordionContext.tsx
@@ -0,0 +1,12 @@
+import { createContext, useContext } from "react";
+
+export const CoralAccordionContext = createContext<{
+ open: boolean;
+ toggle: () => void;
+} | null>(null);
+
+export const useCoralAccordion = () => {
+ const ctx = useContext(CoralAccordionContext);
+ if (!ctx) throw new Error("Must be used inside CoralAccordionItem");
+ return ctx;
+};
diff --git a/src/frontend/src/coral/components/CoralAccordion/CoralAccordionHeader.tsx b/src/frontend/src/coral/components/CoralAccordion/CoralAccordionHeader.tsx
new file mode 100644
index 000000000..c6372a423
--- /dev/null
+++ b/src/frontend/src/coral/components/CoralAccordion/CoralAccordionHeader.tsx
@@ -0,0 +1,50 @@
+import React from "react";
+import { Body1 } from "@fluentui/react-components";
+import { ChevronDown20Regular, ChevronUp20Regular } from "@fluentui/react-icons";
+import { useCoralAccordion } from "./CoralAccordionContext";
+
+type Props = {
+ children: React.ReactNode;
+ height?: string;
+ chevron?: boolean;
+};
+
+const CoralAccordionHeader: React.FC = ({
+ children,
+ height = "32px",
+ chevron = false,
+}) => {
+ const { open, toggle } = useCoralAccordion();
+
+ return (
+
+ {children}
+ {chevron && (
+
+
+
+ )}
+
+ );
+};
+
+CoralAccordionHeader.displayName = "CoralAccordionHeader";
+export default CoralAccordionHeader;
diff --git a/src/frontend/src/coral/components/CoralAccordion/CoralAccordionItem.tsx b/src/frontend/src/coral/components/CoralAccordion/CoralAccordionItem.tsx
new file mode 100644
index 000000000..a25e98357
--- /dev/null
+++ b/src/frontend/src/coral/components/CoralAccordion/CoralAccordionItem.tsx
@@ -0,0 +1,36 @@
+import React, { useState, cloneElement, isValidElement } from "react";
+import { CoralAccordionContext } from "./CoralAccordionContext";
+
+type CoralAccordionItemProps = {
+ defaultOpen?: boolean;
+ children: React.ReactNode;
+};
+
+const CoralAccordionItem: React.FC = ({
+ defaultOpen = false,
+ children,
+}) => {
+ const [open, setOpen] = useState(defaultOpen);
+ const toggle = () => setOpen((prev) => !prev);
+
+ return (
+
+ {React.Children.map(children, (child) => {
+ if (!isValidElement(child)) return child;
+
+ const type =
+ (child.type as any)?.displayName || (child.type as any)?.name || "";
+
+ // Show CoralAccordionPanel only if open
+ if (type === "CoralAccordionPanel") {
+ return open ? child : null;
+ }
+
+ // Render all other children (e.g., CoralAccordionHeader)
+ return child;
+ })}
+
+ );
+};
+
+export default CoralAccordionItem;
diff --git a/src/frontend/src/coral/components/CoralAccordion/CoralAccordionPanel.tsx b/src/frontend/src/coral/components/CoralAccordion/CoralAccordionPanel.tsx
new file mode 100644
index 000000000..018c26f0d
--- /dev/null
+++ b/src/frontend/src/coral/components/CoralAccordion/CoralAccordionPanel.tsx
@@ -0,0 +1,7 @@
+import React from "react";
+
+const CoralAccordionPanel: React.FC<{ children: React.ReactNode }> = ({ children }) => {
+ return {children}
;
+};
+
+export default CoralAccordionPanel;
diff --git a/src/frontend/src/coral/components/Header/Header.tsx b/src/frontend/src/coral/components/Header/Header.tsx
new file mode 100644
index 000000000..8af77094f
--- /dev/null
+++ b/src/frontend/src/coral/components/Header/Header.tsx
@@ -0,0 +1,69 @@
+import React from "react";
+import { Avatar, Subtitle2 } from "@fluentui/react-components";
+import MsftColor from "../../imports/MsftColor"; // Default icon component
+
+/**
+ * @component
+ * @name Header
+ * @description A header component for displaying a logo, title, and optional subtitle.
+ *
+ * @prop {React.ReactNode} [logo] - Custom logo (defaults to Microsoft icon).
+ * @prop {string} [title="Microsoft"] - Main title text.
+ * @prop {string} [subtitle] - Optional subtitle displayed next to the title.
+ * @prop {React.ReactNode} [children] - Optional header toolbar (e.g., buttons, menus).
+ */
+type HeaderProps = {
+ logo?: React.ReactNode;
+ title?: string;
+ subtitle?: string;
+ children?: React.ReactNode;
+};
+
+const Header: React.FC = ({ logo, title = "Microsoft", subtitle, children }) => {
+ return (
+
+ );
+};
+
+export default Header;
diff --git a/src/frontend/src/coral/components/Header/HeaderTools.tsx b/src/frontend/src/coral/components/Header/HeaderTools.tsx
new file mode 100644
index 000000000..0df091905
--- /dev/null
+++ b/src/frontend/src/coral/components/Header/HeaderTools.tsx
@@ -0,0 +1,29 @@
+import React, { useState } from "react";
+import { Toolbar, ToolbarDivider, Avatar } from "@fluentui/react-components";
+import eventBus from "../eventbus";
+import PanelRightToggles from "./PanelRightToggles"; // Import PanelRightToggles
+
+
+interface HeaderToolsProps {
+ children?: React.ReactNode;
+}
+
+const HeaderTools: React.FC = ({ children }) => {
+
+
+ return (
+
+ {children}
+
+ );
+};
+
+export default HeaderTools;
diff --git a/src/frontend/src/coral/components/Header/PanelRightToggles.tsx b/src/frontend/src/coral/components/Header/PanelRightToggles.tsx
new file mode 100644
index 000000000..938777226
--- /dev/null
+++ b/src/frontend/src/coral/components/Header/PanelRightToggles.tsx
@@ -0,0 +1,92 @@
+import React, {
+ useState,
+ useEffect,
+ ReactElement,
+ cloneElement,
+ isValidElement
+} from "react";
+import {
+ Toolbar,
+ ToggleButton,
+ ToggleButtonProps,
+ Button,
+ ButtonProps
+} from "@fluentui/react-components";
+import { PanelRightContract, PanelRightExpand } from "@/coral/imports/bundleicons";
+import eventBus from "../eventbus.js";
+
+type PanelRightTogglesProps = {
+ children: React.ReactNode;
+};
+
+type PanelToggleExtras = {
+ panelToggleIcon?: boolean;
+};
+
+type AnyButtonProps = (ToggleButtonProps | ButtonProps) & PanelToggleExtras;
+
+const PanelRightToggles: React.FC = ({ children }) => {
+ const [activePanel, setActivePanel] = useState<"first" | "second" | "third" | "fourth" | null>(null);
+ const panelTypes = ["first", "second", "third", "fourth"] as const;
+
+ useEffect(() => {
+ // Sync to current state
+ setActivePanel(eventBus.getActivePanel());
+
+ const handlePanelToggle = (panel: typeof panelTypes[number] | null) => {
+ setActivePanel(panel);
+ };
+
+ const handlePanelInit = ({ panelType, isActive }: { panelType: string; isActive: boolean }) => {
+ if (isActive) setActivePanel(panelType as any);
+ };
+
+ eventBus.on("setActivePanel", handlePanelToggle);
+ eventBus.on("panelInitState", handlePanelInit);
+
+ return () => {
+ eventBus.off("setActivePanel", handlePanelToggle);
+ eventBus.off("panelInitState", handlePanelInit);
+ };
+ }, []);
+
+ const togglePanel = (panel: typeof panelTypes[number]) => {
+ const next = activePanel === panel ? null : panel;
+ eventBus.setActivePanel(next);
+ };
+
+ const isFluentButton = (child: React.ReactNode): child is ReactElement =>
+ isValidElement(child) &&
+ (child.type === ToggleButton || child.type === Button);
+
+ return (
+
+ {React.Children.map(children, (child, index) => {
+ const panelType = panelTypes[index];
+
+ if (isFluentButton(child) && panelType) {
+ const isActive = activePanel === panelType;
+ const { panelToggleIcon, icon, ...rest } = child.props as AnyButtonProps;
+
+ const resolvedIcon = panelToggleIcon
+ ? isActive
+ ?
+ :
+ : icon;
+
+ return cloneElement(child, {
+ ...rest,
+ icon: resolvedIcon,
+ onClick: () => togglePanel(panelType),
+ "aria-pressed": isActive,
+ checked: "checked" in child.props ? isActive : undefined,
+ });
+ }
+
+ return child;
+ })}
+
+ );
+};
+
+export default PanelRightToggles;
diff --git a/src/frontend/src/coral/components/Header/README.md b/src/frontend/src/coral/components/Header/README.md
new file mode 100644
index 000000000..3af609b6e
--- /dev/null
+++ b/src/frontend/src/coral/components/Header/README.md
@@ -0,0 +1,197 @@
+# Header Components
+
+The Header components form the top navigation bar of your Coral application, providing branding, navigation tools, and panel toggles.
+
+## Components Overview
+
+- `Header`: Main container component for the top bar
+- `HeaderTools`: Container for right-aligned actions and tools
+- `PanelRightToggles`: Container for toggle buttons that control right panel visibility
+
+## Phase 1: UI Customization
+
+### Header Component
+
+The Header component accepts these customization props:
+
+```jsx
+} // Custom logo component or image
+>
+ {/* Children will be rendered inside the header */}
+
+```
+
+### HeaderTools Component
+
+The `HeaderTools` component is a container for right-aligned elements:
+
+```jsx
+
+ // User avatar
+ // Visual separator
+ {/* Other right-aligned tools */}
+
+```
+
+### PanelRightToggles Component
+
+This component contains toggle buttons for showing/hiding right panels:
+
+```jsx
+
+ } // Replace with your icon
+ />
+ {/* Add more toggle buttons as needed */}
+
+```
+
+### Styling
+
+You can customize the appearance using:
+
+1. **Props**: Use the `appearance` prop on buttons (values: "subtle", "primary", etc.)
+2. **Icons**: Replace default icons with your own from Fluent UI or custom SVGs
+3. **Custom CSS**: Apply CSS classes or inline styles
+
+```jsx
+// Example with custom styling
+
+
+
+ }
+ />
+
+```
+
+## Phase 2: Data Population (Mock Data)
+
+The Header components can be populated with dynamic data:
+
+### Dynamic User Information
+
+```jsx
+// Example with dynamic user data
+const user = {
+ name: "Jane Doe",
+ avatarUrl: "https://example.com/avatar.jpg",
+ role: "Admin"
+};
+
+
+
+ {user.name}
+ {user.role}
+
+```
+
+## Phase 3: Service Integration & Event Handling
+
+### Panel Toggle State Management
+
+Connect toggle buttons to control panel visibility:
+
+```jsx
+import { useState } from 'react';
+import eventBus from '../eventbus';
+
+function MyHeader() {
+ const [isHistoryPanelOpen, setHistoryPanelOpen] = useState(false);
+
+ const toggleHistoryPanel = () => {
+ const newState = !isHistoryPanelOpen;
+ setHistoryPanelOpen(newState);
+ // Emit event to inform other components
+ eventBus.emit('historyPanelToggled', newState);
+ };
+
+ return (
+
+
+
+
+
+ }
+ checked={isHistoryPanelOpen}
+ onClick={toggleHistoryPanel}
+ />
+ {/* Other toggles */}
+
+
+
+ );
+}
+```
+
+### User Authentication Integration
+
+```jsx
+// Example with user service integration
+import { userService } from '../../services/userService';
+
+function UserProfile() {
+ const [user, setUser] = useState(null);
+
+ useEffect(() => {
+ // Fetch user profile on component mount
+ userService.getCurrentUser()
+ .then(userData => setUser(userData))
+ .catch(err => console.error('Failed to load user:', err));
+ }, []);
+
+ return (
+
+ {user ? (
+ <>
+
+ {user.name}
+ >
+ ) : (
+ Sign In
+ )}
+
+ );
+}
+```
+
+## Props API
+
+### Header Props
+
+| Prop | Type | Default | Description |
+|------|------|---------|-------------|
+| title | string | "" | Primary title/brand name |
+| subtitle | string | "" | Secondary title/app name |
+| logo | ReactNode | null | Component to render as the logo |
+| children | ReactNode | null | Content to render in the header |
+
+### HeaderTools Props
+
+This component primarily acts as a container and doesn't accept special props beyond standard React props.
+
+### PanelRightToggles Props
+
+This component primarily acts as a container and doesn't accept special props beyond standard React props.
+
+## Best Practices
+
+1. Keep the header clean and minimal for better user experience.
+2. Group related actions together.
+3. Use consistent icons and button styles.
+4. Consider responsive behavior for smaller screens.
+5. Ensure toggle buttons clearly indicate their state (active/inactive).
\ No newline at end of file
diff --git a/src/frontend/src/coral/components/Layout/CoralShellColumn.tsx b/src/frontend/src/coral/components/Layout/CoralShellColumn.tsx
new file mode 100644
index 000000000..171e186cf
--- /dev/null
+++ b/src/frontend/src/coral/components/Layout/CoralShellColumn.tsx
@@ -0,0 +1,25 @@
+// coral.config/components/Layout/CoralShellColumn.tsx
+// Structural wrapper for top-level app layout (vertical orientation)
+
+import React from "react";
+
+const CoralShellColumn: React.FC<{ children: React.ReactNode }> = ({ children }) => {
+ return (
+
+ {children}
+
+ );
+};
+
+export default CoralShellColumn;
+
+
+
diff --git a/src/frontend/src/coral/components/Layout/CoralShellRow.tsx b/src/frontend/src/coral/components/Layout/CoralShellRow.tsx
new file mode 100644
index 000000000..2ccdf21fc
--- /dev/null
+++ b/src/frontend/src/coral/components/Layout/CoralShellRow.tsx
@@ -0,0 +1,20 @@
+// coral.config/components/Layout/CoralShellRow.tsx
+// Structural wrapper for main workspace layout (horizontal split)
+
+import React from "react";
+
+const CoralShellRow: React.FC<{ children: React.ReactNode }> = ({ children }) => {
+ return (
+
+ {children}
+
+ );
+};
+
+export default CoralShellRow;
\ No newline at end of file
diff --git a/src/frontend/src/coral/components/Layout/README.md b/src/frontend/src/coral/components/Layout/README.md
new file mode 100644
index 000000000..59b3a0f09
--- /dev/null
+++ b/src/frontend/src/coral/components/Layout/README.md
@@ -0,0 +1,157 @@
+# Layout Components
+
+The Layout components provide the fundamental structure for your Coral application, defining how different sections are arranged on the page.
+
+## Components Overview
+
+- `CoralShellColumn`: Vertical layout container that typically wraps the entire application
+- `CoralShellRow`: Horizontal layout container that typically wraps the main content area and panels
+
+## Phase 1: UI Customization
+
+### CoralShellColumn Component
+
+The `CoralShellColumn` component creates a vertical column layout:
+
+```jsx
+
+
+
+ {/* Main content and panels */}
+
+
+```
+
+You can customize it with:
+
+- Standard CSS properties via inline styles
+- CSS classes
+- Wrapping it with custom containers
+
+Example with styling:
+
+```jsx
+
+ {/* Content */}
+
+```
+
+### CoralShellRow Component
+
+The `CoralShellRow` component creates a horizontal row layout, typically used to arrange panels and main content:
+
+```jsx
+
+
+
+
+
+```
+
+Customization options:
+
+```jsx
+
+ {/* Content */}
+
+```
+
+## Layout Structure
+
+The typical arrangement of components:
+
+```jsx
+
+ {/* Top Section */}
+
+
+ {/* Main Section */}
+
+ {/* Left Navigation */}
+
+
+ {/* Panel content */}
+
+
+ {/* Center Content */}
+
+
+ {/* Main application content */}
+
+
+ {/* Right Panels */}
+
+
+ {/* Additional panels */}
+
+
+```
+
+## Responsive Behavior
+
+The layout components are designed to be responsive. Here are some tips for ensuring your layout works across different screen sizes:
+
+1. Use percentage or viewport-based widths for panels
+2. Consider hiding less important panels on smaller screens
+3. Apply media queries for specific breakpoints
+
+Example of responsive customization:
+
+```jsx
+// In your CSS file
+@media (max-width: 768px) {
+ .panel-left {
+ display: none;
+ }
+
+ .content-area {
+ padding: 8px;
+ }
+}
+
+// In your component
+
+
+```
+
+## Props API
+
+### CoralShellColumn Props
+
+This component primarily acts as a container and accepts standard React props like:
+- `children`: React nodes to render inside the column
+- `className`: CSS class to apply to the column
+- `style`: Inline styles to apply to the column
+
+### CoralShellRow Props
+
+This component primarily acts as a container and accepts standard React props like:
+- `children`: React nodes to render inside the row
+- `className`: CSS class to apply to the row
+- `style`: Inline styles to apply to the row
+
+## Best Practices
+
+1. **Maintain Hierarchy**: Follow the standard nesting pattern (Column > Row > Components)
+2. **Flex Properties**: Use flex properties for fine-tuning the layout
+3. **Accessibility**: Ensure your layout is accessible by maintaining proper landmark regions
+4. **Consistent Spacing**: Use consistent spacing between layout elements
+5. **Responsive Design**: Test your layout on various screen sizes
\ No newline at end of file
diff --git a/src/frontend/src/coral/components/LoadingMessage.tsx b/src/frontend/src/coral/components/LoadingMessage.tsx
new file mode 100644
index 000000000..441503d26
--- /dev/null
+++ b/src/frontend/src/coral/components/LoadingMessage.tsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import {
+ Text,
+} from "@fluentui/react-components";
+
+export const loadingMessages = [
+ "Initializing AI agents...",
+ "Generating plan scaffolds...",
+ "Optimizing task steps...",
+ "Applying finishing touches...",
+];
+
+export interface LoadingMessageProps {
+ loadingMessage: string;
+ iconSrc?: string;
+ iconWidth?: number;
+ iconHeight?: number;
+}
+
+const LoadingMessage: React.FC = ({
+ loadingMessage,
+ iconSrc,
+ iconWidth = 64,
+ iconHeight = 64
+}) => {
+ return (
+
+ {iconSrc && (
+
+ )}
+
{loadingMessage}
+
+ );
+};
+
+export default LoadingMessage;
\ No newline at end of file
diff --git a/src/frontend/src/coral/components/Panels/PanelFooter.tsx b/src/frontend/src/coral/components/Panels/PanelFooter.tsx
new file mode 100644
index 000000000..d0ae9619f
--- /dev/null
+++ b/src/frontend/src/coral/components/Panels/PanelFooter.tsx
@@ -0,0 +1,18 @@
+import React from "react";
+
+const PanelFooter: React.FC<{ children: React.ReactNode }> = ({ children }) => {
+ return (
+
+ {children}
+
+ );
+};
+
+PanelFooter.displayName = "PanelFooter";
+
+export default PanelFooter;
diff --git a/src/frontend/src/coral/components/Panels/PanelLeft.tsx b/src/frontend/src/coral/components/Panels/PanelLeft.tsx
new file mode 100644
index 000000000..bc83cbe78
--- /dev/null
+++ b/src/frontend/src/coral/components/Panels/PanelLeft.tsx
@@ -0,0 +1,134 @@
+import React, {
+ useState,
+ useEffect,
+ ReactNode,
+ ReactElement,
+ isValidElement,
+} from "react";
+import PanelToolbar from "./PanelLeftToolbar.js";
+import PanelFooter from "./PanelFooter"; // 👈 new
+import {
+ Avatar,
+ Body1,
+ Body1Strong,
+ Caption1,
+} from "@fluentui/react-components";
+import Human from "../../imports/human.png";
+
+interface PanelLeftProps {
+ panelWidth?: number;
+ panelResize?: boolean;
+ children?: ReactNode;
+}
+
+const PanelLeft: React.FC = ({
+ panelWidth = 500,
+ panelResize = true,
+ children,
+}) => {
+ const [width, setWidth] = useState(panelWidth);
+ const [isHandleHovered, setIsHandleHovered] = useState(false);
+
+ useEffect(() => {
+ setWidth(panelWidth);
+ }, [panelWidth]);
+
+ const handleMouseDown = (e: React.MouseEvent) => {
+ if (!panelResize) return;
+
+ const startX = e.clientX;
+ const startWidth = width;
+
+ const onMouseMove = (moveEvent: MouseEvent) => {
+ const newWidth = Math.min(
+ 500,
+ Math.max(256, startWidth + (moveEvent.clientX - startX))
+ );
+ setWidth(newWidth);
+ };
+
+ const onMouseUp = () => {
+ document.removeEventListener("mousemove", onMouseMove);
+ document.removeEventListener("mouseup", onMouseUp);
+ document.body.style.userSelect = "";
+ };
+
+ document.addEventListener("mousemove", onMouseMove);
+ document.addEventListener("mouseup", onMouseUp);
+ document.body.style.userSelect = "none";
+ };
+
+ const childrenArray = React.Children.toArray(children) as ReactElement[];
+ const toolbar = childrenArray.find(
+ (child) => isValidElement(child) && child.type === PanelToolbar
+ );
+ const footer = childrenArray.find(
+ (child) => isValidElement(child) && child.type === PanelFooter
+ );
+ const content = childrenArray.filter(
+ (child) =>
+ !(
+ isValidElement(child) &&
+ (child.type === PanelToolbar || child.type === PanelFooter)
+ )
+ );
+
+ return (
+
+ {toolbar &&
{toolbar}
}
+
+
+ {content}
+
+
+ {footer &&
{footer}
}
+
+ {panelResize && (
+
setIsHandleHovered(true)}
+ onMouseLeave={() => setIsHandleHovered(false)}
+ style={{
+ position: "absolute",
+ top: 0,
+ right: 0,
+ width: "2px",
+ height: "100%",
+ cursor: "ew-resize",
+ zIndex: 1,
+ backgroundColor: isHandleHovered
+ ? "var(--colorNeutralStroke2)"
+ : "transparent",
+ }}
+ />
+ )}
+
+ );
+};
+
+export default PanelLeft;
diff --git a/src/frontend/src/coral/components/Panels/PanelLeftToolbar.tsx b/src/frontend/src/coral/components/Panels/PanelLeftToolbar.tsx
new file mode 100644
index 000000000..3272b332c
--- /dev/null
+++ b/src/frontend/src/coral/components/Panels/PanelLeftToolbar.tsx
@@ -0,0 +1,101 @@
+import React, { ReactNode } from "react";
+import { Subtitle2 } from "@fluentui/react-components";
+import { Link } from "react-router-dom";
+
+interface PanelLeftToolbarProps {
+ panelIcon?: ReactNode;
+ panelTitle?: string | null;
+ linkTo?: string;
+ children?: ReactNode;
+}
+
+const PanelLeftToolbar: React.FC
= ({
+ panelIcon,
+ panelTitle,
+ linkTo,
+ children,
+}) => {
+ const TitleContent = (
+
+ {panelIcon && (
+
+ {panelIcon}
+
+ )}
+ {panelTitle && (
+
+ {panelTitle}
+
+ )}
+
+ );
+
+ return (
+
+ {(panelIcon || panelTitle) &&
+ (linkTo ? (
+
+ {TitleContent}
+
+ ) : (
+ TitleContent
+ ))}
+
+ {children}
+
+
+ );
+};
+
+export default PanelLeftToolbar;
diff --git a/src/frontend/src/coral/components/Panels/PanelRight.tsx b/src/frontend/src/coral/components/Panels/PanelRight.tsx
new file mode 100644
index 000000000..19f5ee758
--- /dev/null
+++ b/src/frontend/src/coral/components/Panels/PanelRight.tsx
@@ -0,0 +1,149 @@
+import React, { useState, useEffect, ReactNode, ReactElement } from "react";
+import eventBus from "../eventbus.js";
+import PanelRightToolbar from "./PanelRightToolbar.js"; // Import to identify toolbar
+
+interface PanelRightProps {
+ panelWidth?: number; // Optional width of the panel
+ panelResize?: boolean; // Whether resizing is enabled
+ panelType: "first" | "second" | "third" | "fourth"; // Panel type identifier
+ defaultClosed?: boolean;
+ children?: ReactNode;
+}
+
+const PanelRight: React.FC = ({
+ panelWidth = 325, // Default width if not provided
+ panelResize = true,
+ panelType = "first", // Default to "first" if not explicitly defined
+ defaultClosed = false,
+ children,
+}) => {
+ const [isActive, setIsActive] = useState(() =>
+ defaultClosed ? false : panelType === "first"
+ );
+ const [width, setWidth] = useState(panelWidth); // Initial width from props or default
+ const [isHandleHovered, setIsHandleHovered] = useState(false);
+
+ useEffect(() => {
+ // Initialize shared width if not already set in the EventBus
+ if (eventBus.getPanelWidth() === 400) {
+ eventBus.setPanelWidth(panelWidth); // Use the provided panelWidth prop
+ }
+ setWidth(eventBus.getPanelWidth()); // Set the current width from EventBus
+
+ const handleActivePanel = (panel: "first" | "second" | "third" | "fourth" | null) => {
+ setIsActive(panel === panelType); // Check if this panelType matches the active panel
+ };
+
+ const handleWidthChange = (newWidth: number) => {
+ setWidth(newWidth); // Update width when EventBus notifies
+ };
+
+ eventBus.on("setActivePanel", handleActivePanel);
+ eventBus.on("panelWidthChanged", handleWidthChange);
+
+ return () => {
+ eventBus.off("setActivePanel", handleActivePanel);
+ eventBus.off("panelWidthChanged", handleWidthChange);
+ };
+ }, [panelType, panelWidth]);
+
+ useEffect(() => {
+ // On initial mount, tell the header what panels are open
+ eventBus.emit("panelInitState", {
+ panelType,
+ isActive,
+ });
+ }, []);
+
+ const handleMouseDown = (e: React.MouseEvent) => {
+ if (!panelResize) return;
+
+ const startX = e.clientX;
+ const startWidth = width;
+
+ const onMouseMove = (moveEvent: MouseEvent) => {
+ const newWidth = Math.min(
+ 500, // Max width
+ Math.max(256, startWidth - (moveEvent.clientX - startX)) // Min width
+ );
+ setWidth(newWidth);
+ eventBus.setPanelWidth(newWidth); // Persist the new width in EventBus
+ };
+
+ const onMouseUp = () => {
+ document.removeEventListener("mousemove", onMouseMove);
+ document.removeEventListener("mouseup", onMouseUp);
+ document.body.style.userSelect = "";
+ };
+
+ document.addEventListener("mousemove", onMouseMove);
+ document.addEventListener("mouseup", onMouseUp);
+
+ document.body.style.userSelect = "none";
+ };
+
+ if (!isActive) return null; // Do not render if not active
+
+ const childrenArray = React.Children.toArray(children) as ReactElement[];
+ const toolbar = childrenArray.find(
+ (child) => React.isValidElement(child) && child.type === PanelRightToolbar
+ );
+ const content = childrenArray.filter(
+ (child) => !(React.isValidElement(child) && child.type === PanelRightToolbar)
+ );
+
+ return (
+
+ {toolbar &&
{toolbar}
}
+
+
+ {content}
+
+
+ {panelResize && (
+
setIsHandleHovered(true)}
+ onMouseLeave={() => setIsHandleHovered(false)}
+ style={{
+ position: "absolute",
+ top: 0,
+ left: 0,
+ width: "2px",
+ height: "100%",
+ cursor: "ew-resize",
+ zIndex: 1,
+ backgroundColor: isHandleHovered
+ ? "var(--colorNeutralStroke2)"
+ : "transparent",
+ }}
+ />
+ )}
+
+ );
+};
+
+export default PanelRight;
\ No newline at end of file
diff --git a/src/frontend/src/coral/components/Panels/PanelRightToolbar.tsx b/src/frontend/src/coral/components/Panels/PanelRightToolbar.tsx
new file mode 100644
index 000000000..0fc3285f0
--- /dev/null
+++ b/src/frontend/src/coral/components/Panels/PanelRightToolbar.tsx
@@ -0,0 +1,90 @@
+import React, { ReactNode } from "react";
+import { Body1Strong, Button } from "@fluentui/react-components";
+import eventBus from "../eventbus.js";
+import { Dismiss } from "../../imports/bundleicons.js";
+
+interface PanelRightToolbarProps {
+ panelTitle?: string | null;
+ panelIcon?: ReactNode;
+ // panelType?: "first" | "second"; // Optional, defaults to "first"
+ children?: ReactNode;
+ handleDismiss?: () => void; // Add this line
+}
+
+const PanelRightToolbar: React.FC
= ({
+ panelTitle,
+ panelIcon,
+ // panelType = "first", // Default value set here
+ children,
+}) => {
+ const handleDismiss = () => {
+ eventBus.emit("setActivePanel", null); // Close the current panel
+ };
+
+ return (
+
+
+ {panelIcon && (
+
+ {panelIcon}
+
+ )}
+ {panelTitle && (
+
+ {panelTitle}
+
+ )}
+
+
+ {children}
+ {/* }
+ onClick={handleDismiss} // Handle dismiss logic
+ aria-label="Close panel"
+ /> */}
+
+
+ );
+};
+
+export default PanelRightToolbar;
\ No newline at end of file
diff --git a/src/frontend/src/coral/components/Panels/README.md b/src/frontend/src/coral/components/Panels/README.md
new file mode 100644
index 000000000..1f2e6b4f0
--- /dev/null
+++ b/src/frontend/src/coral/components/Panels/README.md
@@ -0,0 +1,332 @@
+# Panel Components
+
+Panel components provide specialized containers for navigation, filters, tools, and information displays that typically appear on the sides of your Coral application.
+
+## Components Overview
+
+- `PanelLeft`: Main left-side panel with resize capabilities
+- `PanelLeftToolbar`: Header area for the left panel with title and controls
+- `PanelRightFirst`, `PanelRightSecond`, etc.: Right-side panels for various purposes
+
+## Phase 1: UI Customization
+
+### PanelLeft Component
+
+The `PanelLeft` component creates a resizable left panel:
+
+```jsx
+
+ }
+ />
+ {/* Panel content */}
+
+```
+
+Customization options:
+
+```jsx
+
+ {/* Content */}
+
+```
+
+### PanelLeftToolbar Component
+
+The `PanelLeftToolbar` component provides a header for the left panel:
+
+```jsx
+ }
+>
+ {/* Optional toolbar actions */}
+ } />
+
+```
+
+### Right Panel Components
+
+Right panels follow a similar pattern:
+
+```jsx
+
+ {/* Content for the first right panel */}
+
+
+
+ {/* Content for the second right panel */}
+
+```
+
+## Phase 2: Data Population (Mock Data)
+
+The panels can be populated with dynamic data to display lists, trees, or other structured information.
+
+### Navigation List Example
+
+```jsx
+import { useState } from 'react';
+import {
+ List,
+ ListItem,
+ ListItemIcon,
+ ListItemText
+} from '@fluentui/react-components';
+
+function NavigationPanel() {
+ // Mock navigation data
+ const navItems = [
+ { id: 'home', label: 'Home', icon: },
+ { id: 'documents', label: 'Documents', icon: },
+ { id: 'settings', label: 'Settings', icon: },
+ ];
+
+ const [selectedItem, setSelectedItem] = useState('home');
+
+ return (
+
+
+
+
+ {navItems.map(item => (
+ setSelectedItem(item.id)}
+ >
+ {item.icon}
+ {item.label}
+
+ ))}
+
+
+ );
+}
+```
+
+### Filtered List Example
+
+```jsx
+import { useState, useEffect } from 'react';
+import {
+ Input,
+ List,
+ ListItem,
+ ListItemText
+} from '@fluentui/react-components';
+import { Search } from '@fluentui/react-icons';
+
+function FilterPanel() {
+ // Mock data
+ const allItems = [
+ { id: '1', name: 'Item One', category: 'A' },
+ { id: '2', name: 'Item Two', category: 'B' },
+ { id: '3', name: 'Another Item', category: 'A' },
+ { id: '4', name: 'Last Item', category: 'C' },
+ ];
+
+ const [searchTerm, setSearchTerm] = useState('');
+ const [filteredItems, setFilteredItems] = useState(allItems);
+
+ // Filter items based on search
+ useEffect(() => {
+ const filtered = allItems.filter(item =>
+ item.name.toLowerCase().includes(searchTerm.toLowerCase())
+ );
+ setFilteredItems(filtered);
+ }, [searchTerm]);
+
+ return (
+
+
+
+
+ setSearchTerm(e.target.value)}
+ contentBefore={ }
+ />
+
+
+
+ {filteredItems.map(item => (
+
+ {item.name}
+
+ ))}
+
+
+ );
+}
+```
+
+## Phase 3: Service Integration & Event Handling
+
+Connect your panels to services and event handling to make them fully interactive.
+
+### Data Service Integration
+
+```jsx
+import { useState, useEffect } from 'react';
+import {
+ List,
+ ListItem,
+ ListItemText,
+ Spinner
+} from '@fluentui/react-components';
+// Example service
+import { itemService } from '../../services/itemService';
+
+function ServiceConnectedPanel() {
+ const [items, setItems] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ // Fetch data from service
+ setLoading(true);
+ itemService.getItems()
+ .then(data => {
+ setItems(data);
+ setLoading(false);
+ })
+ .catch(err => {
+ console.error('Failed to load items:', err);
+ setError('Failed to load items');
+ setLoading(false);
+ });
+ }, []);
+
+ return (
+
+
+
+ {loading && }
+ {error && {error}
}
+
+
+ {items.map(item => (
+
+ {item.name}
+
+ ))}
+
+
+ );
+}
+```
+
+### EventBus Integration
+
+```jsx
+import { useState, useEffect } from 'react';
+import eventBus from '../eventbus';
+
+function EventAwarePanel() {
+ const [isPanelVisible, setPanelVisible] = useState(true);
+
+ useEffect(() => {
+ // Subscribe to events
+ const handleToggle = (visible) => {
+ setPanelVisible(visible);
+ };
+
+ eventBus.on('toggleLeftPanel', handleToggle);
+
+ // Cleanup
+ return () => {
+ eventBus.off('toggleLeftPanel', handleToggle);
+ };
+ }, []);
+
+ if (!isPanelVisible) return null;
+
+ return (
+
+ }
+ />
+ {/* Panel content */}
+
+ );
+}
+```
+
+### Selection Event Emitting
+
+```jsx
+import eventBus from '../eventbus';
+
+function SelectionPanel() {
+ const items = [/*...your items...*/];
+
+ const handleItemClick = (item) => {
+ // Emit event when item is selected
+ eventBus.emit('itemSelected', item);
+ };
+
+ return (
+
+
+
+
+ {items.map(item => (
+ handleItemClick(item)}
+ >
+ {item.name}
+
+ ))}
+
+
+ );
+}
+```
+
+## Props API
+
+### PanelLeft Props
+
+| Prop | Type | Default | Description |
+|------|------|---------|-------------|
+| panelWidth | number | 280 | Initial width of the panel in pixels |
+| panelResize | boolean | false | Whether the panel can be resized by the user |
+| children | ReactNode | null | Content to render inside the panel |
+| className | string | "" | Additional CSS class names |
+| style | CSSProperties | {} | Additional inline styles |
+
+### PanelLeftToolbar Props
+
+| Prop | Type | Default | Description |
+|------|------|---------|-------------|
+| panelTitle | string | "" | Title text to display in the toolbar |
+| panelIcon | ReactNode | null | Icon to display next to the title |
+| children | ReactNode | null | Additional content for the toolbar (buttons, etc.) |
+
+### Right Panel Props
+
+Right panels typically accept standard React props like `children`, `className`, and `style`.
+
+## Best Practices
+
+1. **Content Organization**: Keep panel content organized and minimal.
+2. **Visual Hierarchy**: Use proper sizing and spacing for list items.
+3. **Loading States**: Always show loading indicators when fetching data.
+4. **Error Handling**: Display user-friendly error messages.
+5. **Responsive Design**: Consider how panels will behave on smaller screens.
\ No newline at end of file
diff --git a/src/frontend/src/coral/components/Panels/UserCard.tsx b/src/frontend/src/coral/components/Panels/UserCard.tsx
new file mode 100644
index 000000000..ec393c9d5
--- /dev/null
+++ b/src/frontend/src/coral/components/Panels/UserCard.tsx
@@ -0,0 +1,39 @@
+import React from "react";
+import {
+ Avatar,
+ AvatarProps,
+ Body1Strong,
+ Caption1,
+} from "@fluentui/react-components";
+
+interface PanelUserCardProps extends AvatarProps {
+ name: string; // required for both Avatar and label
+ alias?: string; // optional sub-label
+}
+
+const PanelUserCard: React.FC = ({ name, alias, ...avatarProps }) => {
+ return (
+
+
+
+ {name}
+ {alias && (
+
+ {alias}
+
+ )}
+
+
+ );
+};
+
+export default PanelUserCard;
diff --git a/src/frontend/src/coral/components/Progress/ProgressCircle.tsx b/src/frontend/src/coral/components/Progress/ProgressCircle.tsx
new file mode 100644
index 000000000..fce6306bc
--- /dev/null
+++ b/src/frontend/src/coral/components/Progress/ProgressCircle.tsx
@@ -0,0 +1,92 @@
+import React, { useEffect, useRef, useState } from "react";
+
+interface ProgressCircleProps {
+ progress: number; // 0 to 1
+ size?: number;
+ strokeWidth?: number;
+ backgroundColor?: string;
+ fillColor?: string;
+}
+
+const ProgressCircle: React.FC = ({
+ progress,
+ size = 56,
+ strokeWidth = 8,
+ backgroundColor = "var(--colorNeutralBackground6)",
+ fillColor = "var(--colorPaletteSeafoamBorderActive)",
+}) => {
+ const circleRef = useRef(null);
+ const [hasMounted, setHasMounted] = useState(false);
+
+ const radius = (size - strokeWidth) / 2;
+ const circumference = 2 * Math.PI * radius;
+
+ useEffect(() => {
+ const circle = circleRef.current;
+ if (circle) {
+ const offset = circumference * (1 - progress);
+
+ if (hasMounted) {
+ circle.style.transition = "stroke-dashoffset 0.6s ease";
+ } else {
+ circle.style.transition = "none";
+ setHasMounted(true);
+ }
+
+ circle.style.strokeDashoffset = `${offset}`;
+ }
+ }, [progress, circumference, hasMounted]);
+
+ return (
+
+
+
+
+
+
+ {progress >= 1 && (
+
+ 🚀
+
+ )}
+
+ );
+};
+
+export default ProgressCircle;
diff --git a/src/frontend/src/coral/components/PromptCard.tsx b/src/frontend/src/coral/components/PromptCard.tsx
new file mode 100644
index 000000000..378660816
--- /dev/null
+++ b/src/frontend/src/coral/components/PromptCard.tsx
@@ -0,0 +1,76 @@
+// PromptCard.tsx
+import React from "react";
+import { Card } from "@fluentui/react-components";
+import { Body1, Body1Strong } from "@fluentui/react-components";
+
+type PromptCardProps = {
+ title: string;
+ description: string;
+ icon?: React.ReactNode;
+ onClick?: () => void;
+ disabled?: boolean; // ✅ New prop for disabling the card
+};
+
+const PromptCard: React.FC = ({
+ title,
+ description,
+ icon,
+ onClick,
+ disabled = false, // 🔧 Default is false (enabled)
+}) => {
+ return (
+ {
+ if (!disabled) {
+ e.currentTarget.style.backgroundColor =
+ "var(--colorNeutralBackground4Hover)";
+ }
+ }}
+ onMouseOut={(e) => {
+ if (!disabled) {
+ e.currentTarget.style.backgroundColor =
+ "var(--colorNeutralBackground3)";
+ }
+ }}
+ >
+
+ {icon && (
+
+ {icon}
+
+ )}
+
+ {title}
+
+ {description}
+
+
+
+
+ );
+};
+
+export default PromptCard;
diff --git a/src/frontend/src/coral/components/eventbus.README.md b/src/frontend/src/coral/components/eventbus.README.md
new file mode 100644
index 000000000..807edaf14
--- /dev/null
+++ b/src/frontend/src/coral/components/eventbus.README.md
@@ -0,0 +1,226 @@
+# Event Bus
+
+The `eventbus.tsx` component provides a simple pub/sub (publish-subscribe) mechanism for decoupled communication between components across your Coral application.
+
+## Overview
+
+The Event Bus enables communication between components that:
+- Don't have a direct parent-child relationship
+- Are in different parts of the component tree
+- Need to communicate without prop drilling
+
+It follows the Observer pattern, allowing components to subscribe to events (topics) and react when those events are triggered by other components.
+
+## Basic Usage
+
+### Importing the Event Bus
+
+```jsx
+import eventBus from './eventbus';
+```
+
+### Subscribing to Events
+
+To listen for a specific event:
+
+```jsx
+// Event handler function
+const handleMyEvent = (data) => {
+ console.log('Event received with data:', data);
+ // Handle the event...
+};
+
+// Subscribe to an event
+eventBus.on('myEventName', handleMyEvent);
+```
+
+### Publishing Events
+
+To trigger an event:
+
+```jsx
+// Emit an event with optional data
+eventBus.emit('myEventName', { id: 123, value: 'example data' });
+```
+
+### Unsubscribing from Events
+
+Always unsubscribe when a component unmounts to prevent memory leaks:
+
+```jsx
+// Unsubscribe from an event
+eventBus.off('myEventName', handleMyEvent);
+```
+
+## Example in React Components
+
+### Component A (Event Publisher)
+
+```jsx
+import React from 'react';
+import eventBus from '../eventbus';
+import { Button } from '@fluentui/react-components';
+
+function ComponentA() {
+ const handleButtonClick = () => {
+ // Publish an event when button is clicked
+ eventBus.emit('itemSelected', {
+ id: '123',
+ name: 'Example Item',
+ details: 'This is an example item'
+ });
+ };
+
+ return (
+
+ Select Item
+
+ );
+}
+
+export default ComponentA;
+```
+
+### Component B (Event Subscriber)
+
+```jsx
+import React, { useState, useEffect } from 'react';
+import eventBus from '../eventbus';
+
+function ComponentB() {
+ const [selectedItem, setSelectedItem] = useState(null);
+
+ useEffect(() => {
+ // Handler function
+ const handleItemSelected = (item) => {
+ setSelectedItem(item);
+ console.log('Item selected:', item);
+ };
+
+ // Subscribe when component mounts
+ eventBus.on('itemSelected', handleItemSelected);
+
+ // Unsubscribe when component unmounts
+ return () => {
+ eventBus.off('itemSelected', handleItemSelected);
+ };
+ }, []); // Empty dependency array ensures this runs only once on mount
+
+ return (
+
+
Selected Item:
+ {selectedItem ? (
+
+
ID: {selectedItem.id}
+
Name: {selectedItem.name}
+
Details: {selectedItem.details}
+
+ ) : (
+
No item selected
+ )}
+
+ );
+}
+
+export default ComponentB;
+```
+
+## Common Use Cases
+
+1. **Panel Visibility Toggling**: Toggle right/left panels from header buttons
+ ```jsx
+ // In header component
+ eventBus.emit('togglePanel', { panelId: 'rightPanel', isVisible: true });
+
+ // In panel component
+ eventBus.on('togglePanel', ({ panelId, isVisible }) => {
+ if (panelId === 'rightPanel') {
+ setVisible(isVisible);
+ }
+ });
+ ```
+
+2. **Selection Synchronization**: Update multiple components when an item is selected
+ ```jsx
+ // In list component
+ eventBus.emit('itemSelected', selectedItem);
+
+ // In details component
+ eventBus.on('itemSelected', setCurrentItem);
+ ```
+
+3. **Global Notifications**: Show notifications across the application
+ ```jsx
+ // Trigger notification from anywhere
+ eventBus.emit('showNotification', {
+ message: 'Operation completed successfully',
+ type: 'success'
+ });
+
+ // In notification component
+ eventBus.on('showNotification', showNotification);
+ ```
+
+## Best Practices
+
+1. **Consistent Event Names**: Use a clear naming convention for events, such as:
+ - `verb:noun` (e.g., `select:item`, `toggle:panel`)
+ - `entityName:action` (e.g., `item:selected`, `panel:toggled`)
+
+2. **Typed Events**: For TypeScript applications, define interfaces for your event data:
+ ```typescript
+ interface ItemSelectedEvent {
+ id: string;
+ name: string;
+ category?: string;
+ }
+
+ // Emit with type
+ eventBus.emit('itemSelected', { id: '123', name: 'Example' } as ItemSelectedEvent);
+
+ // Handle with type
+ const handleItemSelected = (data: ItemSelectedEvent) => {
+ // Typed data
+ };
+ ```
+
+3. **Cleanup Subscriptions**: Always unsubscribe in the `useEffect` cleanup function or `componentWillUnmount` lifecycle method.
+
+4. **Documentation**: Document the events emitted and required payload for each component.
+
+5. **When to Use**: Only use the Event Bus when props or React Context are not suitable:
+ - Props: For direct parent-child communication
+ - Context: For state shared across a subtree of components
+ - Event Bus: For communication between unrelated components
+
+## Implementation Details
+
+The Event Bus is implemented using a simple JavaScript object that maintains a map of event names to arrays of handler functions:
+
+```typescript
+// Simplified implementation
+const eventBus = {
+ events: {},
+
+ on(event: string, callback: Function) {
+ if (!this.events[event]) {
+ this.events[event] = [];
+ }
+ this.events[event].push(callback);
+ },
+
+ off(event: string, callback: Function) {
+ if (this.events[event]) {
+ this.events[event] = this.events[event].filter(cb => cb !== callback);
+ }
+ },
+
+ emit(event: string, data?: any) {
+ if (this.events[event]) {
+ this.events[event].forEach(callback => callback(data));
+ }
+ }
+};
+
+export default eventBus;
+```
\ No newline at end of file
diff --git a/src/frontend/src/coral/components/eventbus.tsx b/src/frontend/src/coral/components/eventbus.tsx
new file mode 100644
index 000000000..eb3d36878
--- /dev/null
+++ b/src/frontend/src/coral/components/eventbus.tsx
@@ -0,0 +1,47 @@
+type EventCallback = (...args: any[]) => void;
+
+class EventBus {
+ private events: { [key: string]: EventCallback[] } = {};
+ private panelWidth: number = 400;
+ private activePanel: "first" | "second" | "third" | "fourth" | null = null;
+
+ on(event: string, callback: EventCallback) {
+ if (!this.events[event]) {
+ this.events[event] = [];
+ }
+ this.events[event].push(callback);
+ }
+
+ off(event: string, callback: EventCallback) {
+ if (!this.events[event]) return;
+ this.events[event] = this.events[event].filter(cb => cb !== callback);
+ }
+
+ emit(event: string, ...args: any[]) {
+ if (!this.events[event]) return;
+ this.events[event].forEach(callback => callback(...args));
+ }
+
+ // Panel control
+ setActivePanel(panel: "first" | "second" | "third" | "fourth" | null) {
+ this.activePanel = panel;
+ this.emit("setActivePanel", panel);
+ }
+
+ getActivePanel(): "first" | "second" | "third" | "fourth" | null {
+ return this.activePanel;
+ }
+
+ // Shared panel width
+ setPanelWidth(width: number) {
+ this.panelWidth = width;
+ this.emit("panelWidthChanged", width);
+ }
+
+ getPanelWidth(): number {
+ return this.panelWidth;
+ }
+}
+
+const eventBus = new EventBus();
+export default eventBus;
diff --git a/src/frontend/src/coral/imports/ContosoLogo.tsx b/src/frontend/src/coral/imports/ContosoLogo.tsx
new file mode 100644
index 000000000..af27010bc
--- /dev/null
+++ b/src/frontend/src/coral/imports/ContosoLogo.tsx
@@ -0,0 +1,22 @@
+import React from 'react';
+
+const ContosoLogo: React.FC = () => {
+ return (
+
+
+
+ );
+};
+
+export default ContosoLogo;
diff --git a/src/frontend/src/coral/imports/MsftColor.tsx b/src/frontend/src/coral/imports/MsftColor.tsx
new file mode 100644
index 000000000..9b030d24a
--- /dev/null
+++ b/src/frontend/src/coral/imports/MsftColor.tsx
@@ -0,0 +1,20 @@
+import React from 'react';
+
+const MicrosoftLogo: React.FC = () => {
+ return (
+
+
+
+
+
+
+ );
+};
+
+export default MicrosoftLogo;
diff --git a/src/frontend/src/coral/imports/Octopus.png b/src/frontend/src/coral/imports/Octopus.png
new file mode 100644
index 000000000..2394f4283
Binary files /dev/null and b/src/frontend/src/coral/imports/Octopus.png differ
diff --git a/src/frontend/src/coral/imports/bundleicons.tsx b/src/frontend/src/coral/imports/bundleicons.tsx
new file mode 100644
index 000000000..2b8e6432b
--- /dev/null
+++ b/src/frontend/src/coral/imports/bundleicons.tsx
@@ -0,0 +1,138 @@
+//DEV NOTES:
+//It's recommended to create bundleIcons for icons that nest within Fluent components and then import them into your project.
+// See full catalog of icons at https://react.fluentui.dev/?path=/docs/icons-catalog--docs.
+
+import {
+ ArrowExitFilled,
+ ArrowExitRegular,
+ BeakerFilled,
+ BeakerRegular,
+ BookmarkFilled,
+ BookmarkRegular,
+ CodeFilled,
+ CodeRegular,
+ CubeFilled,
+ CubeRegular,
+ DesignIdeasFilled,
+ DesignIdeasRegular,
+ DrawerArrowDownloadFilled,
+ DrawerArrowDownloadRegular,
+ FlowFilled,
+ FlowRegular,
+ FolderOpenFilled,
+ FolderOpenRegular,
+ LeafOneFilled,
+ LeafOneRegular,
+ LinkFilled,
+ LinkRegular,
+ OpenFilled,
+ OpenRegular,
+ OrganizationHorizontalFilled,
+ OrganizationHorizontalRegular,
+ PanelLeftContractFilled,
+ PanelLeftContractRegular,
+ PanelLeftExpandFilled,
+ PanelLeftExpandRegular,
+ PanelRightContractFilled,
+ PanelRightContractRegular,
+ PanelRightExpandFilled,
+ PanelRightExpandRegular,
+ PersonFilled,
+ PersonRegular,
+ PersonFeedbackFilled,
+ PersonFeedbackRegular,
+ SearchFilled,
+ SearchRegular,
+ SendFilled,
+ SendRegular,
+ ShareFilled,
+ ShareRegular,
+ TreeDeciduousFilled,
+ TreeDeciduousRegular,
+ TreeEvergreenFilled,
+ TreeEvergreenRegular,
+ WeatherMoonFilled,
+ WeatherMoonRegular,
+ WeatherSunnyFilled,
+ WeatherSunnyRegular,
+ DismissFilled,
+ DismissRegular,
+ DocumentSparkleFilled,
+ DocumentSparkleRegular,
+ SparkleFilled,
+ SparkleRegular,
+ StarFilled,
+ StarRegular,
+ MoreHorizontalFilled,
+ MoreHorizontalRegular,
+ bundleIcon,
+ CopyFilled,
+ CopyRegular,
+ HistoryFilled,
+ HistoryRegular,
+ TaskListSquareLtrFilled,
+ TaskListSquareLtrRegular,
+
+ } from "@fluentui/react-icons";
+
+ export const TaskListSquareLtr = bundleIcon(TaskListSquareLtrFilled, TaskListSquareLtrRegular);
+ export const History = bundleIcon(HistoryFilled, HistoryRegular);
+ export const Copy = bundleIcon(CopyFilled, CopyRegular);
+ export const Send = bundleIcon(SendFilled, SendRegular);
+ export const MoreHorizontal = bundleIcon(MoreHorizontalFilled, MoreHorizontalRegular);
+ export const ArrowExit = bundleIcon(ArrowExitFilled, ArrowExitRegular);
+ export const Bookmark = bundleIcon(BookmarkFilled, BookmarkRegular);
+ export const Sparkle = bundleIcon(SparkleFilled, SparkleRegular);
+ export const Star = bundleIcon(StarFilled, StarRegular);
+ export const DocumentSparkle = bundleIcon(DocumentSparkleFilled, DocumentSparkleRegular);
+ export const Dismiss = bundleIcon(DismissFilled, DismissRegular);
+ export const DrawerArrowDownload = bundleIcon(DrawerArrowDownloadFilled, DrawerArrowDownloadRegular);
+ export const Beaker = bundleIcon(BeakerFilled, BeakerRegular);
+ export const Code = bundleIcon(CodeFilled, CodeRegular);
+ export const Cube = bundleIcon(CubeFilled, CubeRegular);
+ export const DesignIdeas = bundleIcon(DesignIdeasFilled, DesignIdeasRegular);
+ export const Flow = bundleIcon(FlowFilled, FlowRegular);
+ export const FolderOpen = bundleIcon(FolderOpenFilled, FolderOpenRegular);
+ export const LeafOne = bundleIcon(LeafOneFilled, LeafOneRegular);
+ export const Link = bundleIcon(LinkFilled, LinkRegular);
+ export const Open = bundleIcon(OpenFilled, OpenRegular);
+ export const OrganizationHorizontal = bundleIcon(
+ OrganizationHorizontalFilled,
+ OrganizationHorizontalRegular
+ );
+ export const PanelLeftContract = bundleIcon(
+ PanelLeftContractFilled,
+ PanelLeftContractRegular
+ );
+ export const PanelLeftExpand = bundleIcon(
+ PanelLeftExpandFilled,
+ PanelLeftExpandRegular
+ );
+ export const PanelRightContract = bundleIcon(
+ PanelRightContractFilled,
+ PanelRightContractRegular
+ );
+ export const PanelRightExpand = bundleIcon(
+ PanelRightExpandFilled,
+ PanelRightExpandRegular
+ );
+ export const Person = bundleIcon(PersonFilled, PersonRegular);
+ export const PersonFeedback = bundleIcon(
+ PersonFeedbackFilled,
+ PersonFeedbackRegular
+ );
+ export const Search = bundleIcon(SearchFilled, SearchRegular);
+ export const Share = bundleIcon(ShareFilled, ShareRegular);
+ export const TreeDeciduous = bundleIcon(
+ TreeDeciduousFilled,
+ TreeDeciduousRegular
+ );
+ export const TreeEvergreen = bundleIcon(
+ TreeEvergreenFilled,
+ TreeEvergreenRegular
+ );
+ export const WeatherMoon = bundleIcon(WeatherMoonFilled, WeatherMoonRegular);
+ export const WeatherSunny = bundleIcon(WeatherSunnyFilled, WeatherSunnyRegular);
+
+ export default {bundleIcon}
+
\ No newline at end of file
diff --git a/src/frontend/src/coral/imports/human.png b/src/frontend/src/coral/imports/human.png
new file mode 100644
index 000000000..cb7e8ea24
Binary files /dev/null and b/src/frontend/src/coral/imports/human.png differ
diff --git a/src/frontend/src/coral/modules/Chat.css b/src/frontend/src/coral/modules/Chat.css
new file mode 100644
index 000000000..e7e0a3ca8
--- /dev/null
+++ b/src/frontend/src/coral/modules/Chat.css
@@ -0,0 +1,304 @@
+.chat-container {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ min-height: 0;
+
+ margin: 0 auto; /* ✅ centers it */
+}
+
+.messages {
+ flex: 1;
+ overflow-y: auto;
+ overflow-x: hidden;
+ padding: 0 16px 16px 16px;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ margin-left: 0;
+ margin-right: 0;
+
+ p {
+ margin: 8px 0;
+ white-space: pre-wrap;
+ line-height: 1.5rem;
+ }
+
+ li {
+ white-space: normal;
+ margin: 0;
+ }
+
+ ol,
+ ul {
+ display: block;
+ list-style-type: decimal;
+ margin-block-start: 0px;
+ margin-block-end: 0px;
+ margin-inline-start: 0px;
+ margin-inline-end: 0px;
+ padding-inline-start: 24px;
+ unicode-bidi: isolate;
+ }
+
+ a {
+ color: var(--colorBrandForeground1);
+ }
+}
+
+code.language-tsx,
+code.language-bash {
+ white-space: pre-wrap;
+ word-break: break-word;
+ background-color: var(--colorNeutralBackground1);
+
+ border-radius: 4px;
+ /* border: 1px solid var(--colorNeutralStroke1); */
+}
+
+code.language-tsx {
+ display: flex;
+}
+
+pre {
+ display: inline-block;
+ /* Shrink-wrap to content */
+ max-width: 100%;
+ /* Do not exceed parent's width */
+ white-space: pre-wrap;
+ /* Allow wrapping of long lines */
+ word-break: break-word;
+ /* Break words if necessary */
+ overflow-wrap: break-word;
+ /* Provide fallback for older browsers */
+ background-color: var(--colorNeutralBackground1);
+ padding: 4px 8px;
+ border-radius: 4px;
+ overflow: scroll;
+}
+
+pre code.language-bash {
+ white-space: pre-wrap;
+ word-break: break-word;
+ overflow-wrap: break-word;
+
+ /* Optional: add padding, background, border-radius, etc. */
+ background-color: transparent;
+}
+
+.message {
+ /* Prevents messages from getting too wide */
+ display: inline-block;
+ /* Ensures width only expands as needed */
+ word-wrap: break-word;
+ /* Prevents overflow issues */
+ word-break: break-word;
+
+ box-sizing: border-box;
+ margin-left: 0 !important;
+ margin-right: 0 !important;
+}
+
+.user {
+ background-color: var(--colorNeutralBackground2);
+ color: var(--colorNeutralForeground2);
+ align-self: flex-end;
+ padding: 2px 16px;
+ border-radius: 6px;
+}
+
+.assistant {
+ color: var(--colorNeutralForeground2);
+ align-self: flex-start;
+ margin: 16px 0 0 0;
+ width: 100%;
+}
+
+.input-container {
+ display: flex;
+ /* padding: 16px; */
+ /* border-top: 1px solid #ccc; */
+}
+
+input {
+ flex: 1;
+ padding: 5px;
+ border: 1px solid #ccc;
+}
+
+button {
+ margin-left: 5px;
+ padding: 5px 10px;
+ background-color: #0078d4;
+ color: white;
+ border: none;
+ cursor: pointer;
+}
+
+.typing-indicator {
+ font-size: 14px;
+ color: #666;
+}
+
+.typing-indicator .dots {
+ animation: blink 1.5s infinite;
+}
+
+@keyframes blink {
+ 0% {
+ opacity: 0.3;
+ }
+
+ 50% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0.3;
+ }
+}
+
+/* Input Container */
+.input-wrapper {
+ /* margin: 0 16px 16px 16px; */
+ display: inline-flex;
+ /* Allows height to expand dynamically */
+ flex-direction: column;
+ gap: 8px;
+ align-items: stretch;
+ width: 100%;
+ padding: 8px;
+ border-radius: var(--borderRadiusLarge);
+ background-color: var(--colorNeutralBackground1);
+ border: 1px solid var(--colorNeutralStroke1);
+ transition: border-color 0.2s ease-in-out;
+ position: relative;
+ box-sizing: border-box;
+}
+
+/* Hover and Active States */
+.input-wrapper:hover {
+ border-color: var(--colorNeutralStroke1Hover);
+}
+
+.input-wrapper:active {
+ border-color: var(--colorNeutralStroke1Pressed);
+}
+
+/* Focus State */
+.input-wrapper.focused {
+ border-color: var(--colorNeutralStroke1Pressed);
+}
+
+/* Input Field */
+.input-field {
+ resize: none;
+ overflow-y: scroll;
+ height: auto;
+ /* Ensures it expands dynamically */
+ min-height: 24px;
+ /* Keeps it stable initially and while typing */
+ max-height: 150px;
+ padding: 8px;
+ /* Add padding while maintaining the height */
+ background-color: transparent;
+ border: none;
+ outline: none;
+ font-family: var(--fontFamilyBase);
+ font-size: var(--fontSizeBase300);
+ font-weight: var(--fontWeightRegular);
+ color: var(--colorNeutralForeground1);
+ line-height: 1.5;
+ box-sizing: border-box;
+ /* Ensures padding doesn’t increase total height */
+}
+
+/* Send Button */
+.send-button {
+ background-color: transparent;
+ border: none;
+ cursor: pointer;
+ padding: 4px 8px;
+ color: var(--colorBrandForeground1);
+ transition: color 0.2s ease-in-out;
+}
+
+.send-button:hover {
+ color: var(--colorBrandForegroundHover);
+}
+
+.send-button:active {
+ color: var(--colorBrandForegroundPressed);
+}
+
+/* Focus Indicator (Purple Line Animation, Bottom Only) */
+.focus-indicator {
+ position: absolute;
+ bottom: 0;
+ /* Ensures it's at the bottom */
+ left: 0;
+ width: 100%;
+ height: 2px;
+ background-color: var(--colorCompoundBrandStroke);
+ transform: scaleX(0);
+ transition: transform 0.2s ease-in-out;
+}
+
+.input-wrapper.focused .focus-indicator {
+ transform: scaleX(1);
+ /* Expands when input is focused */
+}
+
+/* AI Generated Tag Container */
+.ai-tag-container {
+ margin-bottom: 4px;
+ /* Adds a small gap between the tag and the message */
+ display: flex;
+ align-items: center;
+}
+
+.assistant-footer {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 6px;
+ margin-left: -10px;
+}
+
+.assistant-actions {
+ display: flex;
+ /* gap: 8px; */
+}
+
+.messages {
+ flex: 1;
+ overflow-y: auto;
+ overflow-x: hidden;
+ display: flex;
+
+ align-items: center;
+ padding: 0 16px 16px 16px;
+}
+
+.message-wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+ width: 100%;
+ max-width: 768px;
+
+}
+
+.scroll-to-bottom {
+ position: absolute;
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 1000;
+ /* Optional styling */
+ border-radius: 50%;
+ padding: 8px;
+ cursor: pointer;
+ box-shadow: var(--shadow8);
+ margin-bottom: 16px;
+}
diff --git a/src/frontend/src/coral/modules/Chat.tsx b/src/frontend/src/coral/modules/Chat.tsx
new file mode 100644
index 000000000..74f5590e7
--- /dev/null
+++ b/src/frontend/src/coral/modules/Chat.tsx
@@ -0,0 +1,278 @@
+import React, { useState, useEffect, useRef } from "react";
+import ReactMarkdown from "react-markdown";
+import remarkGfm from "remark-gfm";
+import rehypePrism from "rehype-prism";
+import {
+ Body1,
+ Button,
+ Tag,
+ Tooltip as FluentTooltip,
+ ToolbarDivider,
+} from "@fluentui/react-components";
+import { Copy, Send } from "../imports/bundleicons";
+import { ChatDismiss20Regular, HeartRegular } from "@fluentui/react-icons";
+import ChatInput from "./ChatInput";
+import "./Chat.css";
+import "./prism-material-oceanic.css";
+// import { chatService } from "../services/chatService";
+import HeaderTools from "../components/Header/HeaderTools";
+
+interface ChatProps {
+ userId: string;
+ children?: React.ReactNode;
+ onSendMessage?: (
+ input: string,
+ history: { role: string; content: string }[]
+ ) => AsyncIterable | Promise;
+ onSaveMessage?: (
+ userId: string,
+ messages: { role: string; content: string }[]
+ ) => void;
+ onLoadHistory?: (
+ userId: string
+ ) => Promise<{ role: string; content: string }[]>;
+ onClearHistory?: (userId: string) => void;
+}
+
+const Chat: React.FC = ({
+ userId,
+ children,
+ onSendMessage,
+ onSaveMessage,
+ onLoadHistory,
+ onClearHistory,
+}) => {
+ const [messages, setMessages] = useState<{ role: string; content: string }[]>([]);
+ const [input, setInput] = useState("");
+ const [isTyping, setIsTyping] = useState(false);
+ const [showScrollButton, setShowScrollButton] = useState(false);
+ const [inputHeight, setInputHeight] = useState(0);
+ const [currentConversationId, setCurrentConversationId] = useState(undefined);
+
+ const messagesContainerRef = useRef(null);
+ const inputContainerRef = useRef(null);
+
+ useEffect(() => {
+ const loadHistory = async () => {
+ try {
+ if (onLoadHistory) {
+ const historyMessages = await onLoadHistory(userId);
+ if (historyMessages && historyMessages.length > 0) {
+ setMessages(historyMessages);
+ return;
+ }
+ }
+ // const chatMessages = await chatService.getUserHistory(userId);
+ // setMessages(chatMessages);
+ } catch (err) {
+ console.log("Failed to load chat history.", err);
+ }
+ };
+ loadHistory();
+ }, [onLoadHistory, userId]);
+
+ useEffect(() => {
+ if (messagesContainerRef.current) {
+ messagesContainerRef.current.scrollTop = messagesContainerRef.current.scrollHeight;
+ setShowScrollButton(false);
+ }
+ }, [messages]);
+
+ useEffect(() => {
+ const container = messagesContainerRef.current;
+ if (!container) return;
+ const handleScroll = () => {
+ const { scrollTop, scrollHeight, clientHeight } = container;
+ setShowScrollButton(scrollTop + clientHeight < scrollHeight - 100);
+ };
+ container.addEventListener("scroll", handleScroll);
+ return () => container.removeEventListener("scroll", handleScroll);
+ }, []);
+
+ useEffect(() => {
+ if (inputContainerRef.current) {
+ setInputHeight(inputContainerRef.current.offsetHeight);
+ }
+ }, [input]);
+
+ const scrollToBottom = () => {
+ messagesContainerRef.current?.scrollTo({
+ top: messagesContainerRef.current.scrollHeight,
+ behavior: "smooth",
+ });
+ setShowScrollButton(false);
+ };
+
+ const handleCopy = (text: string) => {
+ navigator.clipboard.writeText(text).catch((err) => {
+ console.log("Failed to copy text:", err);
+ });
+ };
+
+ const isAsyncIterable = (value: any): value is AsyncIterable => {
+ return value !== null && typeof value === 'object' && Symbol.asyncIterator in value;
+ };
+
+ const sendMessage = async () => {
+ if (!input.trim()) return;
+
+ const updatedMessages = [...messages, { role: "user", content: input }];
+ setMessages(updatedMessages);
+ setInput("");
+ setIsTyping(true);
+
+ try {
+ if (onSendMessage) {
+ setMessages([...updatedMessages, { role: "assistant", content: "" }]);
+ const response = onSendMessage(input, updatedMessages);
+
+ if (isAsyncIterable(response)) {
+ let assistantContent = "";
+ for await (const chunk of response) {
+ assistantContent += chunk;
+ setMessages((prev) => {
+ const updated = [...prev];
+ updated[updated.length - 1] = {
+ role: "assistant",
+ content: assistantContent,
+ };
+ return updated;
+ });
+ }
+ onSaveMessage?.(userId, [...updatedMessages, { role: "assistant", content: assistantContent }]);
+ } else {
+ const assistantResponse = await response;
+ const newHistory = [...updatedMessages, { role: "assistant", content: assistantResponse }];
+ setMessages(newHistory);
+ onSaveMessage?.(userId, newHistory);
+ }
+ } else {
+ // const response = await chatService.sendMessage(userId, input, currentConversationId);
+ // setCurrentConversationId(response.conversation_id);
+ // const assistantMessage = { role: "assistant", content: response.assistant_response };
+ // setMessages([...updatedMessages, assistantMessage]);
+ }
+ } catch (err) {
+ console.log("Send Message Error:", err);
+ setMessages([
+ ...updatedMessages,
+ { role: "assistant", content: "Oops! Something went wrong sending your message." },
+ ]);
+ } finally {
+ setIsTyping(false);
+ }
+ };
+
+ const clearChat = async () => {
+ try {
+ if (onClearHistory) {
+ onClearHistory(userId);
+ } else {
+ // await chatService.clearChatHistory(userId);
+ }
+ setMessages([]);
+ setCurrentConversationId(undefined);
+ } catch (err) {
+ console.log("Failed to clear chat history:", err);
+ }
+ };
+
+ return (
+
+
+
{messages.map((msg, index) => (
+
+
+
+
+ {msg.content}
+
+ {msg.role === "assistant" && (
+
+
+ handleCopy(msg.content)}
+ title="Copy Response"
+ appearance="subtle"
+ style={{ height: 28, width: 28 }}
+ icon={ }
+ />
+ console.log("Heart clicked for response:", msg.content)}
+ title="Like"
+ appearance="subtle"
+ style={{ height: 28, width: 28 }}
+ icon={ }
+ />
+
+
+ )}
+
+
+
+ ))}
+
+
+ {isTyping && (
+
+ Thinking...
+
+ )}
+
+
+ {showScrollButton && (
+
+ Back to bottom
+
+ )}
+
+
+
+
+ }
+ disabled={isTyping || !input.trim()}
+ />
+
+ {messages.length > 0 && (
+
+
+ }
+ disabled={isTyping || messages.length === 0} />
+
+
+
+ )}
+
+
+
+
+
+
+
+
+ );
+};
+
+export default Chat;
diff --git a/src/frontend/src/coral/modules/ChatExample.tsx b/src/frontend/src/coral/modules/ChatExample.tsx
new file mode 100644
index 000000000..66aed981a
--- /dev/null
+++ b/src/frontend/src/coral/modules/ChatExample.tsx
@@ -0,0 +1,127 @@
+import React from 'react';
+import '../components/Content/Chat.css';
+
+/**
+ * ChatExample - A component that mimics the conversation flow seen in the UI mockup
+ */
+const ChatExample: React.FC = () => {
+ return (
+
+
+ {/* System action message */}
+
+
+ Help me start onboarding Jessica.
+
+
+
+ {/* Bot message */}
+
+
+
+ Sounds good! Want me to start with a background check?
+
+
+ 👍
+ 👎
+ 🔄
+
+
+
+ {/* System action message */}
+
+
+ {/* Bot message */}
+
+
+
+ You got it! I've initiated a background check and everything looks good to go— You're ready to move onto helping Jessica set up and Office 365 account. Want me to hand that over to your Manager Agent?
+
+
+ 👍
+ 👎
+ 🔄
+
+
+
+ {/* System action message */}
+
+
+ Let's skip that step for now
+
+
+
+ {/* Bot message */}
+
+
+
+ Alright, let's skip Office 365 onboarding.
+
+ Want to move onto helping get her set up with a laptop for now? I can call your IT Agent.
+
+
+ 👍
+ 👎
+ 🔄
+
+
+
+ {/* System action message */}
+
+
+ {/* Bot message */}
+
+
+
+ Nice move - okay we've set her up with a Surface Laptop 15 with a Snapdragon Elite. Given her role as a Product Manager, this should be more than enough power to get her killing it through her workflows.
+
+ We can now move onto registering her with benefit— want me to get that going?
+
+
+ 👍
+ 👎
+ 🔄
+
+
+
+
+ {/* Input area */}
+
+
+
+ ➤
+
+
+
IT Agent and HR Agent are working together...
+
AI-generated content may be incorrect
+
+
+
+ );
+};
+
+export default ChatExample;
\ No newline at end of file
diff --git a/src/frontend/src/coral/modules/ChatInput.tsx b/src/frontend/src/coral/modules/ChatInput.tsx
new file mode 100644
index 000000000..98c1a476c
--- /dev/null
+++ b/src/frontend/src/coral/modules/ChatInput.tsx
@@ -0,0 +1,163 @@
+import React, {
+ useRef,
+ useState,
+ useEffect,
+ forwardRef,
+ useImperativeHandle,
+} from "react";
+import {
+ Tag,
+ Tooltip as FluentTooltip,
+ Caption1,
+} from "@fluentui/react-components";
+import HeaderTools from "../components/Header/HeaderTools";
+
+// ✅ Props definition
+interface ChatInputProps {
+ value: string;
+ onChange: (val: string) => void;
+ onEnter?: () => void;
+ placeholder?: string;
+ children?: React.ReactNode;
+ disabledChat?: boolean;
+}
+
+// ✅ ForwardRef component
+const ChatInput = forwardRef(
+ (
+ {
+ value,
+ onChange,
+ onEnter,
+ placeholder = "Type a message...",
+ children,
+ disabledChat,
+ },
+ ref
+ ) => {
+ const [isFocused, setIsFocused] = useState(false);
+ const textareaRef = useRef(null);
+ const inputContainerRef = useRef(null);
+
+ // ✅ Allow parent to access textarea DOM node
+ useImperativeHandle(ref, () => textareaRef.current as HTMLTextAreaElement);
+
+ useEffect(() => {
+ if (textareaRef.current) {
+ textareaRef.current.style.height = "auto";
+ textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
+ }
+ }, [value]);
+
+ return (
+
+
+
+
+
+
+ AI-generated content may be incorrect
+
+
+ );
+ }
+);
+
+export default ChatInput;
diff --git a/src/frontend/src/coral/modules/prism-material-oceanic.css b/src/frontend/src/coral/modules/prism-material-oceanic.css
new file mode 100644
index 000000000..a48250839
--- /dev/null
+++ b/src/frontend/src/coral/modules/prism-material-oceanic.css
@@ -0,0 +1,79 @@
+/* Light Mode (Default) */
+:root {
+ --color-text: #1e293b;
+ --color-selection: #cbd5e1;
+
+ --color-atrule: #7c3aed;
+ --color-attr-name: #ea580c;
+ --color-attr-value: #15803d;
+ --color-boolean: #7c3aed;
+ --color-comment: #64748b;
+ --color-function: #7c3aed;
+ --color-number: #f97316;
+ --color-string: #15803d;
+ --color-tag: #e11d48;
+ --color-punctuation: #2563eb;
+}
+
+/* Dark Mode */
+body.dark-mode {
+ --color-text: #c3cee3;
+ --color-selection: #363636;
+
+ --color-atrule: #c792ea;
+ --color-attr-name: #ffcb6b;
+ --color-attr-value: #c3e88d;
+ --color-boolean: #c792ea;
+ --color-comment: #546e7a;
+ --color-function: #c792ea;
+ --color-number: #fd9170;
+ --color-string: #c3e88d;
+ --color-tag: #f07178;
+ --color-punctuation: #89ddff;
+}
+
+/* Base Syntax Highlighting */
+code[class*="language-"],
+pre[class*="language-"] {
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ word-wrap: normal;
+ color: var(--color-text);
+ font-family: Roboto Mono, monospace;
+ font-size: .95em;
+ line-height: 1.8em;
+ tab-size: 4;
+ hyphens: none;
+}
+
+code[class*="language-"]::selection,
+pre[class*="language-"]::selection {
+ background: var(--color-selection);
+}
+
+:not(pre) > code[class*="language-"] {
+ white-space: normal;
+ border-radius: 0.2em;
+ padding: 0.1em;
+}
+
+pre[class*="language-"] {
+ overflow: auto;
+ position: relative;
+ margin: 0.5em 0;
+ padding: 1.25em 1em;
+}
+
+/* Token Colors */
+.token.atrule { color: var(--color-atrule); }
+.token.attr-name { color: var(--color-attr-name); }
+.token.attr-value { color: var(--color-attr-value); }
+.token.boolean { color: var(--color-boolean); }
+.token.comment { color: var(--color-comment); }
+.token.function { color: var(--color-function); }
+.token.number { color: var(--color-number); }
+.token.string { color: var(--color-string); }
+.token.tag { color: var(--color-tag); }
+.token.punctuation { color: var(--color-punctuation); }
\ No newline at end of file
diff --git a/src/frontend/src/index.css b/src/frontend/src/index.css
new file mode 100644
index 000000000..d9a069000
--- /dev/null
+++ b/src/frontend/src/index.css
@@ -0,0 +1,46 @@
+body, html, :root {
+ min-height: 100vh;
+ box-sizing: border-box;
+ padding: 0;
+ margin: 0;
+}
+
+
+/* Global Custom Scrollbar */
+::-webkit-scrollbar {
+ overflow-y: auto; /* Ensure scrollable content */
+ scrollbar-width: thin; /* For Firefox */
+ scrollbar-color: rgba(100, 100, 100, 0.7) transparent; /* For Firefox */
+ }
+
+ /* Webkit-based browsers */
+ ::-webkit-scrollbar {
+ width: 6px;
+ }
+
+ ::-webkit-scrollbar-thumb {
+ background-color: rgba(100, 100, 100, 0.7);
+ border-radius: 3px;
+ }
+
+ ::-webkit-scrollbar-thumb:hover {
+ background-color: rgba(100, 100, 100, 1);
+ }
+
+ ::-webkit-scrollbar-track {
+ /* background: red; */
+ }
+
+ * {
+ -webkit-overflow-scrolling: touch;
+ scroll-behavior: smooth;
+ }
+
+ .chart-container canvas {
+ --chartBarColor: var(--colorBrandBackground);
+ --chartHoverColor: var(--colorBrandBackgroundHover);
+ --chartBorderColor: var(--colorBrandForeground1);
+ --chartLineColor: var(--colorBrandForeground1);
+ --chartPointColor: var(--colorBrandBackground);
+ --chartPointBorderColor: var(--colorBrandForeground1);
+}
diff --git a/src/frontend/src/index.tsx b/src/frontend/src/index.tsx
new file mode 100644
index 000000000..0ece07e2e
--- /dev/null
+++ b/src/frontend/src/index.tsx
@@ -0,0 +1,80 @@
+import React, { StrictMode, useEffect, useState } from 'react';
+import ReactDOM from 'react-dom/client';
+import './index.css';
+import App from './App';
+import reportWebVitals from './reportWebVitals';
+import { FluentProvider, teamsLightTheme, teamsDarkTheme } from "@fluentui/react-components";
+import { setEnvData, setApiUrl, config as defaultConfig, toBoolean, getUserInfo, setUserInfoGlobal } from './api/config';
+import { UserInfo } from './models';
+const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement);
+
+const AppWrapper = () => {
+ // State to store the current theme
+ const [isConfigLoaded, setIsConfigLoaded] = useState(false);
+ const [isUserInfoLoaded, setIsUserInfoLoaded] = useState(false);
+ const [isDarkMode, setIsDarkMode] = useState(
+ window.matchMedia("(prefers-color-scheme: dark)").matches
+ );
+ type ConfigType = typeof defaultConfig;
+ const [config, setConfig] = useState(defaultConfig);
+ useEffect(() => {
+ const initConfig = async () => {
+ window.appConfig = config;
+ setEnvData(config);
+ setApiUrl(config.API_URL);
+
+ try {
+ const response = await fetch('/config');
+ let config = defaultConfig;
+ if (response.ok) {
+ config = await response.json();
+ config.ENABLE_AUTH = toBoolean(config.ENABLE_AUTH);
+ }
+
+ window.appConfig = config;
+ setEnvData(config);
+ setApiUrl(config.API_URL);
+ setConfig(config);
+ let defaultUserInfo = config.ENABLE_AUTH ? await getUserInfo() : ({} as UserInfo);
+ window.userInfo = defaultUserInfo;
+ setUserInfoGlobal(defaultUserInfo);
+
+ } catch (error) {
+ console.info("frontend config did not load from python", error);
+ } finally {
+ setIsConfigLoaded(true);
+ setIsUserInfoLoaded(true);
+ }
+ };
+
+ initConfig(); // Call the async function inside useEffect
+ }, []);
+ // Effect to listen for changes in the user's preferred color scheme
+ useEffect(() => {
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
+
+ const handleThemeChange = (event: MediaQueryListEvent) => {
+ setIsDarkMode(event.matches);
+ document.body.classList.toggle("dark-mode", event.matches); // ✅ Add this
+ };
+
+ // Apply dark-mode class initially
+ document.body.classList.toggle("dark-mode", isDarkMode);
+
+ mediaQuery.addEventListener("change", handleThemeChange);
+ return () => mediaQuery.removeEventListener("change", handleThemeChange);
+ }, []);
+ if (!isConfigLoaded || !isUserInfoLoaded) return Loading...
;
+ return (
+
+
+
+
+
+ );
+};
+root.render( );
+// If you want to start measuring performance in your app, pass a function
+// to log results (for example: reportWebVitals(console.log))
+// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
+reportWebVitals();
diff --git a/src/frontend/src/models/agentMessage.tsx b/src/frontend/src/models/agentMessage.tsx
new file mode 100644
index 000000000..9e616345f
--- /dev/null
+++ b/src/frontend/src/models/agentMessage.tsx
@@ -0,0 +1,19 @@
+import { BaseModel } from './plan';
+
+/**
+ * Represents a message from an agent
+ */
+export interface AgentMessage extends BaseModel {
+ /** The type of data model */
+ data_type: "agent_message";
+ /** Session identifier */
+ session_id: string;
+ /** Plan identifier */
+ plan_id: string;
+ /** Content of the message */
+ content: string;
+ /** Source of the message (e.g., agent type) */
+ source: string;
+ /** Optional step identifier associated with the message */
+ step_id?: string;
+}
diff --git a/src/frontend/src/models/auth.tsx b/src/frontend/src/models/auth.tsx
new file mode 100644
index 000000000..9407708d4
--- /dev/null
+++ b/src/frontend/src/models/auth.tsx
@@ -0,0 +1,15 @@
+export type UserInfo = {
+ access_token: string;
+ expires_on: string;
+ id_token: string;
+ provider_name: string;
+ user_claims: any[];
+ user_email: string;
+ user_first_last_name: string;
+ user_id: string;
+};
+
+export type claim = {
+ typ: string;
+ val: string;
+};
\ No newline at end of file
diff --git a/src/frontend/src/models/enums.tsx b/src/frontend/src/models/enums.tsx
new file mode 100644
index 000000000..fc63baadf
--- /dev/null
+++ b/src/frontend/src/models/enums.tsx
@@ -0,0 +1,53 @@
+/**
+ * Enumerations used throughout the application
+ */
+
+/**
+ * Enumeration of agent types.
+ */
+export enum AgentType {
+ HUMAN = "Human_Agent",
+ HR = "Hr_Agent",
+ MARKETING = "Marketing_Agent",
+ PROCUREMENT = "Procurement_Agent",
+ PRODUCT = "Product_Agent",
+ GENERIC = "Generic_Agent",
+ TECH_SUPPORT = "Tech_Support_Agent",
+ GROUP_CHAT_MANAGER = "Group_Chat_Manager",
+ PLANNER = "Planner_Agent"
+}
+
+export enum role {
+ user = "user",
+ assistant = "assistant"
+}
+/**
+ * Enumeration of possible statuses for a step.
+ */
+export enum StepStatus {
+ PLANNED = "planned",
+ AWAITING_FEEDBACK = "awaiting_feedback",
+ APPROVED = "approved",
+ REJECTED = "rejected",
+ ACTION_REQUESTED = "action_requested",
+ COMPLETED = "completed",
+ FAILED = "failed"
+}
+
+/**
+ * Enumeration of possible statuses for a plan.
+ */
+export enum PlanStatus {
+ IN_PROGRESS = "in_progress",
+ COMPLETED = "completed",
+ FAILED = "failed"
+}
+
+/**
+ * Enumeration of human feedback statuses.
+ */
+export enum HumanFeedbackStatus {
+ REQUESTED = "requested",
+ ACCEPTED = "accepted",
+ REJECTED = "rejected"
+}
diff --git a/src/frontend/src/models/homeInput.tsx b/src/frontend/src/models/homeInput.tsx
new file mode 100644
index 000000000..a5458f161
--- /dev/null
+++ b/src/frontend/src/models/homeInput.tsx
@@ -0,0 +1,40 @@
+import { DocumentEdit20Regular, Person20Regular, Phone20Regular, ShoppingBag20Regular } from "@fluentui/react-icons";
+
+export interface QuickTask {
+ id: string;
+ title: string;
+ description: string;
+ icon: React.ReactNode;
+}
+
+export const quickTasks: QuickTask[] = [
+ {
+ id: "onboard",
+ title: "Onboard employee",
+ description: "Onboard a new employee, Jessica Smith.",
+ icon: ,
+ },
+ {
+ id: "mobile",
+ title: "Mobile plan query",
+ description: "Ask about roaming plans prior to heading overseas.",
+ icon: ,
+ },
+ {
+ id: "addon",
+ title: "Buy add-on",
+ description: "Enable roaming on mobile plan, starting next week.",
+ icon: ,
+ },
+ {
+ id: "press",
+ title: "Draft a press release",
+ description: "Write a press release about our current products.",
+ icon: ,
+ },
+];
+
+export interface HomeInputProps {
+ onInputSubmit: (input: string) => void;
+ onQuickTaskSelect: (taskDescription: string) => void;
+}
diff --git a/src/frontend/src/models/index.tsx b/src/frontend/src/models/index.tsx
new file mode 100644
index 000000000..da61c4e8e
--- /dev/null
+++ b/src/frontend/src/models/index.tsx
@@ -0,0 +1,19 @@
+/**
+ * Exports all model interfaces and enums
+ */
+
+// Export enums
+export * from './enums';
+
+// Export models
+export * from './plan';
+export * from './messages';
+export * from './inputTask';
+export * from './agentMessage';
+export * from './taskDetails';
+export * from './taskList';
+export * from './planPanelLeft';
+export * from './homeInput';
+export * from './auth'
+
+// Add other model exports as needed
diff --git a/src/frontend/src/models/inputTask.tsx b/src/frontend/src/models/inputTask.tsx
new file mode 100644
index 000000000..ba1f654ca
--- /dev/null
+++ b/src/frontend/src/models/inputTask.tsx
@@ -0,0 +1,23 @@
+/**
+ * Represents an input task sent by a user to initiate a plan
+ */
+export interface InputTask {
+ /** Optional session identifier (will be generated if not provided) */
+ session_id?: string;
+ /** The task description or goal */
+ description: string;
+}
+
+/**
+ * Response from the input task endpoint
+ */
+export interface InputTaskResponse {
+ /** Status message */
+ status: string;
+ /** Session identifier */
+ session_id: string;
+ /** Plan identifier */
+ plan_id: string;
+ /** The original task description */
+ description: string;
+}
diff --git a/src/frontend/src/models/messages.tsx b/src/frontend/src/models/messages.tsx
new file mode 100644
index 000000000..2d086c192
--- /dev/null
+++ b/src/frontend/src/models/messages.tsx
@@ -0,0 +1,115 @@
+import { AgentType, StepStatus, PlanStatus } from './enums';
+
+/**
+ * Message roles compatible with Semantic Kernel
+ */
+export enum MessageRole {
+ SYSTEM = "system",
+ USER = "user",
+ ASSISTANT = "assistant",
+ FUNCTION = "function"
+}
+
+/**
+ * Base class for chat messages
+ */
+export interface ChatMessage {
+ /** Role of the message sender */
+ role: MessageRole;
+ /** Content of the message */
+ content: string;
+ /** Additional metadata */
+ metadata: Record;
+}
+
+/**
+ * Message sent to request approval for a step
+ */
+export interface ApprovalRequest {
+ /** Step identifier */
+ step_id: string;
+ /** Plan identifier */
+ plan_id: string;
+ /** Session identifier */
+ session_id: string;
+ /** User identifier */
+ user_id: string;
+ /** Action to be performed */
+ action: string;
+ /** Agent assigned to this step */
+ agent: AgentType;
+}
+
+/**
+ * Message containing human feedback on a step
+ */
+export interface HumanFeedback {
+ /** Optional step identifier */
+ step_id?: string;
+ /** Plan identifier */
+ plan_id: string;
+ /** Session identifier */
+ session_id: string;
+ /** Whether the step is approved */
+ approved: boolean;
+ /** Optional feedback from human */
+ human_feedback?: string;
+ /** Optional updated action */
+ updated_action?: string;
+}
+
+/**
+ * Message containing human clarification on a plan
+ */
+export interface HumanClarification {
+ /** Plan identifier */
+ plan_id: string;
+ /** Session identifier */
+ session_id: string;
+ /** Clarification from human */
+ human_clarification: string;
+}
+
+/**
+ * Message sent to an agent to perform an action
+ */
+export interface ActionRequest {
+ /** Step identifier */
+ step_id: string;
+ /** Plan identifier */
+ plan_id: string;
+ /** Session identifier */
+ session_id: string;
+ /** Action to be performed */
+ action: string;
+ /** Agent assigned to this step */
+ agent: AgentType;
+}
+
+/**
+ * Message containing the response from an agent after performing an action
+ */
+export interface ActionResponse {
+ /** Step identifier */
+ step_id: string;
+ /** Plan identifier */
+ plan_id: string;
+ /** Session identifier */
+ session_id: string;
+ /** Result of the action */
+ result: string;
+ /** Status after performing the action */
+ status: StepStatus;
+}
+
+/**
+ * Message for updating the plan state
+ */
+export interface PlanStateUpdate {
+ /** Plan identifier */
+ plan_id: string;
+ /** Session identifier */
+ session_id: string;
+ /** Overall status of the plan */
+ overall_status: PlanStatus;
+}
diff --git a/src/frontend/src/models/plan.tsx b/src/frontend/src/models/plan.tsx
new file mode 100644
index 000000000..fc19aa716
--- /dev/null
+++ b/src/frontend/src/models/plan.tsx
@@ -0,0 +1,126 @@
+import { AgentType, PlanStatus, StepStatus, HumanFeedbackStatus } from './enums';
+
+/**
+ * Base interface with common fields
+ */
+export interface BaseModel {
+ /** Unique identifier for the model */
+ id: string;
+ /** Timestamp when the model was created or updated */
+ timestamp: string;
+}
+
+/**
+ * Represents a plan containing multiple steps.
+ */
+export interface Plan extends BaseModel {
+ /** The type of data model */
+ data_type: "plan";
+ /** Session identifier */
+ session_id: string;
+ /** User identifier */
+ user_id: string;
+ /** The initial goal or task description */
+ initial_goal: string;
+ /** Current status of the plan */
+ overall_status: PlanStatus;
+ /** Source of the plan */
+ source: string;
+ /** Optional summary of the plan */
+ summary?: string;
+ /** Optional clarification request */
+ human_clarification_request?: string;
+ /** Optional response to clarification request */
+ human_clarification_response?: string;
+}
+
+/**
+ * Represents an individual step (task) within a plan.
+ */
+export interface Step extends BaseModel {
+ /** The type of data model */
+ data_type: "step";
+ /** Plan identifier */
+ plan_id: string;
+ /** Session identifier (Partition key) */
+ session_id: string;
+ /** User identifier */
+ user_id: string;
+ /** Action to be performed */
+ action: string;
+ /** Agent assigned to this step */
+ agent: AgentType;
+ /** Current status of the step */
+ status: StepStatus;
+ /** Optional reply from the agent */
+ agent_reply?: string;
+ /** Optional feedback from human */
+ human_feedback?: string;
+ /** Optional human approval status */
+ human_approval_status?: HumanFeedbackStatus;
+ /** Optional updated action */
+ updated_action?: string;
+}
+export interface PlanMessage extends BaseModel {
+ /** The type of data model */
+ data_type: "agent_message";
+ /** Session identifier */
+ session_id: string;
+ /** User identifier */
+ user_id: string;
+ /** Plan identifier */
+ plan_id: string;
+ /** Message content */
+ content: string;
+ /** Source of the message */
+ source: string;
+ /** Step identifier */
+ step_id: string;
+}
+/**
+ * Represents a plan that includes its associated steps.
+ */
+export interface PlanWithSteps extends Plan {
+ /** Steps associated with this plan */
+ steps: Step[];
+ /** Total number of steps */
+ total_steps: number;
+ /** Count of steps in planned status */
+ planned: number;
+ /** Count of steps awaiting feedback */
+ awaiting_feedback: number;
+ /** Count of steps approved */
+ approved: number;
+ /** Count of steps rejected */
+ rejected: number;
+ /** Count of steps with action requested */
+ action_requested: number;
+ /** Count of steps completed */
+ completed: number;
+ /** Count of steps failed */
+ failed: number;
+}
+
+
+/**
+ * Interface for processed plan data
+ */
+export interface ProcessedPlanData {
+ plan: PlanWithSteps;
+ agents: AgentType[];
+ steps: Step[];
+ hasClarificationRequest: boolean;
+ hasClarificationResponse: boolean;
+ enableChat: boolean;
+ enableStepButtons: boolean;
+ messages: PlanMessage[];
+}
+
+export interface PlanChatProps {
+ planData: ProcessedPlanData;
+ input: string;
+ loading: boolean;
+ setInput: any;
+ submittingChatDisableInput: boolean;
+ OnChatSubmit: (message: string) => void;
+}
\ No newline at end of file
diff --git a/src/frontend/src/models/planPanelLeft.tsx b/src/frontend/src/models/planPanelLeft.tsx
new file mode 100644
index 000000000..aa74d48d3
--- /dev/null
+++ b/src/frontend/src/models/planPanelLeft.tsx
@@ -0,0 +1,4 @@
+export interface PlanPanelLefProps {
+ reloadTasks?: boolean;
+ onNewTaskButton: () => void;
+}
\ No newline at end of file
diff --git a/src/frontend/src/models/taskDetails.tsx b/src/frontend/src/models/taskDetails.tsx
new file mode 100644
index 000000000..6d7f8fde3
--- /dev/null
+++ b/src/frontend/src/models/taskDetails.tsx
@@ -0,0 +1,29 @@
+import { ProcessedPlanData, Step } from "./plan";
+
+export interface SubTask {
+ id: string;
+ name: string;
+ status: 'completed' | 'working' | 'removed';
+}
+
+export interface Agent {
+ id: string;
+ name: string;
+ description: string;
+ avatarUrl?: string;
+}
+
+export interface Human {
+ id: string;
+ name: string;
+ email: string;
+ avatarUrl?: string;
+}
+
+export interface TaskDetailsProps {
+ planData: ProcessedPlanData;
+ loading: boolean;
+ submittingChatDisableInput: boolean;
+ processingSubtaskId: string | null;
+ OnApproveStep: (step: Step, total: number, completed: number, approve: boolean) => void;
+}
\ No newline at end of file
diff --git a/src/frontend/src/models/taskList.tsx b/src/frontend/src/models/taskList.tsx
new file mode 100644
index 000000000..ee65bb991
--- /dev/null
+++ b/src/frontend/src/models/taskList.tsx
@@ -0,0 +1,14 @@
+export interface Task {
+ id: string;
+ name: string;
+ status: 'inprogress' | 'completed';
+ date?: string;
+}
+
+export interface TaskListProps {
+ inProgressTasks: Task[];
+ completedTasks: Task[];
+ onTaskSelect: (taskId: string) => void;
+ loading?: boolean;
+ selectedTaskId?: string;
+}
\ No newline at end of file
diff --git a/src/frontend/src/pages/HomePage.tsx b/src/frontend/src/pages/HomePage.tsx
new file mode 100644
index 000000000..fe3487430
--- /dev/null
+++ b/src/frontend/src/pages/HomePage.tsx
@@ -0,0 +1,70 @@
+import React, { useEffect, useState, useCallback } from 'react';
+import { useNavigate } from 'react-router-dom';
+import {
+ Button,
+ Spinner,
+ Toast,
+ ToastTitle,
+ ToastBody,
+ useToastController,
+ Toaster
+} from '@fluentui/react-components';
+import {
+ Add20Regular,
+ ErrorCircle20Regular,
+ Sparkle20Filled
+} from '@fluentui/react-icons';
+import '../styles/PlanPage.css';
+import CoralShellColumn from '../coral/components/Layout/CoralShellColumn';
+import CoralShellRow from '../coral/components/Layout/CoralShellRow';
+import Content from '../coral/components/Content/Content';
+import HomeInput from '@/components/content/HomeInput';
+import { NewTaskService } from '../services/NewTaskService';
+import PlanPanelLeft from '@/components/content/PlanPanelLeft';
+import ContentToolbar from '@/coral/components/Content/ContentToolbar';
+
+/**
+ * HomePage component - displays task lists and provides navigation
+ * Accessible via the route "/"
+ */
+const HomePage: React.FC = () => {
+ /**
+ * Handle new task creation from the "New task" button
+ * Resets textarea to empty state on HomePage
+ */
+ const handleNewTaskButton = useCallback(() => {
+ NewTaskService.handleNewTaskFromHome();
+ }, []);
+
+ /**
+ * Handle new task creation from input submission - placeholder for future implementation
+ */
+ const handleNewTask = useCallback((taskName: string) => {
+ console.log('Creating new task:', taskName);
+ }, []);
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
+
+export default HomePage;
\ No newline at end of file
diff --git a/src/frontend/src/pages/PlanPage.tsx b/src/frontend/src/pages/PlanPage.tsx
new file mode 100644
index 000000000..43934daf3
--- /dev/null
+++ b/src/frontend/src/pages/PlanPage.tsx
@@ -0,0 +1,215 @@
+import React, { useCallback, useEffect, useState } from "react";
+import { useParams, useNavigate } from "react-router-dom";
+import {
+ Text,
+ ToggleButton,
+} from "@fluentui/react-components";
+import "../styles/PlanPage.css";
+import CoralShellColumn from "../coral/components/Layout/CoralShellColumn";
+import CoralShellRow from "../coral/components/Layout/CoralShellRow";
+import Content from "../coral/components/Content/Content";
+import { NewTaskService } from "../services/NewTaskService";
+import { PlanDataService } from "../services/PlanDataService";
+import { Step, ProcessedPlanData } from "@/models";
+import PlanPanelLeft from "@/components/content/PlanPanelLeft";
+import ContentToolbar from "@/coral/components/Content/ContentToolbar";
+import PlanChat from "@/components/content/PlanChat";
+import PlanPanelRight from "@/components/content/PlanPanelRight";
+import InlineToaster, {
+ useInlineToaster,
+} from "../components/toast/InlineToaster";
+import Octo from "../coral/imports/Octopus.png"; // 🐙 Animated PNG loader
+import PanelRightToggles from "@/coral/components/Header/PanelRightToggles";
+import { TaskListSquareLtr } from "@/coral/imports/bundleicons";
+import LoadingMessage, { loadingMessages } from "@/coral/components/LoadingMessage";
+
+/**
+ * Page component for displaying a specific plan
+ * Accessible via the route /plan/{plan_id}
+ */
+const PlanPage: React.FC = () => {
+ const { planId } = useParams<{ planId: string }>();
+ const navigate = useNavigate();
+ const { showToast, dismissToast } = useInlineToaster();
+
+ const [input, setInput] = useState("");
+ const [planData, setPlanData] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [submittingChatDisableInput, setSubmitting] = useState(false);
+ const [error, setError] = useState(null);
+ const [processingSubtaskId, setProcessingSubtaskId] = useState(
+ null
+ );
+ const [reloadLeftList, setReloadLeftList] = useState(true);
+
+ const [loadingMessage, setLoadingMessage] = useState(loadingMessages[0]);
+
+ // 🌀 Cycle loading messages while loading
+ useEffect(() => {
+ if (!loading) return;
+ let index = 0;
+ const interval = setInterval(() => {
+ index = (index + 1) % loadingMessages.length;
+ setLoadingMessage(loadingMessages[index]);
+ }, 2000);
+ return () => clearInterval(interval);
+ }, [loading]);
+
+ const loadPlanData = useCallback(
+ async (navigate: boolean = true) => {
+ if (!planId) return;
+
+ try {
+ setInput(""); // Clear input on new load
+ if (navigate) {
+ setPlanData(null);
+ setLoading(true);
+ setError(null);
+ setProcessingSubtaskId(null);
+ }
+
+ setError(null);
+ const data = await PlanDataService.fetchPlanData(planId);
+ console.log("Fetched plan data:", data);
+ setPlanData(data);
+ } catch (err) {
+ console.log("Failed to load plan data:", err);
+ setError(
+ err instanceof Error ? err : new Error("Failed to load plan data")
+ );
+ } finally {
+ setLoading(false);
+ }
+ },
+ [planId]
+ );
+
+ const handleOnchatSubmit = useCallback(
+ async (chatInput: string) => {
+
+ console.log("handleOnchatSubmit called with input:", chatInput);
+ if (!chatInput.trim()) {
+ showToast("Please enter a clarification", "error");
+ return;
+ }
+ setInput("");
+ if (!planData?.plan) return;
+ setSubmitting(true);
+ let id = showToast("Submitting clarification", "progress");
+ try {
+ await PlanDataService.submitClarification(
+ planData.plan.id,
+ planData.plan.session_id,
+ chatInput
+ );
+ setInput("");
+ dismissToast(id);
+ showToast("Clarification submitted successfully", "success");
+ await loadPlanData(false);
+ } catch (error) {
+ dismissToast(id);
+ showToast("Failed to submit clarification", "error");
+ console.log("Failed to submit clarification:", error);
+ } finally {
+ setInput("");
+ setSubmitting(false);
+ }
+ },
+ [planData, loadPlanData]
+ );
+
+ const handleApproveStep = useCallback(
+ async (step: Step, total: number, completed: number, approve: boolean) => {
+ setProcessingSubtaskId(step.id);
+ const toastMessage = approve ? "Approving step" : "Rejecting step";
+ let id = showToast(toastMessage, "progress");
+ setSubmitting(true);
+ try {
+ let approveRejectDetails = await PlanDataService.stepStatus(step, approve);
+ dismissToast(id);
+ showToast(`Step ${approve ? "approved" : "rejected"} successfully`, "success");
+ if (approveRejectDetails && Object.keys(approveRejectDetails).length > 0) {
+ await loadPlanData(false);
+ }
+ setReloadLeftList(total === completed);
+ } catch (error) {
+ dismissToast(id);
+ showToast(`Failed to ${approve ? "approve" : "reject"} step`, "error");
+ console.log(`Failed to ${approve ? "approve" : "reject"} step:`, error);
+ } finally {
+ setProcessingSubtaskId(null);
+ setSubmitting(false);
+ }
+ },
+ [loadPlanData]
+ );
+
+
+ useEffect(() => {
+ loadPlanData();
+ }, [loadPlanData]);
+
+ const handleNewTaskButton = () => {
+ NewTaskService.handleNewTaskFromPlan(navigate);
+ };
+
+ if (!planId) {
+ return (
+
+ Error: No plan ID provided
+
+ );
+ }
+
+ return (
+
+
+
+
+
+ {/* 🐙 Only replaces content body, not page shell */}
+ {loading ? (
+ <>
+
+ >
+ ) : (
+ <>
+ }
+ >
+
+ }
+ />
+
+
+
+ >
+ )}
+
+
+
+
+
+ );
+};
+
+export default PlanPage;
diff --git a/src/frontend/src/pages/index.tsx b/src/frontend/src/pages/index.tsx
new file mode 100644
index 000000000..c73f6fa91
--- /dev/null
+++ b/src/frontend/src/pages/index.tsx
@@ -0,0 +1,2 @@
+export { default as HomePage } from './HomePage';
+export { default as PlanPage } from './PlanPage';
\ No newline at end of file
diff --git a/src/frontend/src/react-app-env.d.ts b/src/frontend/src/react-app-env.d.ts
new file mode 100644
index 000000000..6431bc5fc
--- /dev/null
+++ b/src/frontend/src/react-app-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/src/frontend/src/reportWebVitals.ts b/src/frontend/src/reportWebVitals.ts
new file mode 100644
index 000000000..49a2a16e0
--- /dev/null
+++ b/src/frontend/src/reportWebVitals.ts
@@ -0,0 +1,15 @@
+import { ReportHandler } from 'web-vitals';
+
+const reportWebVitals = (onPerfEntry?: ReportHandler) => {
+ if (onPerfEntry && onPerfEntry instanceof Function) {
+ import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+ getCLS(onPerfEntry);
+ getFID(onPerfEntry);
+ getFCP(onPerfEntry);
+ getLCP(onPerfEntry);
+ getTTFB(onPerfEntry);
+ });
+ }
+};
+
+export default reportWebVitals;
diff --git a/src/frontend/src/reportWebVitals.tsx b/src/frontend/src/reportWebVitals.tsx
new file mode 100644
index 000000000..d95c0a66b
--- /dev/null
+++ b/src/frontend/src/reportWebVitals.tsx
@@ -0,0 +1,15 @@
+import { ReportHandler } from 'web-vitals';
+
+const reportWebVitals = (onPerfEntry?: ReportHandler) => {
+ if (onPerfEntry && onPerfEntry instanceof Function) {
+ import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+ getCLS(onPerfEntry);
+ getFID(onPerfEntry);
+ getFCP(onPerfEntry);
+ getLCP(onPerfEntry);
+ getTTFB(onPerfEntry);
+ });
+ }
+};
+
+export default reportWebVitals;
diff --git a/src/frontend/src/services/NewTaskService.tsx b/src/frontend/src/services/NewTaskService.tsx
new file mode 100644
index 000000000..0559e5061
--- /dev/null
+++ b/src/frontend/src/services/NewTaskService.tsx
@@ -0,0 +1,63 @@
+
+/**
+ * Service for handling "New Task" button functionality across different pages
+ * Provides reusable methods for navigating to homepage and resetting textarea
+ */
+export class NewTaskService {
+ /**
+ * Event name for textarea reset functionality
+ */
+ private static readonly RESET_TEXTAREA_EVENT = 'resetTextarea';
+
+ /**
+ * Handle new task action from PlanPage
+ * Navigates to homepage and resets textarea
+ * @param navigate - React Router navigate function
+ */
+ static handleNewTaskFromPlan(navigate: (to: string) => void): void {
+ // Navigate to homepage
+ navigate('/');
+
+ // Emit event to reset textarea after navigation
+ // Use setTimeout to ensure navigation completes first
+ setTimeout(() => {
+ NewTaskService.resetTextarea();
+ }, 100);
+ }
+
+ /**
+ * Handle new task action from HomePage
+ * Resets textarea to empty state
+ */
+ static handleNewTaskFromHome(): void {
+ NewTaskService.resetTextarea();
+ }
+
+ /**
+ * Reset textarea to empty state
+ * Emits a custom event that HomeInput component can listen to
+ */
+ static resetTextarea(): void {
+ const event = new CustomEvent(NewTaskService.RESET_TEXTAREA_EVENT);
+ window.dispatchEvent(event);
+ }
+
+ /**
+ * Add event listener for textarea reset
+ * Should be called in HomeInput component
+ * @param callback - Function to call when reset event is triggered
+ * @returns Cleanup function to remove the event listener
+ */
+ static addResetListener(callback: () => void): () => void {
+ const handleReset = () => {
+ callback();
+ };
+
+ window.addEventListener(NewTaskService.RESET_TEXTAREA_EVENT, handleReset);
+
+ // Return cleanup function
+ return () => {
+ window.removeEventListener(NewTaskService.RESET_TEXTAREA_EVENT, handleReset);
+ };
+ }
+}
diff --git a/src/frontend/src/services/PlanDataService.tsx b/src/frontend/src/services/PlanDataService.tsx
new file mode 100644
index 000000000..de56c5559
--- /dev/null
+++ b/src/frontend/src/services/PlanDataService.tsx
@@ -0,0 +1,135 @@
+import { PlanWithSteps, Step, AgentType, ProcessedPlanData, PlanMessage } from '@/models';
+import { apiService } from '@/api';
+
+
+/**
+ * Service for processing and managing plan data operations
+ */
+export class PlanDataService { /**
+ * Fetch plan details by plan ID and process the data
+ * @param planId Plan ID to fetch
+ * @returns Promise with processed plan data
+ */
+ static async fetchPlanData(planId: string): Promise {
+ try {
+ // Use optimized getPlanById method for better performance
+ const planBody = await apiService.getPlanById(planId);
+ return this.processPlanData(planBody.plan_with_steps, planBody.messages || []);
+ } catch (error) {
+ console.log('Failed to fetch plan data:', error);
+ throw error;
+ }
+ }
+
+ /**
+ * Process plan data to extract agents, steps, and clarification status
+ * @param plan PlanWithSteps object to process
+ * @returns Processed plan data
+ */
+ static processPlanData(plan: PlanWithSteps, messages: PlanMessage[]): ProcessedPlanData {
+ // Extract unique agents from steps
+ const uniqueAgents = new Set();
+ plan.steps.forEach(step => {
+ if (step.agent) {
+ uniqueAgents.add(step.agent);
+ }
+ });
+
+ // Convert Set to Array for easier handling
+ const agents = Array.from(uniqueAgents);
+
+ // Get all steps
+ const steps = plan.steps;
+
+ // Check if human_clarification_request is not null
+ const hasClarificationRequest = plan.human_clarification_request != null && plan.human_clarification_request.trim().length > 0;
+ const hasClarificationResponse = plan.human_clarification_response != null && plan.human_clarification_response.trim().length > 0;
+ const enableChat = hasClarificationRequest && !hasClarificationResponse;
+ const enableStepButtons = (hasClarificationRequest && hasClarificationResponse) || (!hasClarificationRequest && !hasClarificationResponse);
+ return {
+ plan,
+ agents,
+ steps,
+ hasClarificationRequest,
+ hasClarificationResponse,
+ enableChat,
+ enableStepButtons,
+ messages
+ };
+ }
+
+ /**
+ * Get steps for a specific agent type
+ * @param plan Plan with steps
+ * @param agentType Agent type to filter by
+ * @returns Array of steps for the specified agent
+ */
+ static getStepsForAgent(plan: PlanWithSteps, agentType: AgentType): Step[] {
+ return apiService.getStepsForAgent(plan, agentType);
+ }
+
+ /**
+ * Get steps that are awaiting human feedback
+ * @param plan Plan with steps
+ * @returns Array of steps awaiting feedback
+ */
+ static getStepsAwaitingFeedback(plan: PlanWithSteps): Step[] {
+ return apiService.getStepsAwaitingFeedback(plan);
+ }
+
+ /**
+ * Check if plan is complete
+ * @param plan Plan with steps
+ * @returns Boolean indicating if plan is complete
+ */
+ static isPlanComplete(plan: PlanWithSteps): boolean {
+ return apiService.isPlanComplete(plan);
+ }
+
+ /**
+ * Get plan completion percentage
+ * @param plan Plan with steps
+ * @returns Completion percentage (0-100)
+ */
+ static getPlanCompletionPercentage(plan: PlanWithSteps): number {
+ return apiService.getPlanCompletionPercentage(plan);
+ }
+
+ /**
+ * Approve a plan step
+ * @param step Step to approve
+ * @returns Promise with API response
+ */
+ static async stepStatus(step: Step, action: boolean): Promise<{ status: string }> {
+ try {
+
+
+ return apiService.stepStatus(
+ step.plan_id,
+ step.session_id,
+ action, // approved
+ step.id
+ );
+ } catch (error) {
+ console.log('Failed to change step status:', error);
+ throw error;
+ }
+ }
+
+
+ /**
+ * Submit human clarification for a plan
+ * @param planId Plan ID
+ * @param sessionId Session ID
+ * @param clarification Clarification text
+ * @returns Promise with API response
+ */
+ static async submitClarification(planId: string, sessionId: string, clarification: string) {
+ try {
+ return apiService.submitClarification(planId, sessionId, clarification);
+ } catch (error) {
+ console.log('Failed to submit clarification:', error);
+ throw error;
+ }
+ }
+}
diff --git a/src/frontend/src/services/TaskService.tsx b/src/frontend/src/services/TaskService.tsx
new file mode 100644
index 000000000..76bfd3c0c
--- /dev/null
+++ b/src/frontend/src/services/TaskService.tsx
@@ -0,0 +1,175 @@
+import { PlanWithSteps, PlanStatus } from '../models';
+import { Task } from '../models/taskList';
+import { apiService } from '../api/apiService';
+import { InputTask, InputTaskResponse } from '../models/inputTask';
+
+/**
+ * TaskService - Service for handling task-related operations and transformations
+ */
+export class TaskService {
+ /**
+ * Transform PlanWithSteps data into Task arrays for TaskList component
+ * @param plansData Array of PlanWithSteps to transform
+ * @returns Object containing inProgress and completed task arrays
+ */
+ static transformPlansToTasks(plansData: PlanWithSteps[]): { inProgress: Task[], completed: Task[] } {
+ if (!plansData || plansData.length === 0) {
+ return { inProgress: [], completed: [] };
+ }
+
+ const inProgress: Task[] = [];
+ const completed: Task[] = [];
+
+ plansData.forEach((plan) => {
+ const task: Task = {
+ id: plan.session_id,
+ name: plan.initial_goal,
+ status: apiService.isPlanComplete(plan) ? 'completed' : 'inprogress',
+ date: new Date(plan.timestamp).toLocaleDateString('en-US', {
+ month: 'short',
+ day: 'numeric',
+ hour: '2-digit',
+ minute: '2-digit'
+ })
+ };
+
+ // Categorize based on plan status and completion
+ if (plan.overall_status === PlanStatus.COMPLETED || apiService.isPlanComplete(plan)) {
+ completed.push(task);
+ } else {
+ inProgress.push(task);
+ }
+ });
+
+ return { inProgress, completed };
+ }
+
+ /**
+ * Get task statistics from task arrays
+ * @param inProgressTasks Array of in-progress tasks
+ * @param completedTasks Array of completed tasks
+ * @returns Object containing task count statistics
+ */
+ static getTaskStatistics(inProgressTasks: Task[], completedTasks: Task[]) {
+ return {
+ inProgressCount: inProgressTasks.length,
+ completedCount: completedTasks.length,
+ totalCount: inProgressTasks.length + completedTasks.length
+ };
+ }
+
+ /**
+ * Find a task by ID in either task array
+ * @param taskId The task ID to search for
+ * @param inProgressTasks Array of in-progress tasks
+ * @param completedTasks Array of completed tasks
+ * @returns The found task or undefined
+ */
+ static findTaskById(taskId: string, inProgressTasks: Task[], completedTasks: Task[]): Task | undefined {
+ return [...inProgressTasks, ...completedTasks].find(task => task.id === taskId);
+ }
+
+ /**
+ * Filter tasks by status
+ * @param tasks Array of tasks to filter
+ * @param status Status to filter by
+ * @returns Filtered array of tasks
+ */
+ static filterTasksByStatus(tasks: Task[], status: 'inprogress' | 'completed'): Task[] {
+ return tasks.filter(task => task.status === status);
+ }
+
+ /**
+ * Generate a session ID using the specified algorithm
+ * @returns Generated session ID in format "sid_" + timestamp + "_" + random
+ */
+ static generateSessionId(): string {
+ const timestamp = new Date().getTime();
+ const random = Math.floor(Math.random() * 10000);
+ return `sid_${timestamp}_${random}`;
+ }
+ /**
+ * Split subtask action into description and function/details parts
+ * @param action The full action string to split
+ * @returns Object containing description and functionOrDetails
+ */
+ static splitSubtaskAction(action: string): { description: string; functionOrDetails: string | null } {
+ // Check for "Function:" pattern (with period before Function)
+
+ const functionMatch = action.match(/^(.+?)\.\s*Function:\s*(.+)$/);
+ if (functionMatch) {
+ return {
+ description: functionMatch[1].trim(),
+ functionOrDetails: functionMatch[2].trim()
+ };
+ }
+
+ // Check for any colon pattern - split on first colon
+ const colonIndex = action.indexOf(':');
+ if (colonIndex !== -1) {
+ return {
+ description: action.substring(0, colonIndex).trim(),
+ functionOrDetails: null
+ };
+ }
+
+ // If no colon found, return the full action as description
+ return {
+ description: action,
+ functionOrDetails: null
+ };
+ }
+ /**
+ * Clean text by converting any non-alphanumeric character to spaces
+ * @param text The text string to clean
+ * @returns Cleaned text string with only letters, numbers, and spaces
+ */
+ static cleanTextToSpaces(text: string): string {
+ if (!text) return '';
+ // Replace any non-alphanumeric character with a space
+ let cleanedText = text.replace("Hr_Agent", "HR_Agent").trim().replace(/[^a-zA-Z0-9]/g, ' ');
+
+ // Clean up multiple spaces and trim
+ cleanedText = cleanedText.replace(/\s+/g, ' ').trim();
+
+ return cleanedText;
+ }
+
+ static cleanHRAgent(text: string): string {
+ if (!text) return '';
+ // Replace any non-alphanumeric character with a space
+ let cleanedText = text.replace("Hr_Agent", "HR Agent").replace("Hr Agent", "HR Agent").trim();
+
+
+ return cleanedText;
+ }
+ /**
+ * Submit an input task to create a new plan
+ * @param description Task description
+ * @returns Promise with the response containing session and plan IDs
+ */
+ static async submitInputTask(description: string): Promise {
+ const sessionId = this.generateSessionId();
+
+ const inputTask: InputTask = {
+ session_id: sessionId,
+ description: description
+ };
+
+ try {
+ return await apiService.submitInputTask(inputTask);
+ } catch (error: any) {
+ // You can customize this logic as needed
+ let message = "Failed to create task.";
+ if (error?.response?.data?.message) {
+ message = error.response.data.message;
+ } else if (error?.message) {
+ message = error.message;
+ }
+ // Throw a new error with a user-friendly message
+ throw new Error(message);
+ }
+ }
+}
+
+export default TaskService;
diff --git a/src/frontend/src/services/index.ts b/src/frontend/src/services/index.ts
new file mode 100644
index 000000000..d498dd380
--- /dev/null
+++ b/src/frontend/src/services/index.ts
@@ -0,0 +1 @@
+export { default as TaskService } from './TaskService';
diff --git a/src/frontend/src/setupTests.tsx b/src/frontend/src/setupTests.tsx
new file mode 100644
index 000000000..fc2198522
--- /dev/null
+++ b/src/frontend/src/setupTests.tsx
@@ -0,0 +1,5 @@
+// vitest-dom adds custom vitest matchers for asserting on DOM nodes.
+// allows you to do things like:
+// expect(element).toHaveTextContent(/react/i)
+// learn more: https://github.com/testing-library/jest-dom
+import '@testing-library/jest-dom';
diff --git a/src/frontend/src/styles/Chat.css b/src/frontend/src/styles/Chat.css
new file mode 100644
index 000000000..daf2e6d95
--- /dev/null
+++ b/src/frontend/src/styles/Chat.css
@@ -0,0 +1,324 @@
+.chat-container {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ min-height: 0;
+
+ margin: 0 auto; /* ✅ centers it */
+}
+
+.messages {
+ flex: 1;
+ overflow-y: auto;
+ overflow-x: hidden;
+ padding: 0 16px 16px 16px;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ margin-left: 0;
+ margin-right: 0;
+
+ p {
+ margin: 8px 0;
+ white-space: pre-wrap;
+ line-height: 1.5rem;
+ }
+
+ h5 {
+ margin: 12px 0;
+ white-space: pre-wrap;
+ line-height: 1.5rem;
+ border: 1px solid var(--colorNeutralStroke2);
+ background-color: var(--colorNeutralBackground1);
+ padding: 12px;
+ border-radius: 8px;
+ font-size: var(--fontSizeBase300);
+ font-weight: var(--fontWeightRegular);
+ }
+
+ li {
+ white-space: normal;
+ margin: 0;
+ }
+
+ ol,
+ ul {
+ display: block;
+ list-style-type: decimal;
+ margin-block-start: 0px;
+ margin-block-end: 0px;
+ margin-inline-start: 0px;
+ margin-inline-end: 0px;
+ padding-inline-start: 24px;
+ unicode-bidi: isolate;
+ }
+
+ a {
+ color: var(--colorBrandForeground1);
+ }
+}
+
+.plan-chat-message-content hr {
+ border: none;
+ border-top: 1px solid var(--colorNeutralStroke1); /* or any visible stroke */
+ margin: 16px 0;
+ width: 100%;
+ display: block;
+}
+
+code.language-tsx,
+code.language-bash {
+ white-space: pre-wrap;
+ word-break: break-word;
+ background-color: var(--colorNeutralBackground1);
+
+ border-radius: 4px;
+ /* border: 1px solid var(--colorNeutralStroke1); */
+}
+
+code.language-tsx {
+ display: flex;
+}
+
+pre {
+ display: inline-block;
+ /* Shrink-wrap to content */
+ max-width: 100%;
+ /* Do not exceed parent's width */
+ white-space: pre-wrap;
+ /* Allow wrapping of long lines */
+ word-break: break-word;
+ /* Break words if necessary */
+ overflow-wrap: break-word;
+ /* Provide fallback for older browsers */
+ background-color: var(--colorNeutralBackground1);
+ padding: 4px 8px;
+ border-radius: 4px;
+ overflow: scroll;
+}
+
+pre code.language-bash {
+ white-space: pre-wrap;
+ word-break: break-word;
+ overflow-wrap: break-word;
+
+ /* Optional: add padding, background, border-radius, etc. */
+ background-color: transparent;
+}
+
+.message {
+ /* Prevents messages from getting too wide */
+ display: inline-block;
+ /* Ensures width only expands as needed */
+ word-wrap: break-word;
+ /* Prevents overflow issues */
+ word-break: break-word;
+
+ box-sizing: border-box;
+ margin-left: 0 !important;
+ margin-right: 0 !important;
+}
+
+.user {
+ background-color: var(--colorBrandBackground2);
+ color: var(--colorNeutralForeground1);
+ align-self: flex-end;
+ padding: 2px 16px;
+ border-radius: 6px;
+}
+
+.assistant {
+ color: var(--colorNeutralForeground1);
+ align-self: flex-start;
+ margin: 16px 0 0 0;
+ width: 100%;
+}
+
+.input-container {
+ display: flex;
+ /* padding: 16px; */
+ /* border-top: 1px solid #ccc; */
+}
+
+input {
+ flex: 1;
+ padding: 5px;
+ border: 1px solid #ccc;
+}
+
+button {
+ margin-left: 5px;
+ padding: 5px 10px;
+ background-color: #0078d4;
+ color: white;
+ border: none;
+ cursor: pointer;
+}
+
+.typing-indicator {
+ font-size: 14px;
+ color: #666;
+}
+
+.typing-indicator .dots {
+ animation: blink 1.5s infinite;
+}
+
+@keyframes blink {
+ 0% {
+ opacity: 0.3;
+ }
+
+ 50% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0.3;
+ }
+}
+
+/* Input Container */
+.input-wrapper {
+ /* margin: 0 16px 16px 16px; */
+ display: inline-flex;
+ /* Allows height to expand dynamically */
+ flex-direction: column;
+ gap: 8px;
+ align-items: stretch;
+ width: 100%;
+ padding: 8px;
+ border-radius: var(--borderRadiusLarge);
+ background-color: var(--colorNeutralBackground1);
+ border: 1px solid var(--colorNeutralStroke1);
+ transition: border-color 0.2s ease-in-out;
+ position: relative;
+ box-sizing: border-box;
+}
+
+/* Hover and Active States */
+.input-wrapper:hover {
+ border-color: var(--colorNeutralStroke1Hover);
+}
+
+.input-wrapper:active {
+ border-color: var(--colorNeutralStroke1Pressed);
+}
+
+/* Focus State */
+.input-wrapper.focused {
+ border-color: var(--colorNeutralStroke1Pressed);
+}
+
+/* Input Field */
+.input-field {
+ resize: none;
+ overflow-y: scroll;
+ height: auto;
+ /* Ensures it expands dynamically */
+ min-height: 24px;
+ /* Keeps it stable initially and while typing */
+ max-height: 150px;
+ padding: 8px;
+ /* Add padding while maintaining the height */
+ background-color: transparent;
+ border: none;
+ outline: none;
+ font-family: var(--fontFamilyBase);
+ font-size: var(--fontSizeBase300);
+ font-weight: var(--fontWeightRegular);
+ color: var(--colorNeutralForeground1);
+ line-height: 1.5;
+ box-sizing: border-box;
+ /* Ensures padding doesn’t increase total height */
+}
+
+/* Send Button */
+.send-button {
+ background-color: transparent;
+ border: none;
+ cursor: pointer;
+ padding: 4px 8px;
+ color: var(--colorBrandForeground1);
+ transition: color 0.2s ease-in-out;
+}
+
+.send-button:hover {
+ color: var(--colorBrandForegroundHover);
+}
+
+.send-button:active {
+ color: var(--colorBrandForegroundPressed);
+}
+
+/* Focus Indicator (Purple Line Animation, Bottom Only) */
+.focus-indicator {
+ position: absolute;
+ bottom: 0;
+ /* Ensures it's at the bottom */
+ left: 0;
+ width: 100%;
+ height: 2px;
+ background-color: var(--colorCompoundBrandStroke);
+ transform: scaleX(0);
+ transition: transform 0.2s ease-in-out;
+}
+
+.input-wrapper.focused .focus-indicator {
+ transform: scaleX(1);
+ /* Expands when input is focused */
+}
+
+/* AI Generated Tag Container */
+.ai-tag-container {
+ margin-bottom: 4px;
+ /* Adds a small gap between the tag and the message */
+ display: flex;
+ align-items: center;
+}
+
+.assistant-footer {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 4px;
+ margin-left: -8px;
+}
+
+.assistant-actions {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.messages {
+ flex: 1;
+ overflow-y: auto;
+ overflow-x: hidden;
+ display: flex;
+
+ align-items: center;
+ padding: 40px 16px 16px 16px;
+}
+
+.message-wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: 32px;
+ width: 100%;
+ max-width: 768px;
+}
+
+.scroll-to-bottom {
+ position: absolute;
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 1000;
+ /* Optional styling */
+ border-radius: 50%;
+ padding: 8px;
+ cursor: pointer;
+ box-shadow: var(--shadow8);
+ margin-bottom: 16px;
+}
diff --git a/src/frontend/src/styles/HomeInput.css b/src/frontend/src/styles/HomeInput.css
new file mode 100644
index 000000000..766dfe745
--- /dev/null
+++ b/src/frontend/src/styles/HomeInput.css
@@ -0,0 +1,111 @@
+/* HomeInput Component Styles */
+
+.home-input-container {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+}
+
+.home-input-content {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ padding: 24px;
+ position: relative;
+}
+
+.home-input-center-content {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ max-width: 728px;
+ gap: 32px;
+}
+
+.home-input-title-wrapper {
+ text-align: center;
+ margin-bottom: 24px;
+}
+
+.home-input-input-section {
+ width: 100%;
+ margin-bottom: 32px;
+}
+
+.home-input-input-wrapper {
+ position: relative;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ padding: 12px 16px;
+ background-color: #fafafa; /* tokens.colorNeutralBackground1 */
+ border: 1px solid #d1d1d1; /* tokens.colorNeutralStroke1 */
+ border-radius: 8px;
+}
+
+.home-input-input-field {
+ width: 100%;
+ min-height: 44px;
+ padding: 8px 0;
+ border: none;
+ outline: none;
+ background-color: transparent;
+ font-size: 0.875rem; /* tokens.fontSizeBase300 */
+ color: #242424; /* tokens.colorNeutralForeground1 */
+ resize: none;
+}
+
+.home-input-input-field::placeholder {
+ color: #707070; /* tokens.colorNeutralForeground3 */
+}
+
+.home-input-send-button {
+ min-width: 32px;
+ height: 32px;
+ padding: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 4px;
+ background-color: #0f6cbd; /* tokens.colorBrandBackground */
+ color: #ffffff; /* tokens.colorNeutralForegroundInverted */
+ border: none;
+ cursor: pointer;
+}
+
+.home-input-quick-tasks-section {
+ width: 100%;
+ margin-top: 8px;
+}
+
+.home-input-quick-tasks-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 12px;
+}
+
+.home-input-quick-tasks {
+ display: flex;
+ gap: 12px;
+ flex-wrap: wrap;
+ justify-content: space-between;
+}
+
+.home-input-ai-footer {
+ padding-bottom: 8px;
+ margin-top: 8px;
+ text-align: center;
+ color: #707070; /* tokens.colorNeutralForeground3 */
+}
+
+.home-input-refresh-button {
+ font-size: 0.75rem; /* tokens.fontSizeBase200 */
+ color: #0f6cbd; /* tokens.colorBrandForeground1 */
+ cursor: pointer;
+ background: none;
+ border: none;
+ padding: 0;
+}
diff --git a/src/frontend/src/styles/PlanChat.css b/src/frontend/src/styles/PlanChat.css
new file mode 100644
index 000000000..d79eb0457
--- /dev/null
+++ b/src/frontend/src/styles/PlanChat.css
@@ -0,0 +1,51 @@
+/* PlanChat Component Styles */
+
+.plan-chat-message-content {
+ display: flex;
+ flex-direction: column;
+ white-space: pre-wrap;
+ width: 100%;
+}
+
+.plan-chat-scroll-button {
+ background-color: transparent;
+ border: 1px solid var(--colorNeutralStroke3);
+ backdrop-filter: saturate(180%) blur(16px);
+}
+
+.plan-chat-input-container {
+ display: flex;
+ width: 100%;
+ align-items: center;
+ justify-content: center;
+}
+
+.plan-chat-input-wrapper {
+ display: flex;
+ width: 100%;
+ max-width: 768px;
+ margin: 0px 16px;
+}
+
+
+/* NEW */
+
+.plan-chat-header {
+ display: flex;
+ justify-content: flex-start;
+ margin-bottom: 8px;
+}
+
+.plan-chat-speaker {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ font-size: 12px;
+ color: var(--colorNeutralForeground3, #666);
+}
+
+
+
+
+
+
diff --git a/src/frontend/src/styles/PlanPage.css b/src/frontend/src/styles/PlanPage.css
new file mode 100644
index 000000000..e4683fa00
--- /dev/null
+++ b/src/frontend/src/styles/PlanPage.css
@@ -0,0 +1,81 @@
+/* PlanPage.css */
+.plan-page-container {
+ max-width: 960px;
+ margin: 24px auto;
+ padding: 0 16px;
+}
+
+.plan-page-header {
+ display: flex;
+ align-items: center;
+ margin-bottom: 24px;
+ gap: 12px;
+}
+
+.plan-page-back-button {
+ padding: 8px;
+ min-width: auto;
+}
+
+.plan-page-title {
+ font-weight: 600;
+ font-size: 24px;
+}
+
+.plan-page-error {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 200px;
+}
+
+.plan-page-error .card-content {
+ padding: 0 16px 16px 16px;
+ text-align: center;
+}
+
+.error-header {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ color: #d13438;
+}
+
+.plan-page-content {
+ margin-top: 16px;
+}
+
+/* Loading state */
+.plan-page-loading {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 200px;
+}
+
+
+.loadingWrapper {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 12px;
+}
+
+
+/* Responsive design */
+@media (max-width: 768px) {
+ .plan-page-container {
+ margin: 16px auto;
+ padding: 0 12px;
+ }
+
+ .plan-page-title {
+ font-size: 20px;
+ }
+
+ .plan-page-header {
+ margin-bottom: 16px;
+ }
+}
diff --git a/src/frontend/src/styles/PlanPanelLeft.css b/src/frontend/src/styles/PlanPanelLeft.css
new file mode 100644
index 000000000..5a8831b44
--- /dev/null
+++ b/src/frontend/src/styles/PlanPanelLeft.css
@@ -0,0 +1,90 @@
+/* APP */
+
+.tab {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ color: var(--colorNeutralForeground2);
+ padding: 8px;
+ border-radius: 6px;
+ font-size: 14px;
+ text-decoration: none;
+ cursor: pointer;
+ transition: background-color 0.2s ease-in-out;
+}
+
+.tab:hover {
+ background-color: var(--colorSubtleBackgroundHover);
+}
+
+.tab:active {
+ background-color: var(--colorSubtleBackgroundPressed);
+}
+
+.tab.tab-new-task {
+ margin: 0px 8px;
+}
+
+.tab.tab-new-task-icon {
+ display: flex;
+ width: 40px;
+ height: 40px;
+ background-color: var(--colorNeutralBackground1);
+ justify-content: center;
+ align-items: center;
+ border-radius: 16px;
+ box-sizing: border-box;
+ /* background: #eeaedd;
+background: radial-gradient(circle, rgba(238, 174, 221, 1) 0%, rgba(117, 121, 235, 1) 100%);
+color: #2F2F4A; */
+}
+
+/* TASKLIST */
+
+.task-tab {
+ display: flex;
+ align-items: center;
+ padding: 8px 8px 8px 0;
+ color: var(--colorNeutralForeground2);
+ border-radius: 6px;
+ cursor: pointer;
+ transition: background-color 0.2s ease-in-out;
+ font-size: var(--fontSizeBase00);
+ gap: 14px;
+ min-height: 54px;
+ box-sizing: border-box;
+}
+
+.task-tab:hover {
+ background-color: var(--colorSubtleBackgroundHover);
+}
+
+.task-tab.active {
+ background-color: var(--colorNeutralBackground1Pressed);
+ color: var(--colorNeutralForeground1);
+ font-weight: 500;
+}
+
+.task-tab .sideNavTick {
+ width: 2px;
+ height: 100%;
+ min-height: 32px;
+ background-color: var(--colorCompoundBrandStroke);
+ opacity: 0;
+ flex-shrink: 0;
+ transition: opacity 0.2s ease-in-out;
+ margin-left: -8px;
+}
+
+.task-tab.active .sideNavTick {
+ opacity: 1;
+}
+
+.task-tab .task-menu-button {
+ opacity: 0;
+ transition: opacity 0.2s ease-in-out;
+}
+
+.task-tab:hover .task-menu-button {
+ opacity: 1;
+}
diff --git a/src/frontend/src/styles/TaskDetails.css b/src/frontend/src/styles/TaskDetails.css
new file mode 100644
index 000000000..5e40f1250
--- /dev/null
+++ b/src/frontend/src/styles/TaskDetails.css
@@ -0,0 +1,149 @@
+
+/* TaskDetails.css */
+
+.status-icon-completed {
+ color: var(--colorPaletteSeafoamBorderActive);
+}
+
+.status-icon-planned {
+ color: var(--colorNeutralStroke1);
+}
+
+.status-icon-rejected {
+ color: var(--colorNeutralStroke1);
+}
+
+.task-details-container {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ overflow: auto;
+}
+
+.task-details-section {
+ display: flex;
+ flex-direction: column;
+ border-bottom: 1px solid var(--colorNeutralStroke2);
+ padding: 0px 16px 24px 16px;
+ gap: 24px;
+}
+
+.task-details-progress-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.task-details-progress-card {
+ display: flex;
+ align-items: center;
+ padding: 12px 16px 12px 12px;
+ background-color: var(--colorNeutralBackground4);
+ /* border-radius: var(--borderRadiusXLarge); */
+ border-radius: 16px;
+ width: 100%;
+}
+
+.task-details-progress-icon {
+ position: relative;
+ width: 56px;
+ height: 56px;
+ margin-right: 16px;
+}
+
+.task-details-progress-text {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ padding-bottom: 2px;
+}
+
+.task-details-subtask-list {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+}
+
+.task-details-subtask-item {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ min-height: 32px;
+}
+
+.task-details-status-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 24px;
+ height: 24px;
+}
+
+.task-details-subtask-content {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex: 1;
+ gap: 8px;
+}
+
+.task-details-subtask-description {
+ font-size: var(--fontSizeBase300);
+ font-weight: var(--fontWeightSemibold);
+ flex: 1;
+}
+
+.task-details-action-buttons {
+ display: flex;
+ align-items: center;
+ flex-wrap: nowrap;
+}
+
+.task-details-action-button {
+ cursor: pointer;
+ padding: 4px;
+ border-radius: var(--borderRadiusSmall);
+}
+
+.task-details-action-button-disabled {
+ cursor: not-allowed;
+ padding: 4px;
+ border-radius: var(--borderRadiusSmall);
+}
+
+.task-details-agents-container {
+ display: flex;
+ flex-direction: column;
+}
+
+.task-details-agents-header {
+ padding: 18px 16px;
+ max-height: 56px;
+}
+
+.task-details-agents-list {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ padding: 0 16px 16px 16px;
+}
+
+.task-details-agent-card {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.task-details-agent-details {
+ display: flex;
+ flex-direction: column;
+}
+
+.task-details-agent-name {
+ font-size: var(--fontSizeBase300);
+ font-weight: var(--fontWeightSemibold);
+}
+.strikethrough {
+ text-decoration: line-through;
+}
\ No newline at end of file
diff --git a/src/frontend/src/styles/TaskList.css b/src/frontend/src/styles/TaskList.css
new file mode 100644
index 000000000..f945f35c0
--- /dev/null
+++ b/src/frontend/src/styles/TaskList.css
@@ -0,0 +1,123 @@
+/* TaskList Component Styles */
+
+.task-list-task-date {
+ color: var(--colorNeutralForeground3); /* tokens.colorNeutralForeground2 */
+}
+
+.tab {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ color: var(--colorNeutralForeground2);
+ padding: 8px 16px;
+ border-radius: 6px;
+ font-size: 14px;
+ text-decoration: none;
+ cursor: pointer;
+ transition: background-color 0.2s ease-in-out;
+}
+
+.tab:hover {
+ background-color: var(--colorSubtleBackgroundHover);
+}
+
+.tab:active {
+ background-color: var(--colorSubtleBackgroundPressed);
+}
+
+
+/* TASKLIST */
+
+.task-tab {
+ display: flex;
+ align-items: center;
+ padding: 8px 8px 8px 0;
+ color: var(--colorNeutralForeground2);
+ border-radius: 6px;
+ cursor: pointer;
+ transition: background-color 0.2s ease-in-out;
+ font-size: var(--fontSizeBase00);
+ gap: 14px;
+
+}
+
+.task-tab:hover {
+ background-color: var(--colorSubtleBackgroundHover);
+}
+
+.task-tab.active {
+ background-color: var(--colorNeutralBackground1Pressed);
+ color: var(--colorNeutralForeground1);
+ font-weight: 500;
+
+}
+
+.task-tab {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.task-tab .left {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+.task-name-truncated {
+ position: relative;
+ white-space: nowrap;
+ overflow: hidden;
+ max-width: 100%;
+ mask-image: linear-gradient(to right, black 80%, transparent 100%);
+ -webkit-mask-image: linear-gradient(to right, black 80%, transparent 100%);
+}
+
+
+.task-tab .sideNavTick {
+ width: 2px;
+ height: 100%;
+ min-height: 32px;
+ background-color: var(--colorCompoundBrandStroke);
+ opacity: 0;
+ flex-shrink: 0;
+ transition: opacity 0.2s ease-in-out;
+ margin-left: -8px;
+
+}
+
+.task-tab.active .sideNavTick {
+ opacity: 1;
+}
+
+.task-tab .task-menu-button {
+ opacity: 0;
+ transition: opacity 0.2s ease-in-out;
+}
+
+.task-tab:hover .task-menu-button {
+ opacity: 1;
+}
+
+
+
+/* SKELETON */
+
+.task-skeleton-container {
+ padding: 8px;
+ border-radius: 6px;
+ pointer-events: none;
+ cursor: default;
+ background-color: transparent;
+}
+
+.task-skeleton-wrapper {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+
+
diff --git a/src/frontend/src/styles/prism-material-oceanic.css b/src/frontend/src/styles/prism-material-oceanic.css
new file mode 100644
index 000000000..a48250839
--- /dev/null
+++ b/src/frontend/src/styles/prism-material-oceanic.css
@@ -0,0 +1,79 @@
+/* Light Mode (Default) */
+:root {
+ --color-text: #1e293b;
+ --color-selection: #cbd5e1;
+
+ --color-atrule: #7c3aed;
+ --color-attr-name: #ea580c;
+ --color-attr-value: #15803d;
+ --color-boolean: #7c3aed;
+ --color-comment: #64748b;
+ --color-function: #7c3aed;
+ --color-number: #f97316;
+ --color-string: #15803d;
+ --color-tag: #e11d48;
+ --color-punctuation: #2563eb;
+}
+
+/* Dark Mode */
+body.dark-mode {
+ --color-text: #c3cee3;
+ --color-selection: #363636;
+
+ --color-atrule: #c792ea;
+ --color-attr-name: #ffcb6b;
+ --color-attr-value: #c3e88d;
+ --color-boolean: #c792ea;
+ --color-comment: #546e7a;
+ --color-function: #c792ea;
+ --color-number: #fd9170;
+ --color-string: #c3e88d;
+ --color-tag: #f07178;
+ --color-punctuation: #89ddff;
+}
+
+/* Base Syntax Highlighting */
+code[class*="language-"],
+pre[class*="language-"] {
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ word-wrap: normal;
+ color: var(--color-text);
+ font-family: Roboto Mono, monospace;
+ font-size: .95em;
+ line-height: 1.8em;
+ tab-size: 4;
+ hyphens: none;
+}
+
+code[class*="language-"]::selection,
+pre[class*="language-"]::selection {
+ background: var(--color-selection);
+}
+
+:not(pre) > code[class*="language-"] {
+ white-space: normal;
+ border-radius: 0.2em;
+ padding: 0.1em;
+}
+
+pre[class*="language-"] {
+ overflow: auto;
+ position: relative;
+ margin: 0.5em 0;
+ padding: 1.25em 1em;
+}
+
+/* Token Colors */
+.token.atrule { color: var(--color-atrule); }
+.token.attr-name { color: var(--color-attr-name); }
+.token.attr-value { color: var(--color-attr-value); }
+.token.boolean { color: var(--color-boolean); }
+.token.comment { color: var(--color-comment); }
+.token.function { color: var(--color-function); }
+.token.number { color: var(--color-number); }
+.token.string { color: var(--color-string); }
+.token.tag { color: var(--color-tag); }
+.token.punctuation { color: var(--color-punctuation); }
\ No newline at end of file
diff --git a/src/frontend/src/utils/errorUtils.tsx b/src/frontend/src/utils/errorUtils.tsx
new file mode 100644
index 000000000..ced042c7c
--- /dev/null
+++ b/src/frontend/src/utils/errorUtils.tsx
@@ -0,0 +1,48 @@
+/**
+ * Get a user-friendly error message based on the error type
+ * @param error The error object to process
+ * @returns User-friendly error message
+ */
+export const getErrorMessage = (error: unknown): string => {
+ if (error instanceof Error) {
+ // Check error message patterns for different types of errors
+ const message = error.message.toLowerCase();
+
+ if (message.includes('400') || message.includes('bad request')) {
+ return `Bad request: ${error.message}`;
+ } else if (message.includes('401') || message.includes('unauthorized')) {
+ return 'You are not authorized to perform this action. Please sign in again.';
+ } else if (message.includes('404') || message.includes('not found')) {
+ return `Resource not found: ${error.message}`;
+ } else if (message.includes('500') || message.includes('server error')) {
+ return `Server error: ${error.message}. Please try again later.`;
+ } else if (message.includes('network') || message.includes('fetch')) {
+ return 'Network error. Please check your connection and try again.';
+ }
+
+ return error.message;
+ }
+ return 'An unknown error occurred. Please try again.';
+};
+
+/**
+ * Get CSS class or style based on error type for UI elements
+ * @param error The error object to process
+ * @returns CSS class name or style object
+ */
+export const getErrorStyle = (error: unknown): string => {
+ if (error instanceof Error) {
+ const message = error.message.toLowerCase();
+
+ if (message.includes('400') || message.includes('bad request')) {
+ return 'error-bad-request';
+ } else if (message.includes('401') || message.includes('unauthorized')) {
+ return 'error-unauthorized';
+ } else if (message.includes('404') || message.includes('not found')) {
+ return 'error-not-found';
+ } else if (message.includes('500') || message.includes('server error')) {
+ return 'error-server';
+ }
+ }
+ return 'error-general';
+};
diff --git a/src/frontend/src/vite-env.d.ts b/src/frontend/src/vite-env.d.ts
new file mode 100644
index 000000000..5e2668093
--- /dev/null
+++ b/src/frontend/src/vite-env.d.ts
@@ -0,0 +1,11 @@
+///
+
+interface ImportMetaEnv {
+ readonly REACT_APP_API_URL?: string
+ readonly REACT_APP_ENVIRONMENT?: string
+ // Add more environment variables as needed
+}
+
+interface ImportMeta {
+ readonly env: ImportMetaEnv
+}
diff --git a/src/frontend/tsconfig.json b/src/frontend/tsconfig.json
new file mode 100644
index 000000000..3150fad0a
--- /dev/null
+++ b/src/frontend/tsconfig.json
@@ -0,0 +1,40 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": [
+ "ES2020",
+ "DOM",
+ "DOM.Iterable"
+ ],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": false,
+ "noUnusedParameters": false,
+ "noFallthroughCasesInSwitch": true,
+
+ /* Path mapping */
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["src/*"]
+ },
+
+ /* Additional options for compatibility */
+ "allowJs": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "forceConsistentCasingInFileNames": true
+ }, "include": [
+ "src"
+ ]
+}
diff --git a/src/frontend/tsconfig.node.json b/src/frontend/tsconfig.node.json
new file mode 100644
index 000000000..c7a071e35
--- /dev/null
+++ b/src/frontend/tsconfig.node.json
@@ -0,0 +1,13 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true,
+ "strict": true
+ },
+ "include": [
+ "vite.config.ts"
+ ]
+}
diff --git a/src/frontend/uv.lock b/src/frontend/uv.lock
index 78e2b6fc8..2386b7926 100644
--- a/src/frontend/uv.lock
+++ b/src/frontend/uv.lock
@@ -3,566 +3,6 @@ revision = 2
requires-python = ">=3.11"
[[package]]
-name = "annotated-types"
-version = "0.7.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
-]
-
-[[package]]
-name = "anyio"
-version = "4.9.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "idna" },
- { name = "sniffio" },
- { name = "typing-extensions", marker = "python_full_version < '3.13'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949, upload-time = "2025-03-17T00:02:54.77Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload-time = "2025-03-17T00:02:52.713Z" },
-]
-
-[[package]]
-name = "azure-core"
-version = "1.33.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "requests" },
- { name = "six" },
- { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/75/aa/7c9db8edd626f1a7d99d09ef7926f6f4fb34d5f9fa00dc394afdfe8e2a80/azure_core-1.33.0.tar.gz", hash = "sha256:f367aa07b5e3005fec2c1e184b882b0b039910733907d001c20fb08ebb8c0eb9", size = 295633, upload-time = "2025-04-03T23:51:02.058Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/07/b7/76b7e144aa53bd206bf1ce34fa75350472c3f69bf30e5c8c18bc9881035d/azure_core-1.33.0-py3-none-any.whl", hash = "sha256:9b5b6d0223a1d38c37500e6971118c1e0f13f54951e6893968b38910bc9cda8f", size = 207071, upload-time = "2025-04-03T23:51:03.806Z" },
-]
-
-[[package]]
-name = "azure-identity"
-version = "1.21.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "azure-core" },
- { name = "cryptography" },
- { name = "msal" },
- { name = "msal-extensions" },
- { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/b5/a1/f1a683672e7a88ea0e3119f57b6c7843ed52650fdcac8bfa66ed84e86e40/azure_identity-1.21.0.tar.gz", hash = "sha256:ea22ce6e6b0f429bc1b8d9212d5b9f9877bd4c82f1724bfa910760612c07a9a6", size = 266445, upload-time = "2025-03-11T20:53:07.463Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/3d/9f/1f9f3ef4f49729ee207a712a5971a9ca747f2ca47d9cbf13cf6953e3478a/azure_identity-1.21.0-py3-none-any.whl", hash = "sha256:258ea6325537352440f71b35c3dffe9d240eae4a5126c1b7ce5efd5766bd9fd9", size = 189190, upload-time = "2025-03-11T20:53:09.197Z" },
-]
-
-[[package]]
-name = "certifi"
-version = "2025.4.26"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" },
-]
-
-[[package]]
-name = "cffi"
-version = "1.17.1"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "pycparser" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264, upload-time = "2024-09-04T20:43:51.124Z" },
- { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651, upload-time = "2024-09-04T20:43:52.872Z" },
- { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload-time = "2024-09-04T20:43:56.123Z" },
- { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200, upload-time = "2024-09-04T20:43:57.891Z" },
- { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235, upload-time = "2024-09-04T20:44:00.18Z" },
- { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721, upload-time = "2024-09-04T20:44:01.585Z" },
- { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242, upload-time = "2024-09-04T20:44:03.467Z" },
- { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999, upload-time = "2024-09-04T20:44:05.023Z" },
- { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242, upload-time = "2024-09-04T20:44:06.444Z" },
- { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604, upload-time = "2024-09-04T20:44:08.206Z" },
- { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727, upload-time = "2024-09-04T20:44:09.481Z" },
- { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400, upload-time = "2024-09-04T20:44:10.873Z" },
- { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload-time = "2024-09-04T20:44:12.232Z" },
- { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload-time = "2024-09-04T20:44:13.739Z" },
- { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" },
- { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" },
- { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" },
- { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" },
- { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" },
- { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" },
- { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" },
- { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" },
- { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" },
- { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" },
- { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" },
- { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" },
- { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" },
- { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" },
- { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" },
- { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" },
- { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" },
- { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" },
- { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" },
- { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" },
-]
-
-[[package]]
-name = "charset-normalizer"
-version = "3.4.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188, upload-time = "2024-12-24T18:12:35.43Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", size = 194995, upload-time = "2024-12-24T18:10:12.838Z" },
- { url = "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", size = 139471, upload-time = "2024-12-24T18:10:14.101Z" },
- { url = "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", size = 149831, upload-time = "2024-12-24T18:10:15.512Z" },
- { url = "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", size = 142335, upload-time = "2024-12-24T18:10:18.369Z" },
- { url = "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", size = 143862, upload-time = "2024-12-24T18:10:19.743Z" },
- { url = "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", size = 145673, upload-time = "2024-12-24T18:10:21.139Z" },
- { url = "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", size = 140211, upload-time = "2024-12-24T18:10:22.382Z" },
- { url = "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", size = 148039, upload-time = "2024-12-24T18:10:24.802Z" },
- { url = "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", size = 151939, upload-time = "2024-12-24T18:10:26.124Z" },
- { url = "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", size = 149075, upload-time = "2024-12-24T18:10:30.027Z" },
- { url = "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", size = 144340, upload-time = "2024-12-24T18:10:32.679Z" },
- { url = "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", size = 95205, upload-time = "2024-12-24T18:10:34.724Z" },
- { url = "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", size = 102441, upload-time = "2024-12-24T18:10:37.574Z" },
- { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105, upload-time = "2024-12-24T18:10:38.83Z" },
- { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404, upload-time = "2024-12-24T18:10:44.272Z" },
- { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423, upload-time = "2024-12-24T18:10:45.492Z" },
- { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184, upload-time = "2024-12-24T18:10:47.898Z" },
- { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268, upload-time = "2024-12-24T18:10:50.589Z" },
- { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601, upload-time = "2024-12-24T18:10:52.541Z" },
- { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098, upload-time = "2024-12-24T18:10:53.789Z" },
- { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520, upload-time = "2024-12-24T18:10:55.048Z" },
- { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852, upload-time = "2024-12-24T18:10:57.647Z" },
- { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488, upload-time = "2024-12-24T18:10:59.43Z" },
- { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192, upload-time = "2024-12-24T18:11:00.676Z" },
- { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550, upload-time = "2024-12-24T18:11:01.952Z" },
- { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785, upload-time = "2024-12-24T18:11:03.142Z" },
- { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698, upload-time = "2024-12-24T18:11:05.834Z" },
- { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162, upload-time = "2024-12-24T18:11:07.064Z" },
- { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263, upload-time = "2024-12-24T18:11:08.374Z" },
- { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966, upload-time = "2024-12-24T18:11:09.831Z" },
- { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992, upload-time = "2024-12-24T18:11:12.03Z" },
- { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162, upload-time = "2024-12-24T18:11:13.372Z" },
- { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972, upload-time = "2024-12-24T18:11:14.628Z" },
- { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095, upload-time = "2024-12-24T18:11:17.672Z" },
- { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668, upload-time = "2024-12-24T18:11:18.989Z" },
- { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073, upload-time = "2024-12-24T18:11:21.507Z" },
- { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732, upload-time = "2024-12-24T18:11:22.774Z" },
- { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391, upload-time = "2024-12-24T18:11:24.139Z" },
- { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702, upload-time = "2024-12-24T18:11:26.535Z" },
- { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767, upload-time = "2024-12-24T18:12:32.852Z" },
-]
-
-[[package]]
-name = "click"
-version = "8.1.8"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "colorama", marker = "sys_platform == 'win32'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload-time = "2024-12-21T18:38:44.339Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload-time = "2024-12-21T18:38:41.666Z" },
-]
-
-[[package]]
-name = "colorama"
-version = "0.4.6"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
-]
-
-[[package]]
-name = "cryptography"
-version = "44.0.2"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/cd/25/4ce80c78963834b8a9fd1cc1266be5ed8d1840785c0f2e1b73b8d128d505/cryptography-44.0.2.tar.gz", hash = "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0", size = 710807, upload-time = "2025-03-02T00:01:37.692Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/92/ef/83e632cfa801b221570c5f58c0369db6fa6cef7d9ff859feab1aae1a8a0f/cryptography-44.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7", size = 6676361, upload-time = "2025-03-02T00:00:06.528Z" },
- { url = "https://files.pythonhosted.org/packages/30/ec/7ea7c1e4c8fc8329506b46c6c4a52e2f20318425d48e0fe597977c71dbce/cryptography-44.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1", size = 3952350, upload-time = "2025-03-02T00:00:09.537Z" },
- { url = "https://files.pythonhosted.org/packages/27/61/72e3afdb3c5ac510330feba4fc1faa0fe62e070592d6ad00c40bb69165e5/cryptography-44.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb", size = 4166572, upload-time = "2025-03-02T00:00:12.03Z" },
- { url = "https://files.pythonhosted.org/packages/26/e4/ba680f0b35ed4a07d87f9e98f3ebccb05091f3bf6b5a478b943253b3bbd5/cryptography-44.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843", size = 3958124, upload-time = "2025-03-02T00:00:14.518Z" },
- { url = "https://files.pythonhosted.org/packages/9c/e8/44ae3e68c8b6d1cbc59040288056df2ad7f7f03bbcaca6b503c737ab8e73/cryptography-44.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5", size = 3678122, upload-time = "2025-03-02T00:00:17.212Z" },
- { url = "https://files.pythonhosted.org/packages/27/7b/664ea5e0d1eab511a10e480baf1c5d3e681c7d91718f60e149cec09edf01/cryptography-44.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c", size = 4191831, upload-time = "2025-03-02T00:00:19.696Z" },
- { url = "https://files.pythonhosted.org/packages/2a/07/79554a9c40eb11345e1861f46f845fa71c9e25bf66d132e123d9feb8e7f9/cryptography-44.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a", size = 3960583, upload-time = "2025-03-02T00:00:22.488Z" },
- { url = "https://files.pythonhosted.org/packages/bb/6d/858e356a49a4f0b591bd6789d821427de18432212e137290b6d8a817e9bf/cryptography-44.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308", size = 4191753, upload-time = "2025-03-02T00:00:25.038Z" },
- { url = "https://files.pythonhosted.org/packages/b2/80/62df41ba4916067fa6b125aa8c14d7e9181773f0d5d0bd4dcef580d8b7c6/cryptography-44.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688", size = 4079550, upload-time = "2025-03-02T00:00:26.929Z" },
- { url = "https://files.pythonhosted.org/packages/f3/cd/2558cc08f7b1bb40683f99ff4327f8dcfc7de3affc669e9065e14824511b/cryptography-44.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7", size = 4298367, upload-time = "2025-03-02T00:00:28.735Z" },
- { url = "https://files.pythonhosted.org/packages/71/59/94ccc74788945bc3bd4cf355d19867e8057ff5fdbcac781b1ff95b700fb1/cryptography-44.0.2-cp37-abi3-win32.whl", hash = "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79", size = 2772843, upload-time = "2025-03-02T00:00:30.592Z" },
- { url = "https://files.pythonhosted.org/packages/ca/2c/0d0bbaf61ba05acb32f0841853cfa33ebb7a9ab3d9ed8bb004bd39f2da6a/cryptography-44.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa", size = 3209057, upload-time = "2025-03-02T00:00:33.393Z" },
- { url = "https://files.pythonhosted.org/packages/9e/be/7a26142e6d0f7683d8a382dd963745e65db895a79a280a30525ec92be890/cryptography-44.0.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3", size = 6677789, upload-time = "2025-03-02T00:00:36.009Z" },
- { url = "https://files.pythonhosted.org/packages/06/88/638865be7198a84a7713950b1db7343391c6066a20e614f8fa286eb178ed/cryptography-44.0.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639", size = 3951919, upload-time = "2025-03-02T00:00:38.581Z" },
- { url = "https://files.pythonhosted.org/packages/d7/fc/99fe639bcdf58561dfad1faa8a7369d1dc13f20acd78371bb97a01613585/cryptography-44.0.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd", size = 4167812, upload-time = "2025-03-02T00:00:42.934Z" },
- { url = "https://files.pythonhosted.org/packages/53/7b/aafe60210ec93d5d7f552592a28192e51d3c6b6be449e7fd0a91399b5d07/cryptography-44.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181", size = 3958571, upload-time = "2025-03-02T00:00:46.026Z" },
- { url = "https://files.pythonhosted.org/packages/16/32/051f7ce79ad5a6ef5e26a92b37f172ee2d6e1cce09931646eef8de1e9827/cryptography-44.0.2-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea", size = 3679832, upload-time = "2025-03-02T00:00:48.647Z" },
- { url = "https://files.pythonhosted.org/packages/78/2b/999b2a1e1ba2206f2d3bca267d68f350beb2b048a41ea827e08ce7260098/cryptography-44.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699", size = 4193719, upload-time = "2025-03-02T00:00:51.397Z" },
- { url = "https://files.pythonhosted.org/packages/72/97/430e56e39a1356e8e8f10f723211a0e256e11895ef1a135f30d7d40f2540/cryptography-44.0.2-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9", size = 3960852, upload-time = "2025-03-02T00:00:53.317Z" },
- { url = "https://files.pythonhosted.org/packages/89/33/c1cf182c152e1d262cac56850939530c05ca6c8d149aa0dcee490b417e99/cryptography-44.0.2-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23", size = 4193906, upload-time = "2025-03-02T00:00:56.49Z" },
- { url = "https://files.pythonhosted.org/packages/e1/99/87cf26d4f125380dc674233971069bc28d19b07f7755b29861570e513650/cryptography-44.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922", size = 4081572, upload-time = "2025-03-02T00:00:59.995Z" },
- { url = "https://files.pythonhosted.org/packages/b3/9f/6a3e0391957cc0c5f84aef9fbdd763035f2b52e998a53f99345e3ac69312/cryptography-44.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4", size = 4298631, upload-time = "2025-03-02T00:01:01.623Z" },
- { url = "https://files.pythonhosted.org/packages/e2/a5/5bc097adb4b6d22a24dea53c51f37e480aaec3465285c253098642696423/cryptography-44.0.2-cp39-abi3-win32.whl", hash = "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5", size = 2773792, upload-time = "2025-03-02T00:01:04.133Z" },
- { url = "https://files.pythonhosted.org/packages/33/cf/1f7649b8b9a3543e042d3f348e398a061923ac05b507f3f4d95f11938aa9/cryptography-44.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6", size = 3210957, upload-time = "2025-03-02T00:01:06.987Z" },
- { url = "https://files.pythonhosted.org/packages/d6/d7/f30e75a6aa7d0f65031886fa4a1485c2fbfe25a1896953920f6a9cfe2d3b/cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:909c97ab43a9c0c0b0ada7a1281430e4e5ec0458e6d9244c0e821bbf152f061d", size = 3887513, upload-time = "2025-03-02T00:01:22.911Z" },
- { url = "https://files.pythonhosted.org/packages/9c/b4/7a494ce1032323ca9db9a3661894c66e0d7142ad2079a4249303402d8c71/cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:96e7a5e9d6e71f9f4fca8eebfd603f8e86c5225bb18eb621b2c1e50b290a9471", size = 4107432, upload-time = "2025-03-02T00:01:24.701Z" },
- { url = "https://files.pythonhosted.org/packages/45/f8/6b3ec0bc56123b344a8d2b3264a325646d2dcdbdd9848b5e6f3d37db90b3/cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d1b3031093a366ac767b3feb8bcddb596671b3aaff82d4050f984da0c248b615", size = 3891421, upload-time = "2025-03-02T00:01:26.335Z" },
- { url = "https://files.pythonhosted.org/packages/57/ff/f3b4b2d007c2a646b0f69440ab06224f9cf37a977a72cdb7b50632174e8a/cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:04abd71114848aa25edb28e225ab5f268096f44cf0127f3d36975bdf1bdf3390", size = 4107081, upload-time = "2025-03-02T00:01:28.938Z" },
-]
-
-[[package]]
-name = "fastapi"
-version = "0.115.12"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "pydantic" },
- { name = "starlette" },
- { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/f4/55/ae499352d82338331ca1e28c7f4a63bfd09479b16395dce38cf50a39e2c2/fastapi-0.115.12.tar.gz", hash = "sha256:1e2c2a2646905f9e83d32f04a3f86aff4a286669c6c950ca95b5fd68c2602681", size = 295236, upload-time = "2025-03-23T22:55:43.822Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/50/b3/b51f09c2ba432a576fe63758bddc81f78f0c6309d9e5c10d194313bf021e/fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d", size = 95164, upload-time = "2025-03-23T22:55:42.101Z" },
-]
-
-[[package]]
-name = "frontend"
+name = "frontend-react"
version = "0.1.0"
source = { virtual = "." }
-dependencies = [
- { name = "azure-identity" },
- { name = "fastapi" },
- { name = "jinja2" },
- { name = "python-dotenv" },
- { name = "python-multipart" },
- { name = "uvicorn" },
-]
-
-[package.metadata]
-requires-dist = [
- { name = "azure-identity", specifier = ">=1.21.0" },
- { name = "fastapi", specifier = ">=0.115.12" },
- { name = "jinja2", specifier = ">=3.1.6" },
- { name = "python-dotenv", specifier = ">=1.1.0" },
- { name = "python-multipart", specifier = ">=0.0.20" },
- { name = "uvicorn", specifier = ">=0.34.2" },
-]
-
-[[package]]
-name = "h11"
-version = "0.16.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
-]
-
-[[package]]
-name = "idna"
-version = "3.10"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" },
-]
-
-[[package]]
-name = "jinja2"
-version = "3.1.6"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "markupsafe" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" },
-]
-
-[[package]]
-name = "markupsafe"
-version = "3.0.2"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload-time = "2024-10-18T15:21:02.187Z" },
- { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload-time = "2024-10-18T15:21:02.941Z" },
- { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload-time = "2024-10-18T15:21:03.953Z" },
- { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120, upload-time = "2024-10-18T15:21:06.495Z" },
- { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032, upload-time = "2024-10-18T15:21:07.295Z" },
- { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057, upload-time = "2024-10-18T15:21:08.073Z" },
- { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359, upload-time = "2024-10-18T15:21:09.318Z" },
- { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306, upload-time = "2024-10-18T15:21:10.185Z" },
- { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094, upload-time = "2024-10-18T15:21:11.005Z" },
- { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521, upload-time = "2024-10-18T15:21:12.911Z" },
- { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" },
- { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" },
- { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" },
- { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" },
- { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" },
- { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" },
- { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" },
- { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" },
- { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" },
- { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" },
- { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" },
- { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" },
- { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" },
- { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" },
- { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" },
- { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" },
- { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" },
- { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" },
- { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" },
- { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" },
- { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" },
- { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" },
- { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" },
- { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" },
- { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" },
- { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" },
- { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" },
- { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" },
- { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" },
- { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" },
-]
-
-[[package]]
-name = "msal"
-version = "1.32.3"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "cryptography" },
- { name = "pyjwt", extra = ["crypto"] },
- { name = "requests" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/3f/90/81dcc50f0be11a8c4dcbae1a9f761a26e5f905231330a7cacc9f04ec4c61/msal-1.32.3.tar.gz", hash = "sha256:5eea038689c78a5a70ca8ecbe1245458b55a857bd096efb6989c69ba15985d35", size = 151449, upload-time = "2025-04-25T13:12:34.204Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/04/bf/81516b9aac7fd867709984d08eb4db1d2e3fe1df795c8e442cde9b568962/msal-1.32.3-py3-none-any.whl", hash = "sha256:b2798db57760b1961b142f027ffb7c8169536bf77316e99a0df5c4aaebb11569", size = 115358, upload-time = "2025-04-25T13:12:33.034Z" },
-]
-
-[[package]]
-name = "msal-extensions"
-version = "1.3.1"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "msal" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/01/99/5d239b6156eddf761a636bded1118414d161bd6b7b37a9335549ed159396/msal_extensions-1.3.1.tar.gz", hash = "sha256:c5b0fd10f65ef62b5f1d62f4251d51cbcaf003fcedae8c91b040a488614be1a4", size = 23315, upload-time = "2025-03-14T23:51:03.902Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/5e/75/bd9b7bb966668920f06b200e84454c8f3566b102183bc55c5473d96cb2b9/msal_extensions-1.3.1-py3-none-any.whl", hash = "sha256:96d3de4d034504e969ac5e85bae8106c8373b5c6568e4c8fa7af2eca9dbe6bca", size = 20583, upload-time = "2025-03-14T23:51:03.016Z" },
-]
-
-[[package]]
-name = "pycparser"
-version = "2.22"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" },
-]
-
-[[package]]
-name = "pydantic"
-version = "2.11.4"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "annotated-types" },
- { name = "pydantic-core" },
- { name = "typing-extensions" },
- { name = "typing-inspection" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/77/ab/5250d56ad03884ab5efd07f734203943c8a8ab40d551e208af81d0257bf2/pydantic-2.11.4.tar.gz", hash = "sha256:32738d19d63a226a52eed76645a98ee07c1f410ee41d93b4afbfa85ed8111c2d", size = 786540, upload-time = "2025-04-29T20:38:55.02Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/e7/12/46b65f3534d099349e38ef6ec98b1a5a81f42536d17e0ba382c28c67ba67/pydantic-2.11.4-py3-none-any.whl", hash = "sha256:d9615eaa9ac5a063471da949c8fc16376a84afb5024688b3ff885693506764eb", size = 443900, upload-time = "2025-04-29T20:38:52.724Z" },
-]
-
-[[package]]
-name = "pydantic-core"
-version = "2.33.2"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/3f/8d/71db63483d518cbbf290261a1fc2839d17ff89fce7089e08cad07ccfce67/pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7", size = 2028584, upload-time = "2025-04-23T18:31:03.106Z" },
- { url = "https://files.pythonhosted.org/packages/24/2f/3cfa7244ae292dd850989f328722d2aef313f74ffc471184dc509e1e4e5a/pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246", size = 1855071, upload-time = "2025-04-23T18:31:04.621Z" },
- { url = "https://files.pythonhosted.org/packages/b3/d3/4ae42d33f5e3f50dd467761304be2fa0a9417fbf09735bc2cce003480f2a/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f", size = 1897823, upload-time = "2025-04-23T18:31:06.377Z" },
- { url = "https://files.pythonhosted.org/packages/f4/f3/aa5976e8352b7695ff808599794b1fba2a9ae2ee954a3426855935799488/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc", size = 1983792, upload-time = "2025-04-23T18:31:07.93Z" },
- { url = "https://files.pythonhosted.org/packages/d5/7a/cda9b5a23c552037717f2b2a5257e9b2bfe45e687386df9591eff7b46d28/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de", size = 2136338, upload-time = "2025-04-23T18:31:09.283Z" },
- { url = "https://files.pythonhosted.org/packages/2b/9f/b8f9ec8dd1417eb9da784e91e1667d58a2a4a7b7b34cf4af765ef663a7e5/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a", size = 2730998, upload-time = "2025-04-23T18:31:11.7Z" },
- { url = "https://files.pythonhosted.org/packages/47/bc/cd720e078576bdb8255d5032c5d63ee5c0bf4b7173dd955185a1d658c456/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef", size = 2003200, upload-time = "2025-04-23T18:31:13.536Z" },
- { url = "https://files.pythonhosted.org/packages/ca/22/3602b895ee2cd29d11a2b349372446ae9727c32e78a94b3d588a40fdf187/pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e", size = 2113890, upload-time = "2025-04-23T18:31:15.011Z" },
- { url = "https://files.pythonhosted.org/packages/ff/e6/e3c5908c03cf00d629eb38393a98fccc38ee0ce8ecce32f69fc7d7b558a7/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d", size = 2073359, upload-time = "2025-04-23T18:31:16.393Z" },
- { url = "https://files.pythonhosted.org/packages/12/e7/6a36a07c59ebefc8777d1ffdaf5ae71b06b21952582e4b07eba88a421c79/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30", size = 2245883, upload-time = "2025-04-23T18:31:17.892Z" },
- { url = "https://files.pythonhosted.org/packages/16/3f/59b3187aaa6cc0c1e6616e8045b284de2b6a87b027cce2ffcea073adf1d2/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf", size = 2241074, upload-time = "2025-04-23T18:31:19.205Z" },
- { url = "https://files.pythonhosted.org/packages/e0/ed/55532bb88f674d5d8f67ab121a2a13c385df382de2a1677f30ad385f7438/pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51", size = 1910538, upload-time = "2025-04-23T18:31:20.541Z" },
- { url = "https://files.pythonhosted.org/packages/fe/1b/25b7cccd4519c0b23c2dd636ad39d381abf113085ce4f7bec2b0dc755eb1/pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab", size = 1952909, upload-time = "2025-04-23T18:31:22.371Z" },
- { url = "https://files.pythonhosted.org/packages/49/a9/d809358e49126438055884c4366a1f6227f0f84f635a9014e2deb9b9de54/pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65", size = 1897786, upload-time = "2025-04-23T18:31:24.161Z" },
- { url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" },
- { url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" },
- { url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" },
- { url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" },
- { url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" },
- { url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" },
- { url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" },
- { url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" },
- { url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" },
- { url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" },
- { url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" },
- { url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" },
- { url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" },
- { url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" },
- { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" },
- { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" },
- { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" },
- { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" },
- { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" },
- { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" },
- { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" },
- { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" },
- { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" },
- { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" },
- { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" },
- { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" },
- { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" },
- { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" },
- { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" },
- { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" },
- { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" },
- { url = "https://files.pythonhosted.org/packages/7b/27/d4ae6487d73948d6f20dddcd94be4ea43e74349b56eba82e9bdee2d7494c/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8", size = 2025200, upload-time = "2025-04-23T18:33:14.199Z" },
- { url = "https://files.pythonhosted.org/packages/f1/b8/b3cb95375f05d33801024079b9392a5ab45267a63400bf1866e7ce0f0de4/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593", size = 1859123, upload-time = "2025-04-23T18:33:16.555Z" },
- { url = "https://files.pythonhosted.org/packages/05/bc/0d0b5adeda59a261cd30a1235a445bf55c7e46ae44aea28f7bd6ed46e091/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612", size = 1892852, upload-time = "2025-04-23T18:33:18.513Z" },
- { url = "https://files.pythonhosted.org/packages/3e/11/d37bdebbda2e449cb3f519f6ce950927b56d62f0b84fd9cb9e372a26a3d5/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7", size = 2067484, upload-time = "2025-04-23T18:33:20.475Z" },
- { url = "https://files.pythonhosted.org/packages/8c/55/1f95f0a05ce72ecb02a8a8a1c3be0579bbc29b1d5ab68f1378b7bebc5057/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e", size = 2108896, upload-time = "2025-04-23T18:33:22.501Z" },
- { url = "https://files.pythonhosted.org/packages/53/89/2b2de6c81fa131f423246a9109d7b2a375e83968ad0800d6e57d0574629b/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8", size = 2069475, upload-time = "2025-04-23T18:33:24.528Z" },
- { url = "https://files.pythonhosted.org/packages/b8/e9/1f7efbe20d0b2b10f6718944b5d8ece9152390904f29a78e68d4e7961159/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf", size = 2239013, upload-time = "2025-04-23T18:33:26.621Z" },
- { url = "https://files.pythonhosted.org/packages/3c/b2/5309c905a93811524a49b4e031e9851a6b00ff0fb668794472ea7746b448/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb", size = 2238715, upload-time = "2025-04-23T18:33:28.656Z" },
- { url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757, upload-time = "2025-04-23T18:33:30.645Z" },
-]
-
-[[package]]
-name = "pyjwt"
-version = "2.10.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785, upload-time = "2024-11-28T03:43:29.933Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997, upload-time = "2024-11-28T03:43:27.893Z" },
-]
-
-[package.optional-dependencies]
-crypto = [
- { name = "cryptography" },
-]
-
-[[package]]
-name = "python-dotenv"
-version = "1.1.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920, upload-time = "2025-03-25T10:14:56.835Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256, upload-time = "2025-03-25T10:14:55.034Z" },
-]
-
-[[package]]
-name = "python-multipart"
-version = "0.0.20"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload-time = "2024-12-16T19:45:46.972Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload-time = "2024-12-16T19:45:44.423Z" },
-]
-
-[[package]]
-name = "requests"
-version = "2.32.3"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "certifi" },
- { name = "charset-normalizer" },
- { name = "idna" },
- { name = "urllib3" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" },
-]
-
-[[package]]
-name = "six"
-version = "1.17.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
-]
-
-[[package]]
-name = "sniffio"
-version = "1.3.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" },
-]
-
-[[package]]
-name = "starlette"
-version = "0.46.2"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "anyio" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846, upload-time = "2025-04-13T13:56:17.942Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037, upload-time = "2025-04-13T13:56:16.21Z" },
-]
-
-[[package]]
-name = "typing-extensions"
-version = "4.13.2"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" },
-]
-
-[[package]]
-name = "typing-inspection"
-version = "0.4.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload-time = "2025-02-25T17:27:59.638Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload-time = "2025-02-25T17:27:57.754Z" },
-]
-
-[[package]]
-name = "urllib3"
-version = "2.4.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" },
-]
-
-[[package]]
-name = "uvicorn"
-version = "0.34.2"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "click" },
- { name = "h11" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/a6/ae/9bbb19b9e1c450cf9ecaef06463e40234d98d95bf572fab11b4f19ae5ded/uvicorn-0.34.2.tar.gz", hash = "sha256:0e929828f6186353a80b58ea719861d2629d766293b6d19baf086ba31d4f3328", size = 76815, upload-time = "2025-04-19T06:02:50.101Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/b1/4b/4cef6ce21a2aaca9d852a6e84ef4f135d99fcd74fa75105e2fc0c8308acd/uvicorn-0.34.2-py3-none-any.whl", hash = "sha256:deb49af569084536d269fe0a6d67e3754f104cf03aba7c11c40f01aadf33c403", size = 62483, upload-time = "2025-04-19T06:02:48.42Z" },
-]
diff --git a/src/frontend/vite.config.ts b/src/frontend/vite.config.ts
new file mode 100644
index 000000000..ad505f1a8
--- /dev/null
+++ b/src/frontend/vite.config.ts
@@ -0,0 +1,65 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+import { resolve } from 'path'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react()],
+
+ // Define path aliases (similar to Create React App)
+ resolve: {
+ alias: {
+ '@': resolve(__dirname, 'src'),
+ },
+ },
+
+ // Server configuration
+ server: {
+ port: 3001,
+ open: true,
+ host: true,
+ },
+
+ // Build configuration
+ build: {
+ outDir: 'build',
+ sourcemap: true,
+ // Optimize dependencies
+ rollupOptions: {
+ output: {
+ manualChunks: {
+ vendor: ['react', 'react-dom'],
+ fluentui: ['@fluentui/react-components', '@fluentui/react-icons'],
+ router: ['react-router-dom'],
+ }
+ }
+ }
+ },
+
+ // Handle CSS and static assets
+ css: {
+ modules: {
+ localsConvention: 'camelCase'
+ }
+ },
+
+ // Environment variables configuration
+ envPrefix: 'REACT_APP_',
+
+ // Define global constants
+ define: {
+ 'process.env': process.env,
+ },
+
+ // Optimization
+ optimizeDeps: {
+ include: [
+ 'react',
+ 'react-dom',
+ '@fluentui/react-components',
+ '@fluentui/react-icons',
+ 'react-router-dom',
+ 'axios'
+ ]
+ }
+})
diff --git a/src/frontend/vitest.config.ts b/src/frontend/vitest.config.ts
new file mode 100644
index 000000000..17a2289c9
--- /dev/null
+++ b/src/frontend/vitest.config.ts
@@ -0,0 +1,19 @@
+///
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+import { resolve } from 'path'
+
+export default defineConfig({
+ plugins: [react()],
+ test: {
+ globals: true,
+ environment: 'jsdom',
+ setupFiles: ['./src/setupTests.ts'],
+ css: true,
+ },
+ resolve: {
+ alias: {
+ '@': resolve(__dirname, 'src'),
+ },
+ },
+})
diff --git a/src/frontend/wwwroot/app.css b/src/frontend/wwwroot/app.css
deleted file mode 100644
index 1c64a10ea..000000000
--- a/src/frontend/wwwroot/app.css
+++ /dev/null
@@ -1,242 +0,0 @@
-@import "https://cdn.jsdelivr.net/npm/bulma@1.0.2/css/bulma.min.css";
-@import "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css";
-@import "assets/theme.css";
-
-/* App global */
-
-html,
-body {
- overflow-x: hidden;
- overflow-y: auto;
- height: 100%;
-}
-
-body {
- position: relative;
- background: rgb(247, 249, 251);
- min-height: 100vh;
-}
-
-.border-right {
- border-right: 1px solid hsl(221, 14%, calc(86% + 0%));
-}
-
-/* App template */
-
-#app .columns {
- min-height: 100vh;
- height: 100%;
-}
-#app .modal,
-#app .menu {
- overflow: hidden; /* Prevent scrolling within modals and menus */
-}
-#app .asside {
- background: rgba(231, 236, 243, 0.7);
-}
-ul#tasksStats.menu-list {
- min-height: 100px;
-}
-@media (min-width: 1800px) {
- #app .asside {
- max-width: 400px;
- }
-}
-
-#app .menu-logo {
- font-size: 1.25rem;
- font-weight: 700;
- cursor: pointer;
-}
-
-#app .menu-logo img {
- width: 30px;
-}
-
-#app .asside .menu-list a {
- background-color: transparent;
-}
-
-#app .asside .menu-list a.is-active {
- background-color: rgb(71, 80, 235);
-}
-
-#app .asside .menu-list a.is-active i {
- color: white !important;
-}
-
-#app .asside .menu-list a.is-active:hover {
- background-color: rgb(71, 80, 235);
-}
-
-#app .asside .menu-list a.menu-task {
- display: flex;
- align-items: center;
-}
-
-#app .asside .menu-list a.menu-task span {
- flex: 1;
-}
-
-#app .asside .menu-list a:hover {
- background-color: rgba(0, 0, 0, 0.1);
-}
-
-#app .iframe {
- width: 100%;
- background-color: transparent;
-}
-
-#app .context-switch {
- position: fixed;
- bottom: 50px;
- right: calc(50% - 220px);
- z-index: 3;
-}
-
-.is-avatar.is-rounded {
- border-radius: var(--bulma-radius-rounded);
-}
-
-.is-avatar.is-agent {
- display: flex;
- /* background-color: rgba(231, 236, 243, 0.7); */
- background-color: rgba(70, 79, 235, 0.25);
-}
-
-.is-avatar.is-agent img {
- width: 75%;
- height: 75%;
- margin: 13%;
-}
-
-@keyframes moveImage {
- 0% {
- transform: rotate(0deg);
- }
-
- 50% {
- transform: rotate(-3deg);
- }
-
- 100% {
- transform: rotate(3deg);
- }
-}
-
-.is-avatar.is-agent img.manager {
- background-color: rgba(220, 56, 72, 0.35);
- box-shadow: 0 0 0 4px rgba(220, 56, 72, 0.35);
- animation: moveImage 0.3s infinite alternate;
-}
-
-.is-avatar.is-agent img.hr_agent {
- background-color: rgba(0, 209, 178, 0.35);
- box-shadow: 0 0 0 4px rgba(0, 209, 178, 0.35);
- animation: moveImage 0.5s infinite alternate;
-}
-
-.is-avatar.is-agent img.procurement_agent {
- background-color: rgba(255, 183, 15, 0.35);
- box-shadow: 0 0 0 4px rgba(255, 183, 15, 0.35);
- animation: moveImage 0.1s infinite alternate;
-}
-
-.is-avatar.is-agent img.tech_agent {
- background-color: rgba(178, 222, 39, 0.35);
- box-shadow: 0 0 0 4px rgba(178, 222, 39, 0.35);
- animation: moveImage 0.7s infinite alternate;
-}
-
-.is-avatar.is-agent img.unknown {
- background-color: rgba(39, 57, 222, 0.35);
- box-shadow: 0 0 0 4px rgba(39, 57, 222, 0.35);
- animation: moveImage 0.7s infinite alternate;
-}
-
-.is-avatar.has-status::after {
- content: "";
- position: absolute;
- bottom: 0;
- right: 0;
- width: 30%;
- height: 30%;
- border-radius: 50%;
- background-color: rgb(255, 255, 255);
- border: 2px solid rgb(255, 255, 255);
-}
-
-.is-avatar.has-status.has-status-active::after {
- background-color: hsl(
- var(--bulma-success-h),
- var(--bulma-success-s),
- var(--bulma-success-l)
- );
-}
-
-.is-avatar.has-status.has-status-busy::after {
- background-color: hsl(
- var(--bulma-danger-h),
- var(--bulma-danger-s),
- var(--bulma-danger-l)
- );
-}
-
-.is-avatar.has-status.has-status-paused::after {
- background-color: hsl(
- var(--bulma-dark-h),
- var(--bulma-dark-s),
- var(--bulma-dark-l)
- );
-}
-
-.button.is-greyed-out {
- background-color: #e0e0e0;
- color: lightgrey;
- cursor: not-allowed;
-}
-
-.button.is-selected {
- background-color: #d3d3d3;
- color: #000;
-}
-
-.notyf__toast {
- max-width: 100% !important;
- border-radius: var(--bulma-control-radius) !important;
-}
-
-.notyf__wrapper {
- padding: 0.75rem 0.5rem !important;
-}
-/* Menu list scroll style start*/
-#app .asside .menu-list {
- max-height: calc(100vh - 450px);
- overflow-y: scroll;
- padding-right: 2px;
- transition: all 0.3s ease;
- box-sizing: border-box;
-}
-/* Hide the scrollbar initially (before hover) */
-#app .asside .menu-list::-webkit-scrollbar {
- width: 8px;
- opacity: 0;
- visibility: hidden;
- transition: opacity 0.3s ease, visibility 0s 0.3s;
-}
-/* Style the scrollbar thumb (the draggable part) */
-#app .asside .menu-list::-webkit-scrollbar-thumb {
- border-radius: 10px;
- transition: background-color 0.3s ease;
-}
-/* Show the scrollbar and thumb when hovering */
-#app .asside .menu-list:hover::-webkit-scrollbar {
- opacity: 1;
- visibility: visible;
- transition: opacity 0.3s ease, visibility 0s;
-}
-/* Style the thumb when hovering */
-#app .asside .menu-list:hover::-webkit-scrollbar-thumb {
- background-color: rgba(0, 0, 0, 0.2);
-}
-/* Menu list scroll style end*/
diff --git a/src/frontend/wwwroot/app.html b/src/frontend/wwwroot/app.html
deleted file mode 100644
index 43615c5c4..000000000
--- a/src/frontend/wwwroot/app.html
+++ /dev/null
@@ -1,88 +0,0 @@
-
-
-
-
-
- Multi-Agent - Custom Automation Engine
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/frontend/wwwroot/app.js b/src/frontend/wwwroot/app.js
deleted file mode 100644
index 16760c490..000000000
--- a/src/frontend/wwwroot/app.js
+++ /dev/null
@@ -1,249 +0,0 @@
-(() => {
- window.headers = GetAuthDetails();
- const apiEndpoint = getStoredData('apiEndpoint') || BACKEND_API_URL;
- const goHomeButton = document.getElementById("goHomeButton");
- const newTaskButton = document.getElementById("newTaskButton");
- const closeModalButtons = document.querySelectorAll(".modal-close-button");
- const myTasksMenu = document.getElementById("myTasksMenu");
- const tasksStats = document.getElementById("tasksStats");
-
- if(AUTH_ENABLED !== undefined) {
- setStoredData('authEnabled', AUTH_ENABLED.toString().toLowerCase());
- }
-
- //if (!getStoredData('apiEndpoint'))setStoredData('apiEndpoint', apiEndpoint);
- // Force rewrite of apiEndpoint
- setStoredData('apiEndpoint', apiEndpoint);
- setStoredData('context', 'employee');
- // Refresh rate is set
- if (!getStoredData('apiRefreshRate'))setStoredData('apiRefreshRate', 5000);
- if (!getStoredData('actionStagesRun'))setStoredData('actionStagesRun', []);
-
- const getQueryParam = (param) => {
- const urlParams = new URLSearchParams(window.location.search);
- return urlParams.get(param);
- };
-
- const setQueryParam = (param, value) => {
- const urlParams = new URLSearchParams(window.location.search);
- urlParams.set(param, value);
- window.history.replaceState(null, null, `?${urlParams.toString()}`);
- };
-
- const switchView = () => {
- const viewIframe = document.getElementById('viewIframe');
- if (viewIframe) {
- const viewRoute = getQueryParam('v');
- const viewContext = getStoredData('context');
- const noCache = '?nocache=' + new Date().getTime();
- switch (viewRoute) {
- case 'home':
- viewIframe.src = 'home/home.html' + noCache;
- break;
- case 'task':
- viewIframe.src = `task/${viewContext}.html` + noCache;
- break;
- default:
- viewIframe.src = 'home/home.html';
- }
- }
- };
- // get user session
- const getUserInfo = async () => {
- if (window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1') {
- // Runninng in Azure so get user info from /.auth/me
- try {
- const response = await fetch('/.auth/me');
- if (!response.ok) {
- if(getStoredData('authEnabled') === 'false'){
- //Authentication is disabled. Will use mock user
- return {
- name: 'Local User',
- authenticated: true
- }
- }
- else{
- console.log("No identity provider found. Access to chat will be blocked.");
- return null;
- }
- }
- const payload = await response.json();
-
- if (payload) {
- return payload;
- }
- return null;
- } catch (e) {
- console.error("Error fetching user info:", e);
- return null;
- }
- } else {
- // Running locally so use a mock user
- return {
- name: 'Local User',
- authenticated: true
- }
- }
- };
-
- const homeActions = () => {
- if (newTaskButton && goHomeButton) {
- newTaskButton.addEventListener('click', (event) => {
- event.preventDefault();
- setQueryParam('v', 'home');
- switchView();
- });
-
- goHomeButton.addEventListener('click', (event) => {
- event.preventDefault();
- setQueryParam('v', 'home');
- switchView();
- });
- }
- };
-
- const messageListeners = () => {
-
- window.addEventListener('message', (event) => {
- if (event.data && event.data.button) {
- if (event.data.button === 'taskAgentsButton') taskAgentsModal.classList.add('is-active');
- if (event.data.button === 'taskWokFlowButton') taskWokFlowModal.classList.add('is-active');
- }
- if (event.data && event.data.action) {
- if (event.data.action === 'taskStarted') fetchTasksIfNeeded();
- }
- });
-
- }
-
- const getMyTasks = () => {
- myTasksMenu.innerHTML = `
-
- Loading tasks...
-
- `;
- }
-
- const fetchTasksIfNeeded = async () => {
- const taskStore = JSON.parse(getStoredData('task'));
- window.headers
- .then(headers => {
- fetch(apiEndpoint + '/plans', {
- method: 'GET',
- headers: headers,
- })
- .then(response => response.json())
- .then(data => {
-
- if (myTasksMenu){
- myTasksMenu.innerHTML = '';
- }
-
- if (data && data.length > 0) {
-
- const lastFiveTasks = data.slice(-5);
- let taskCount = 1;
- let inProgressTaskCount = 0;
- let inCompletedTaskCount = 0;
- let stagesPlannedCount = 0;
- let stagesRejectedCount = 0;
-
- lastFiveTasks.forEach(task => {
- const newTaskItem = document.createElement('li');
- const completedSteps = task.completed;
- let taskActive = '';
-
- if (taskStore && taskStore.id === task.session_id) taskActive = 'is-active';
-
- const taskStatus = (task.overall_status === 'completed') ? ' ' : ' ';
-
- newTaskItem.innerHTML = `
-
- `;
-
- if(myTasksMenu){
- myTasksMenu.appendChild(newTaskItem);
- }
-
- newTaskItem.querySelector('.menu-task').addEventListener('click', (event) => {
- const sessionId = event.target.closest('.menu-task').dataset.id;
- const taskName = event.target.closest('.menu-task').dataset.name;
-
- event.preventDefault();
- setQueryParam('v', 'task');
- switchView();
-
- setStoredData('task', JSON.stringify({
- id: sessionId,
- name: taskName
- }));
-
- document.querySelectorAll('.menu-task').forEach(task => {
- task.classList.remove('is-active');
- });
-
- event.target.closest('.menu-task').classList.add('is-active');
- });
-
- if (task.overall_status === 'completed') inCompletedTaskCount++;
- if (task.overall_status !== 'completed') inProgressTaskCount++;
- if (task.overall_status === 'planned') stagesPlannedCount++;
- if (task.overall_status === 'rejected') stagesRejectedCount++;
-
- const addS = (word, count) => (count === 1) ? word : word + 's';
-
- if(tasksStats){
- tasksStats.innerHTML = `
- ${inCompletedTaskCount} ${addS('task', inCompletedTaskCount)} completed
- ${inProgressTaskCount} ${addS('task', inProgressTaskCount)} in progress
- `;
- }
-
- taskCount++;
-
- })
-
-
- }
-
- })
- .catch(error => {
- console.error('Error:', error);
- })
-
- })
-
- };
-
- const modalActions = () => {
- closeModalButtons.forEach(closeModalButton => {
- closeModalButton.addEventListener('click', (event) => {
- event.preventDefault();
- const modal = closeModalButton.closest('.modal');
- modal.classList.remove('is-active');
- });
- });
- };
-
- const initializeApp = async () => {
- // Fetch user info when the app loads
- const userInfo = await getUserInfo();
- if (!userInfo) {
- console.error("Authentication failed. Access to tasks is restricted.");
- } else {
- setStoredData('userInfo', userInfo);
- await fetchTasksIfNeeded(); // Fetch tasks after initialization if needed
- }
- };
-
- fetchTasksIfNeeded();
- initializeApp();
- homeActions();
- switchView();
- messageListeners();
- modalActions();
-})();
diff --git a/src/frontend/wwwroot/assets/Send.svg b/src/frontend/wwwroot/assets/Send.svg
deleted file mode 100644
index 214d2ef72..000000000
--- a/src/frontend/wwwroot/assets/Send.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/src/frontend/wwwroot/assets/app-logo.svg b/src/frontend/wwwroot/assets/app-logo.svg
deleted file mode 100644
index 403a99082..000000000
--- a/src/frontend/wwwroot/assets/app-logo.svg
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/frontend/wwwroot/assets/avatar/expense_billing_agent.png b/src/frontend/wwwroot/assets/avatar/expense_billing_agent.png
deleted file mode 100644
index f169d02b4..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/expense_billing_agent.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/hr_agent.png b/src/frontend/wwwroot/assets/avatar/hr_agent.png
deleted file mode 100644
index 173504b8a..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/hr_agent.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/invoice_reconciliation_agent.png b/src/frontend/wwwroot/assets/avatar/invoice_reconciliation_agent.png
deleted file mode 100644
index c880eabd5..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/invoice_reconciliation_agent.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/legal_agent.png b/src/frontend/wwwroot/assets/avatar/legal_agent.png
deleted file mode 100644
index 32d037701..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/legal_agent.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/manager.png b/src/frontend/wwwroot/assets/avatar/manager.png
deleted file mode 100644
index 1b40b70d2..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/manager.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/marketing_agent.png b/src/frontend/wwwroot/assets/avatar/marketing_agent.png
deleted file mode 100644
index e3ac695e6..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/marketing_agent.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/procurement_agent.png b/src/frontend/wwwroot/assets/avatar/procurement_agent.png
deleted file mode 100644
index 16103b055..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/procurement_agent.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/product_agent.png b/src/frontend/wwwroot/assets/avatar/product_agent.png
deleted file mode 100644
index 3723443a0..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/product_agent.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/tech_agent.png b/src/frontend/wwwroot/assets/avatar/tech_agent.png
deleted file mode 100644
index 1c6408010..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/tech_agent.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/unknown.png b/src/frontend/wwwroot/assets/avatar/unknown.png
deleted file mode 100644
index 40f2d99f8..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/unknown.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/user0.png b/src/frontend/wwwroot/assets/avatar/user0.png
deleted file mode 100644
index 334c17ed5..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/user0.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/user1.png b/src/frontend/wwwroot/assets/avatar/user1.png
deleted file mode 100644
index db95af534..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/user1.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/user2.png b/src/frontend/wwwroot/assets/avatar/user2.png
deleted file mode 100644
index 1f8edca85..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/user2.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/user3.png b/src/frontend/wwwroot/assets/avatar/user3.png
deleted file mode 100644
index 30acfe0f8..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/user3.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/user4.png b/src/frontend/wwwroot/assets/avatar/user4.png
deleted file mode 100644
index bf155957f..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/user4.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/avatar/user5.png b/src/frontend/wwwroot/assets/avatar/user5.png
deleted file mode 100644
index cd267a51d..000000000
Binary files a/src/frontend/wwwroot/assets/avatar/user5.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/bulma-switch.css b/src/frontend/wwwroot/assets/bulma-switch.css
deleted file mode 100644
index 697d0e219..000000000
--- a/src/frontend/wwwroot/assets/bulma-switch.css
+++ /dev/null
@@ -1,609 +0,0 @@
-/* https: //github.com/justboil/bulma-switch-control */
-
-/* Bulma Utilities */
-.switch {
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-}
-
-/* Box-shadow */
-.switch {
- cursor: pointer;
- display: inline-flex;
- align-items: center;
- position: relative;
- margin-right: 0.5em;
-}
-
-.switch+.switch:last-child {
- margin-right: 0;
-}
-
-.switch input[type=checkbox] {
- position: absolute;
- left: 0;
- opacity: 0;
- outline: none;
- z-index: -1;
-}
-
-.switch input[type=checkbox]+.check {
- display: flex;
- align-items: center;
- flex-shrink: 0;
- width: 2.75em;
- height: 1.575em;
- padding: 0.2em;
- background: #b5b5b5;
- border-radius: 4px;
- transition: background 150ms ease-out, box-shadow 150ms ease-out;
-}
-
-.switch input[type=checkbox]+.check.is-white-passive,
-.switch input[type=checkbox]+.check:hover {
- background: white;
-}
-
-.switch input[type=checkbox]+.check.input[type=checkbox]+.switch input[type=checkbox]+.check.check {
- background: 'pink';
-}
-
-.switch input[type=checkbox]+.check.is-black-passive,
-.switch input[type=checkbox]+.check:hover {
- background: #0a0a0a;
-}
-
-.switch input[type=checkbox]+.check.input[type=checkbox]+.switch input[type=checkbox]+.check.check {
- background: 'pink';
-}
-
-.switch input[type=checkbox]+.check.is-light-passive,
-.switch input[type=checkbox]+.check:hover {
- background: whitesmoke;
-}
-
-.switch input[type=checkbox]+.check.input[type=checkbox]+.switch input[type=checkbox]+.check.check {
- background: 'pink';
-}
-
-.switch input[type=checkbox]+.check.is-dark-passive,
-.switch input[type=checkbox]+.check:hover {
- background: #363636;
-}
-
-.switch input[type=checkbox]+.check.input[type=checkbox]+.switch input[type=checkbox]+.check.check {
- background: 'pink';
-}
-
-.switch input[type=checkbox]+.check.is-primary-passive,
-.switch input[type=checkbox]+.check:hover {
- background: #00d1b2;
-}
-
-.switch input[type=checkbox]+.check.input[type=checkbox]+.switch input[type=checkbox]+.check.check {
- background: 'pink';
-}
-
-.switch input[type=checkbox]+.check.is-link-passive,
-.switch input[type=checkbox]+.check:hover {
- background: #485fc7;
-}
-
-.switch input[type=checkbox]+.check.input[type=checkbox]+.switch input[type=checkbox]+.check.check {
- background: 'pink';
-}
-
-.switch input[type=checkbox]+.check.is-info-passive,
-.switch input[type=checkbox]+.check:hover {
- background: #3e8ed0;
-}
-
-.switch input[type=checkbox]+.check.input[type=checkbox]+.switch input[type=checkbox]+.check.check {
- background: 'pink';
-}
-
-.switch input[type=checkbox]+.check.is-success-passive,
-.switch input[type=checkbox]+.check:hover {
- background: #48c78e;
-}
-
-.switch input[type=checkbox]+.check.input[type=checkbox]+.switch input[type=checkbox]+.check.check {
- background: 'pink';
-}
-
-.switch input[type=checkbox]+.check.is-warning-passive,
-.switch input[type=checkbox]+.check:hover {
- background: #ffe08a;
-}
-
-.switch input[type=checkbox]+.check.input[type=checkbox]+.switch input[type=checkbox]+.check.check {
- background: 'pink';
-}
-
-.switch input[type=checkbox]+.check.is-danger-passive,
-.switch input[type=checkbox]+.check:hover {
- background: #f14668;
-}
-
-.switch input[type=checkbox]+.check.input[type=checkbox]+.switch input[type=checkbox]+.check.check {
- background: 'pink';
-}
-
-.switch input[type=checkbox]+.check:before {
- content: "";
- display: block;
- border-radius: 4px;
- width: 1.175em;
- height: 1.175em;
- background: whitesmoke;
- transition: transform 150ms ease-out;
- will-change: transform;
- transform-origin: left;
-}
-
-.switch input[type=checkbox]+.check.is-elastic:before {
- transform: scaleX(1.5);
- border-radius: 4px;
-}
-
-.switch input[type=checkbox]:checked+.check {
- background: #00d1b2;
-}
-
-.switch input[type=checkbox]:checked+.check.is-white {
- background: white;
-}
-
-.switch input[type=checkbox]:checked+.check.is-black {
- background: #0a0a0a;
-}
-
-.switch input[type=checkbox]:checked+.check.is-light {
- background: whitesmoke;
-}
-
-.switch input[type=checkbox]:checked+.check.is-dark {
- background: #363636;
-}
-
-.switch input[type=checkbox]:checked+.check.is-primary {
- background: #00d1b2;
-}
-
-.switch input[type=checkbox]:checked+.check.is-link {
- background: #485fc7;
-}
-
-.switch input[type=checkbox]:checked+.check.is-info {
- background: #3e8ed0;
-}
-
-.switch input[type=checkbox]:checked+.check.is-success {
- background: #29a847;
-}
-
-.switch input[type=checkbox]:checked+.check.is-warning {
- background: #ffe08a;
-}
-
-.switch input[type=checkbox]:checked+.check.is-danger {
- background: #f14668;
-}
-
-.switch input[type=checkbox]:checked+.check:before {
- transform: translate3d(100%, 0, 0);
-}
-
-.switch input[type=checkbox]:checked+.check.is-elastic:before {
- transform: translate3d(50%, 0, 0) scaleX(1.5);
-}
-
-.switch input[type=checkbox]:focus,
-.switch input[type=checkbox]:active {
- outline: none;
-}
-
-.switch .control-label {
- padding-left: 0.5em;
-}
-
-.switch:hover input[type=checkbox]+.check {
- background: rgba(181, 181, 181, 0.9);
-}
-
-.switch:hover input[type=checkbox]+.check.is-white-passive {
- background: rgba(255, 255, 255, 0.9);
-}
-
-.switch:hover input[type=checkbox]+.check.is-black-passive {
- background: rgba(10, 10, 10, 0.9);
-}
-
-.switch:hover input[type=checkbox]+.check.is-light-passive {
- background: rgba(245, 245, 245, 0.9);
-}
-
-.switch:hover input[type=checkbox]+.check.is-dark-passive {
- background: rgba(54, 54, 54, 0.9);
-}
-
-.switch:hover input[type=checkbox]+.check.is-primary-passive {
- background: rgba(0, 209, 178, 0.9);
-}
-
-.switch:hover input[type=checkbox]+.check.is-link-passive {
- background: rgba(72, 95, 199, 0.9);
-}
-
-.switch:hover input[type=checkbox]+.check.is-info-passive {
- background: rgba(62, 142, 208, 0.9);
-}
-
-.switch:hover input[type=checkbox]+.check.is-success-passive {
- background: rgba(72, 199, 142, 0.9);
-}
-
-.switch:hover input[type=checkbox]+.check.is-warning-passive {
- background: rgba(255, 224, 138, 0.9);
-}
-
-.switch:hover input[type=checkbox]+.check.is-danger-passive {
- background: rgba(241, 70, 104, 0.9);
-}
-
-.switch:hover input[type=checkbox]:checked+.check {
- background: rgba(0, 209, 178, 0.9);
-}
-
-.switch:hover input[type=checkbox]:checked+.check.is-white {
- background: rgba(255, 255, 255, 0.9);
-}
-
-.switch:hover input[type=checkbox]:checked+.check.is-black {
- background: rgba(10, 10, 10, 0.9);
-}
-
-.switch:hover input[type=checkbox]:checked+.check.is-light {
- background: rgba(245, 245, 245, 0.9);
-}
-
-.switch:hover input[type=checkbox]:checked+.check.is-dark {
- background: rgba(54, 54, 54, 0.9);
-}
-
-.switch:hover input[type=checkbox]:checked+.check.is-primary {
- background: rgba(0, 209, 178, 0.9);
-}
-
-.switch:hover input[type=checkbox]:checked+.check.is-link {
- background: rgba(72, 95, 199, 0.9);
-}
-
-.switch:hover input[type=checkbox]:checked+.check.is-info {
- background: rgba(62, 142, 208, 0.9);
-}
-
-.switch:hover input[type=checkbox]:checked+.check.is-success {
- background: rgba(41, 168, 71, 0.9);
-}
-
-.switch:hover input[type=checkbox]:checked+.check.is-warning {
- background: rgba(255, 224, 138, 0.9);
-}
-
-.switch:hover input[type=checkbox]:checked+.check.is-danger {
- background: rgba(241, 70, 104, 0.9);
-}
-
-.switch.is-rounded input[type=checkbox]+.check {
- border-radius: 9999px;
-}
-
-.switch.is-rounded input[type=checkbox]+.check:before {
- border-radius: 9999px;
-}
-
-.switch.is-rounded input[type=checkbox].is-elastic:before {
- transform: scaleX(1.5);
- border-radius: 9999px;
-}
-
-.switch.is-outlined input[type=checkbox]+.check {
- background: transparent;
- border: 0.1rem solid #b5b5b5;
- padding: 0.1em;
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-white-passive {
- border: 0.1rem solid rgba(255, 255, 255, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-white-passive:before {
- background: white;
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-white-passive:hover {
- border-color: rgba(255, 255, 255, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-black-passive {
- border: 0.1rem solid rgba(10, 10, 10, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-black-passive:before {
- background: #0a0a0a;
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-black-passive:hover {
- border-color: rgba(10, 10, 10, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-light-passive {
- border: 0.1rem solid rgba(245, 245, 245, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-light-passive:before {
- background: whitesmoke;
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-light-passive:hover {
- border-color: rgba(245, 245, 245, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-dark-passive {
- border: 0.1rem solid rgba(54, 54, 54, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-dark-passive:before {
- background: #363636;
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-dark-passive:hover {
- border-color: rgba(54, 54, 54, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-primary-passive {
- border: 0.1rem solid rgba(0, 209, 178, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-primary-passive:before {
- background: #00d1b2;
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-primary-passive:hover {
- border-color: rgba(0, 209, 178, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-link-passive {
- border: 0.1rem solid rgba(72, 95, 199, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-link-passive:before {
- background: #485fc7;
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-link-passive:hover {
- border-color: rgba(72, 95, 199, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-info-passive {
- border: 0.1rem solid rgba(62, 142, 208, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-info-passive:before {
- background: #3e8ed0;
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-info-passive:hover {
- border-color: rgba(62, 142, 208, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-success-passive {
- border: 0.1rem solid rgba(72, 199, 142, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-success-passive:before {
- background: #48c78e;
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-success-passive:hover {
- border-color: rgba(72, 199, 142, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-warning-passive {
- border: 0.1rem solid rgba(255, 224, 138, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-warning-passive:before {
- background: #ffe08a;
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-warning-passive:hover {
- border-color: rgba(255, 224, 138, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-danger-passive {
- border: 0.1rem solid rgba(241, 70, 104, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-danger-passive:before {
- background: #f14668;
-}
-
-.switch.is-outlined input[type=checkbox]+.check.is-danger-passive:hover {
- border-color: rgba(241, 70, 104, 0.9);
-}
-
-.switch.is-outlined input[type=checkbox]+.check:before {
- background: #b5b5b5;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check {
- border-color: #00d1b2;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-white {
- background: transparent;
- border-color: white;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-white:before {
- background: white;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-black {
- background: transparent;
- border-color: #0a0a0a;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-black:before {
- background: #0a0a0a;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-light {
- background: transparent;
- border-color: whitesmoke;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-light:before {
- background: whitesmoke;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-dark {
- background: transparent;
- border-color: #363636;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-dark:before {
- background: #363636;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-primary {
- background: transparent;
- border-color: #00d1b2;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-primary:before {
- background: #00d1b2;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-link {
- background: transparent;
- border-color: #485fc7;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-link:before {
- background: #485fc7;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-info {
- background: transparent;
- border-color: #3e8ed0;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-info:before {
- background: #3e8ed0;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-success {
- background: transparent;
- border-color: #48c78e;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-success:before {
- background: #48c78e;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-warning {
- background: transparent;
- border-color: #ffe08a;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-warning:before {
- background: #ffe08a;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-danger {
- background: transparent;
- border-color: #f14668;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check.is-danger:before {
- background: #f14668;
-}
-
-.switch.is-outlined input[type=checkbox]:checked+.check:before {
- background: #00d1b2;
-}
-
-.switch.is-outlined:hover input[type=checkbox]+.check {
- background: transparent;
- border-color: rgba(181, 181, 181, 0.9);
-}
-
-.switch.is-outlined:hover input[type=checkbox]:checked+.check {
- background: transparent;
- border-color: rgba(0, 209, 178, 0.9);
-}
-
-.switch.is-outlined:hover input[type=checkbox]:checked+.check.is-white {
- border-color: rgba(255, 255, 255, 0.9);
-}
-
-.switch.is-outlined:hover input[type=checkbox]:checked+.check.is-black {
- border-color: rgba(10, 10, 10, 0.9);
-}
-
-.switch.is-outlined:hover input[type=checkbox]:checked+.check.is-light {
- border-color: rgba(245, 245, 245, 0.9);
-}
-
-.switch.is-outlined:hover input[type=checkbox]:checked+.check.is-dark {
- border-color: rgba(54, 54, 54, 0.9);
-}
-
-.switch.is-outlined:hover input[type=checkbox]:checked+.check.is-primary {
- border-color: rgba(0, 209, 178, 0.9);
-}
-
-.switch.is-outlined:hover input[type=checkbox]:checked+.check.is-link {
- border-color: rgba(72, 95, 199, 0.9);
-}
-
-.switch.is-outlined:hover input[type=checkbox]:checked+.check.is-info {
- border-color: rgba(62, 142, 208, 0.9);
-}
-
-.switch.is-outlined:hover input[type=checkbox]:checked+.check.is-success {
- border-color: rgba(72, 199, 142, 0.9);
-}
-
-.switch.is-outlined:hover input[type=checkbox]:checked+.check.is-warning {
- border-color: rgba(255, 224, 138, 0.9);
-}
-
-.switch.is-outlined:hover input[type=checkbox]:checked+.check.is-danger {
- border-color: rgba(241, 70, 104, 0.9);
-}
-
-.switch.is-small {
- border-radius: 2px;
- font-size: 0.75rem;
-}
-
-.switch.is-medium {
- font-size: 1.25rem;
-}
-
-.switch.is-large {
- font-size: 1.5rem;
-}
-
-.switch[disabled] {
- opacity: 0.5;
- cursor: not-allowed;
- color: #7a7a7a;
-}
\ No newline at end of file
diff --git a/src/frontend/wwwroot/assets/favicon/favicon-16x16.png b/src/frontend/wwwroot/assets/favicon/favicon-16x16.png
deleted file mode 100644
index 9cc665537..000000000
Binary files a/src/frontend/wwwroot/assets/favicon/favicon-16x16.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/favicon/favicon-32x32.png b/src/frontend/wwwroot/assets/favicon/favicon-32x32.png
deleted file mode 100644
index f7effc777..000000000
Binary files a/src/frontend/wwwroot/assets/favicon/favicon-32x32.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/images/A.png b/src/frontend/wwwroot/assets/images/A.png
deleted file mode 100644
index 59d9bb3d4..000000000
Binary files a/src/frontend/wwwroot/assets/images/A.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/images/AA.png b/src/frontend/wwwroot/assets/images/AA.png
deleted file mode 100644
index 69abd5ba4..000000000
Binary files a/src/frontend/wwwroot/assets/images/AA.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/images/CA.png b/src/frontend/wwwroot/assets/images/CA.png
deleted file mode 100644
index c863a0850..000000000
Binary files a/src/frontend/wwwroot/assets/images/CA.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/images/EA.png b/src/frontend/wwwroot/assets/images/EA.png
deleted file mode 100644
index 76fed32b0..000000000
Binary files a/src/frontend/wwwroot/assets/images/EA.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/images/HA.png b/src/frontend/wwwroot/assets/images/HA.png
deleted file mode 100644
index 7bb79582d..000000000
Binary files a/src/frontend/wwwroot/assets/images/HA.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/images/PA.png b/src/frontend/wwwroot/assets/images/PA.png
deleted file mode 100644
index 279d85cd9..000000000
Binary files a/src/frontend/wwwroot/assets/images/PA.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/images/SA.png b/src/frontend/wwwroot/assets/images/SA.png
deleted file mode 100644
index 6ac72482c..000000000
Binary files a/src/frontend/wwwroot/assets/images/SA.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/images/TA.png b/src/frontend/wwwroot/assets/images/TA.png
deleted file mode 100644
index 9c6ccc0f1..000000000
Binary files a/src/frontend/wwwroot/assets/images/TA.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/images/U.png b/src/frontend/wwwroot/assets/images/U.png
deleted file mode 100644
index 93f91f470..000000000
Binary files a/src/frontend/wwwroot/assets/images/U.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/images/Unknown.png b/src/frontend/wwwroot/assets/images/Unknown.png
deleted file mode 100644
index 31e8aa766..000000000
Binary files a/src/frontend/wwwroot/assets/images/Unknown.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/images/add.png b/src/frontend/wwwroot/assets/images/add.png
deleted file mode 100644
index 132646532..000000000
Binary files a/src/frontend/wwwroot/assets/images/add.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/images/air-button.svg b/src/frontend/wwwroot/assets/images/air-button.svg
deleted file mode 100644
index 7bdbd82b6..000000000
--- a/src/frontend/wwwroot/assets/images/air-button.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/src/frontend/wwwroot/assets/images/done.png b/src/frontend/wwwroot/assets/images/done.png
deleted file mode 100644
index bda7ce6ac..000000000
Binary files a/src/frontend/wwwroot/assets/images/done.png and /dev/null differ
diff --git a/src/frontend/wwwroot/assets/images/stars.svg b/src/frontend/wwwroot/assets/images/stars.svg
deleted file mode 100644
index e17395da6..000000000
--- a/src/frontend/wwwroot/assets/images/stars.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/src/frontend/wwwroot/assets/microsoft-logo.svg b/src/frontend/wwwroot/assets/microsoft-logo.svg
deleted file mode 100644
index 1f1848872..000000000
--- a/src/frontend/wwwroot/assets/microsoft-logo.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/frontend/wwwroot/assets/theme.css b/src/frontend/wwwroot/assets/theme.css
deleted file mode 100644
index 211b5ae28..000000000
--- a/src/frontend/wwwroot/assets/theme.css
+++ /dev/null
@@ -1,162 +0,0 @@
-:root {
- --bulma-link-h: 200deg;
- --bulma-info-s: 0%;
- --bulma-link-l: 0%;
-
- --bulma-info-h: 237deg;
- --bulma-info-s: 80%;
- --bulma-info-l: 60%;
-
- --bulma-focus-h: 237deg;
- --bulma-focus-s: 80%;
- --bulma-focus-l: 60%;
-
- --bulma-scheme-h: 200;
- --bulma-scheme-s: 0%;
-
- --bulma-soft-l: 80%;
- --bulma-bold-l: 0%;
-
- --bulma-family-primary: ui-sans-serif, -apple-system, system-ui, Segoe UI, Helvetica, Apple Color Emoji, Arial, sans-serif, Segoe UI Emoji, Segoe UI Symbol;
- --bulma-family-secondary: ui-sans-serif, -apple-system, system-ui, Segoe UI, Helvetica, Apple Color Emoji, Arial, sans-serif, Segoe UI Emoji, Segoe UI Symbol;
-
- --bulma-body-background-color: hsl(0, 100%, 100%);
- --bulma-body-color: rgb(74, 74, 74);
- --bulma-strong-color: hsl(0, 0%, 0%);
- --bulma-control-radius: 1000px;
- --bulma-info-invert-l: 98%;
-
- --bulma-success-h: 134deg;
- --bulma-success-s: 61%;
- --bulma-success-l: 41%;
- --bulma-success-invert-l: 98%;
-
- --bulma-danger-h: 354deg;
- --bulma-danger-s: 70%;
- --bulma-danger-l: 54%;
-}
-
-.card {
- --bulma-card-color: rgb(74, 74, 74);
- --bulma-card-shadow: rgba(51, 51, 51, 0.05) 0px 1px 2px 0px,
- rgba(51, 51, 51, 0.05) 0px 2px 4px 0px,
- rgb(214, 217, 224) 0px 0px 0px 1px inset;
- --bulma-card-header-shadow: 0;
-}
-
-.card.is-hoverable {
- transition: all 0.2s ease-in-out;
-}
-
-.card.is-hoverable:hover {
- cursor: pointer;
- transform: translateY(-2px);
- --bulma-card-shadow: 0 0 2px rgba(0, 0, 0, 0.12),
- 0 4px 8px rgba(0, 0, 0, 0.14),
- rgb(70, 79, 235) 0px 0px 0px 1px inset;
-}
-
-.media {
- --bulma-media-border-size: 0;
-}
-
-.modal-card-head {
- box-shadow: 0px 1px 1px 0px rgb(214, 217, 224);
-}
-
-.modal {
- --bulma-modal-background-background-color: hsla(0, 0%, 0%, 0.5);
- --bulma-modal-card-head-background-color: hsl(0, 0%, 100%);
- --bulma-modal-card-title-color: hsl(0, 0%, 0%);
- --bulma-modal-card-foot-background-color: hsl(0, 0%, 100%);
- --bulma-modal-card-body-background-color: hsl(0, 0%, 100%);
-}
-
-.box {
- --bulma-box-color: hsl(var(--bulma-menu-item-h), var(--bulma-menu-item-s), var(--bulma-menu-item-color-l));
- --bulma-box-shadow: rgb(214, 217, 224) 0px 0px 0px 1px;
-}
-
-.panel {
- --bulma-panel-shadow: rgb(214, 217, 224) 0px 0px 0px 1px;
- --bulma-panel-block-hover-background-color: hsl(0, 0%, 100%);
-}
-
-.tabs {
- --bulma-tabs-link-active-border-bottom-color: hsl(0, 0%, 0%);
- --bulma-tabs-link-active-color: hsl(0, 0%, 0%);
-}
-
-.tag {
- border-radius: var(--bulma-control-radius);
- font-weight: 500;
-}
-
-.menu-label {
- --bulma-menu-label-color: hsl(0, 0%, 0%);
- --bulma-menu-label-font-size: .85rem;
- text-transform: none;
- font-weight: 500;
- letter-spacing: 0;
-}
-
-.menu-list i {
- color: hsl(0, 0%, 0%);
-}
-
-.title {
- font-weight: 700;
- color: hsl(0, 0%, 0%);
-}
-
-.button {
- --bulma-button-ghost-color: hsl(0, 0%, 0%);
-}
-
-.modal {
- --bulma-modal-card-title-size: 1.15rem;
- --bulma-modal-card-head-padding: 1rem 2rem;
-}
-
-.modal-card-title {
- font-weight: 600;
-}
-
-.modal-card-head {
- display: flex;
- align-items: center;
-}
-
-.modal-card-head .button {
- --bulma-button-padding-horizontal: 0.68rem;
-}
-
-.modal-card-head .button i {
- margin-top: 1px;
-}
-
-.dropdown-content {
- padding: var(--bulma-dropdown-content-padding-bottom);
- box-shadow: var(--bulma-dropdown-content-shadow), rgb(214, 217, 224) 0px 0px 0px 1px inset;
-}
-
-.dropdown-content a.dropdown-item {
- border-radius: 0.25rem;
-}
-
-.input:focus,
-.input:focus-within,
-.is-focused.input,
-.is-focused.textarea,
-.select select.is-focused,
-.select select:focus,
-.select select:focus-within,
-.textarea:focus,
-.textarea:focus-within {
- border-color: hsl(var(--bulma-input-focus-h), var(--bulma-input-focus-s), var(--bulma-input-focus-l));
- box-shadow: var(--bulma-input-focus-shadow-size) hsla(var(--bulma-input-focus-h), var(--bulma-input-focus-s), var(--bulma-input-focus-l), var(--bulma-input-focus-shadow-alpha));
-}
-
-.progress::-webkit-progress-value {
- transition: width 0.5s ease;
-}
\ No newline at end of file
diff --git a/src/frontend/wwwroot/assets/title.svg b/src/frontend/wwwroot/assets/title.svg
deleted file mode 100644
index 890ab9751..000000000
--- a/src/frontend/wwwroot/assets/title.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/src/frontend/wwwroot/home/home.css b/src/frontend/wwwroot/home/home.css
deleted file mode 100644
index 292d3bd20..000000000
--- a/src/frontend/wwwroot/home/home.css
+++ /dev/null
@@ -1,269 +0,0 @@
-@import "../app.css";
-
-.container {
- inset: 0;
- min-height: 100vh;
- overflow-y: auto;
-}
-
-.section {
- min-width: 800px;
- z-index: 1;
-}
-
-.app-logo {
- width: 60px;
- margin: 0 auto;
-}
-
-.background {
- inset: 0;
- position: absolute;
- opacity: 0.1;
- overflow-y: hidden;
-}
-
-.description {
- color: Black;
- text-align: center;
-
- /* Web/Body 1 */
- font-family: "Segoe UI";
- font-size: 14px;
- font-style: normal;
- font-weight: 400;
- line-height: 20px; /* 142.857% */
- margin-bottom: 10px;
-}
-
-.title {
- color: var(
- --Light-Mode-Foreground-Neutral-Primary,
- var(--Foreground-Neutral-Primary, #111)
- );
- text-align: center;
- font-family: "Segoe UI";
- font-size: 32px;
- font-style: normal;
- font-weight: 700;
- line-height: 40px; /* 125% */
-}
-
-.assistants {
- text-align: center;
- font-family: "Segoe UI";
- font-size: 32px;
- font-style: normal;
- font-weight: 700;
- line-height: 40px; /* 125% */
-
- background: var(
- --Gradient-M365-Chat-Light-Accessible,
- linear-gradient(90deg, #464feb 10.42%, #8330e9 100%)
- );
- background-clip: text;
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
-}
-
-.orb {
- width: 50%;
- height: 50%;
- border-radius: 50%;
- filter: blur(50px);
- background: radial-gradient(circle);
- position: absolute;
-}
-
-.orb.one {
- bottom: -40%;
- left: 47.5%;
- background-color: rgba(70, 79, 235, 1);
-}
-
-.orb.two {
- bottom: -30%;
- left: 25%;
- background-color: rgb(18, 172, 149);
- z-index: 1;
-}
-
-.orb.three {
- bottom: -40%;
- left: 2.5%;
- background-color: rgb(199, 20, 184);
-}
-
-.new-task-control:has(> textarea:disabled)::before,
-.new-task-control:has(> textarea:disabled)::after {
- pointer-events: none;
- content: "";
- position: absolute;
- left: -2px;
- top: -2px;
- background: linear-gradient(
- 45deg,
- #fb0094,
- #0000ff,
- #fb0094,
- #0000ff,
- #fb0094,
- #0000ff,
- #fb0094,
- #0000ff
- );
- background-size: 400%;
- width: calc(100% + 4px);
- height: calc(100% + 4px);
- border-radius: var(--bulma-input-radius);
- opacity: 0.5;
- z-index: -1;
- animation: steam 20s linear infinite;
-}
-
-@keyframes steam {
- 0% {
- background-position: 0 0;
- }
-
- 50% {
- background-position: 400% 0;
- }
-
- 100% {
- background-position: 0 0;
- }
-}
-
-.new-task-control::after {
- filter: blur(25px);
-}
-
-.text-input-container {
- width: 950px;
- position: relative;
- border: 1px solid #ccc;
- border-radius: 8px;
- background-color: white;
-}
-
-textarea {
- width: 98%;
- padding: 16px 0px 0px 0px;
- border: none;
- border-radius: 8px 8px 0 0;
- font-size: 16px;
- line-height: 1.5;
- resize: none;
- outline: none;
- overflow: hidden;
- margin: 0 10px;
- align-items: center;
- background-color: white;
-}
-textarea:disabled {
- cursor: default;
- background-color: white;
-}
-
-/*Spinner start*/
-#spinnerLoader {
- display: flex;
- flex-direction: column;
- /* justify-content: center; */
- align-items: center;
- position: absolute;
- inset: 0;
- color: black;
- top: 30%;
- left: 50%;
- transform: translateX(-50%);
- /* background-color: rgb(247, 249, 251);*/
- z-index: 9999;
- font-weight: 500;
-}
-
-#spinnerLoader span::before {
- content: "Creating Tasks...";
- animation: spinLoaderAnimation infinite 3s linear;
-}
-
-@keyframes spinLoaderAnimation {
- 75% {
- content: "Agents are on it...";
- }
-}
-
-#spinnerLoader i {
- font-size: 3rem;
-}
-
-#overlay {
- position: fixed;
- display: none;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: rgba(255, 255, 255, 0.5);
-
- z-index: 1;
-}
-
-/*Spinner end*/
-
-.middle-bar {
- display: flex;
- justify-content: space-between;
- align-items: left;
- padding: 0px 5px;
- background-color: white;
-}
-
-.bottom-bar {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 3px 10px;
- border-top: none;
- border-bottom: 4px solid #0f6cbd;
- background-color: white;
-}
-
-.icons {
- display: flex;
- align-items: center;
-}
-
-.star-icon {
- margin-right: 10px;
- cursor: pointer;
-}
-
-.char-count {
- font-size: 14px;
- color: #888;
-}
-
-.send-button {
- border: none;
- background: none;
- font-size: 18px;
- cursor: pointer;
- color: #007bff;
- padding: 4px;
- outline: none;
-}
-
-.send-button:hover {
- color: #0056b3;
-}
-
-.card.is-hoverable.quick-task > .card-content {
- min-height: 225px;
-}
-
-.prompt-container {
- padding-top: 2rem;
- padding-bottom: 2rem;
-}
\ No newline at end of file
diff --git a/src/frontend/wwwroot/home/home.html b/src/frontend/wwwroot/home/home.html
deleted file mode 100644
index 679f082b6..000000000
--- a/src/frontend/wwwroot/home/home.html
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
-
-
-
- Home
-
-
-
-
-
-
-
-
-
-
- Task list Assistants
- Ask your AI team for help
-
-
-
- 0 /1000
-
-
-
-
-
-
-
-
-
-
-
-
- Quick tasks
-
-
-
-
-
-
Mobile plan query
-
I'm looking for information about a roaming plan as I'm headed overseas.
-
-
-
-
-
-
-
-
Buy add-on pack
-
Please enable roaming on my mobile plan, starting next week.
-
-
-
-
-
-
-
-
Onboard employee
-
Onboard a new employee, Jessica Smith.
-
-
-
-
-
-
-
-
Draft a press release
-
Get info about our products. Write a press release about our current products.
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/frontend/wwwroot/home/home.js b/src/frontend/wwwroot/home/home.js
deleted file mode 100644
index dd1828793..000000000
--- a/src/frontend/wwwroot/home/home.js
+++ /dev/null
@@ -1,216 +0,0 @@
-(() => {
- const notyf = new Notyf({
- position: { x: "right", y: "top" },
- ripple: false,
- duration: 3000,
- });
- const apiEndpoint = getStoredData("apiEndpoint");
- const newTaskPrompt = document.getElementById("newTaskPrompt");
- const startTaskButton = document.getElementById("startTaskButton");
- const startTaskButtonContainer = document.querySelector(".send-button");
- const startTaskButtonImg = startTaskButtonContainer
- ? startTaskButtonContainer.querySelector("img")
- : null;
-
- newTaskPrompt.focus();
-
- // Create spinner element
- const createSpinner = () => {
- if (!document.getElementById("spinnerContainer")) {
- const spinnerContainer = document.createElement("div");
- spinnerContainer.id = "spinnerContainer";
- spinnerContainer.innerHTML = `
-
-
-
-
-
- `;
- document.body.appendChild(spinnerContainer);
- }
- };
-
- // Function to create and add the overlay
- const createOverlay = () => {
- let overlay = document.getElementById("overlay");
- if (!overlay) {
- overlay = document.createElement("div");
- overlay.id = "overlay";
- document.body.appendChild(overlay);
- }
- };
-
- const showOverlay = () => {
- const overlay = document.getElementById("overlay");
- if (overlay) {
- overlay.style.display = "block";
- }
- createSpinner();
- };
-
- const hideOverlay = () => {
- const overlay = document.getElementById("overlay");
- if (overlay) {
- overlay.style.display = "none";
- }
- removeSpinner();
- };
-
- // Remove spinner element
- const removeSpinner = () => {
- const spinnerContainer = document.getElementById("spinnerContainer");
- if (spinnerContainer) {
- spinnerContainer.remove();
- }
- };
-
- // Function to update button image based on textarea content
- const updateButtonImage = () => {
- if (startTaskButtonImg) {
- if (newTaskPrompt.value.trim() === "") {
- startTaskButtonImg.src = "../assets/images/air-button.svg";
- startTaskButton.disabled = true;
- } else {
- startTaskButtonImg.src = "/assets/Send.svg";
- startTaskButtonImg.style.width = "16px";
- startTaskButtonImg.style.height = "16px";
- startTaskButton.disabled = false;
- }
- }
- };
-
- const startTask = () => {
- startTaskButton.addEventListener("click", (event) => {
- if (startTaskButton.disabled) {
- return;
- }
- const sessionId =
- "sid_" + new Date().getTime() + "_" + Math.floor(Math.random() * 10000);
-
- newTaskPrompt.disabled = true;
- startTaskButton.disabled = true;
- startTaskButton.classList.add("is-loading");
- createOverlay();
- showOverlay();
- window.headers.then((headers) => {
- fetch(apiEndpoint + "/input_task", {
- method: "POST",
- headers: headers,
- body: JSON.stringify({
- session_id: sessionId,
- description: newTaskPrompt.value,
- }),
- })
- .then((response) => response.json())
- .then((data) => {
- // Check if 'detail' field contains rate limit error
- if (data.detail && data.detail.includes("Rate limit is exceeded")) {
- notyf.error("Application temporarily unavailable due to quota limits. Please try again later.");
- newTaskPrompt.disabled = false;
- startTaskButton.disabled = false;
- startTaskButton.classList.remove("is-loading");
- hideOverlay();
- return;
- }
-
- if (data.status == "Plan not created" || data.plan_id == "") {
- notyf.error("Unable to create plan for this task.");
- newTaskPrompt.disabled = false;
- startTaskButton.disabled = false;
- hideOverlay();
- return;
- }
-
- newTaskPrompt.disabled = false;
- startTaskButton.disabled = false;
- startTaskButton.classList.remove("is-loading");
-
- window.parent.postMessage(
- {
- action: "taskStarted",
- session_id: data.session_id,
- task_id: data.plan_id,
- task_name: newTaskPrompt.value,
- },
- "*"
- );
-
- newTaskPrompt.value = "";
-
- // Reset character count to 0
- const charCount = document.getElementById("charCount");
- if (charCount) {
- charCount.textContent = "0";
- }
- updateButtonImage();
- notyf.success("Task created successfully. AI agents are on it!");
-
- // Remove spinner and hide overlay
- removeSpinner();
- hideOverlay();
- })
- .catch((error) => {
- console.error("Error:", error);
- newTaskPrompt.disabled = false;
- startTaskButton.disabled = false;
- startTaskButton.classList.remove("is-loading");
-
- // Remove spinner and hide overlay
- removeSpinner();
- hideOverlay();
- });
- });
- });
- };
-
- const quickTasks = () => {
- document.querySelectorAll(".quick-task").forEach((task) => {
- task.addEventListener("click", (event) => {
- const quickTaskPrompt =
- task.querySelector(".quick-task-prompt").innerHTML;
- newTaskPrompt.value = quickTaskPrompt.trim().replace(/\s+/g, " ");
- const charCount = document.getElementById("charCount");
- // Update character count
- charCount.textContent = newTaskPrompt.value.length;
- updateButtonImage();
- newTaskPrompt.focus();
- });
- });
- };
- const handleTextAreaTyping = () => {
- const newTaskPrompt = document.getElementById("newTaskPrompt");
- newTaskPrompt.addEventListener("input", () => {
- // const textInput = document.getElementById("newTaskPrompt");
- const charCount = document.getElementById("charCount");
-
- // Update character count
- charCount.textContent = newTaskPrompt.value.length;
-
- // Dynamically adjust height
- newTaskPrompt.style.height = "auto";
- newTaskPrompt.style.height = newTaskPrompt.scrollHeight + "px";
-
- updateButtonImage();
- });
-
- newTaskPrompt.addEventListener("keydown", (event) => {
- const textValue = newTaskPrompt.value.trim();
- // If Enter is pressed without Shift, and the textarea is empty, prevent default behavior
- if (event.key === "Enter" && !event.shiftKey) {
- if (textValue === "") {
- event.preventDefault(); // Disable Enter when textarea is empty
- } else {
- // If there's content in the textarea, allow Enter to trigger the task button click
- startTaskButton.click();
- }
- } else if (event.key === "Enter" && event.shiftKey) {
- return;
- }
- });
- };
-
- updateButtonImage();
- startTask();
- quickTasks();
- handleTextAreaTyping();
-})();
diff --git a/src/frontend/wwwroot/libs/showdown.min.js b/src/frontend/wwwroot/libs/showdown.min.js
deleted file mode 100644
index cf721d9f0..000000000
--- a/src/frontend/wwwroot/libs/showdown.min.js
+++ /dev/null
@@ -1,3 +0,0 @@
-/*! showdown v 2.1.0 - 21-04-2022 */
-!function(){function a(e){"use strict";var r={omitExtraWLInCodeBlocks:{defaultValue:!1,describe:"Omit the default extra whiteline added to code blocks",type:"boolean"},noHeaderId:{defaultValue:!1,describe:"Turn on/off generated header id",type:"boolean"},prefixHeaderId:{defaultValue:!1,describe:"Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic 'section-' prefix",type:"string"},rawPrefixHeaderId:{defaultValue:!1,describe:'Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix)',type:"boolean"},ghCompatibleHeaderId:{defaultValue:!1,describe:"Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)",type:"boolean"},rawHeaderId:{defaultValue:!1,describe:"Remove only spaces, ' and \" from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids",type:"boolean"},headerLevelStart:{defaultValue:!1,describe:"The header blocks level start",type:"integer"},parseImgDimensions:{defaultValue:!1,describe:"Turn on/off image dimension parsing",type:"boolean"},simplifiedAutoLink:{defaultValue:!1,describe:"Turn on/off GFM autolink style",type:"boolean"},excludeTrailingPunctuationFromURLs:{defaultValue:!1,describe:"Excludes trailing punctuation from links generated with autoLinking",type:"boolean"},literalMidWordUnderscores:{defaultValue:!1,describe:"Parse midword underscores as literal underscores",type:"boolean"},literalMidWordAsterisks:{defaultValue:!1,describe:"Parse midword asterisks as literal asterisks",type:"boolean"},strikethrough:{defaultValue:!1,describe:"Turn on/off strikethrough support",type:"boolean"},tables:{defaultValue:!1,describe:"Turn on/off tables support",type:"boolean"},tablesHeaderId:{defaultValue:!1,describe:"Add an id to table headers",type:"boolean"},ghCodeBlocks:{defaultValue:!0,describe:"Turn on/off GFM fenced code blocks support",type:"boolean"},tasklists:{defaultValue:!1,describe:"Turn on/off GFM tasklist support",type:"boolean"},smoothLivePreview:{defaultValue:!1,describe:"Prevents weird effects in live previews due to incomplete input",type:"boolean"},smartIndentationFix:{defaultValue:!1,describe:"Tries to smartly fix indentation in es6 strings",type:"boolean"},disableForced4SpacesIndentedSublists:{defaultValue:!1,describe:"Disables the requirement of indenting nested sublists by 4 spaces",type:"boolean"},simpleLineBreaks:{defaultValue:!1,describe:"Parses simple line breaks as (GFM Style)",type:"boolean"},requireSpaceBeforeHeadingText:{defaultValue:!1,describe:"Makes adding a space between `#` and the header text mandatory (GFM Style)",type:"boolean"},ghMentions:{defaultValue:!1,describe:"Enables github @mentions",type:"boolean"},ghMentionsLink:{defaultValue:"https://github.com/{u}",describe:"Changes the link generated by @mentions. Only applies if ghMentions option is enabled.",type:"string"},encodeEmails:{defaultValue:!0,describe:"Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities",type:"boolean"},openLinksInNewWindow:{defaultValue:!1,describe:"Open all links in new windows",type:"boolean"},backslashEscapesHTMLTags:{defaultValue:!1,describe:"Support for HTML Tag escaping. ex: foo
",type:"boolean"},emoji:{defaultValue:!1,describe:"Enable emoji support. Ex: `this is a :smile: emoji`",type:"boolean"},underline:{defaultValue:!1,describe:"Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `` and ``",type:"boolean"},ellipsis:{defaultValue:!0,describe:"Replaces three dots with the ellipsis unicode character",type:"boolean"},completeHTMLDocument:{defaultValue:!1,describe:"Outputs a complete html document, including ``, `` and `` tags",type:"boolean"},metadata:{defaultValue:!1,describe:"Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).",type:"boolean"},splitAdjacentBlockquotes:{defaultValue:!1,describe:"Split adjacent blockquote blocks",type:"boolean"}};if(!1===e)return JSON.parse(JSON.stringify(r));var t,a={};for(t in r)r.hasOwnProperty(t)&&(a[t]=r[t].defaultValue);return a}var x={},t={},d={},p=a(!0),h="vanilla",_={github:{omitExtraWLInCodeBlocks:!0,simplifiedAutoLink:!0,excludeTrailingPunctuationFromURLs:!0,literalMidWordUnderscores:!0,strikethrough:!0,tables:!0,tablesHeaderId:!0,ghCodeBlocks:!0,tasklists:!0,disableForced4SpacesIndentedSublists:!0,simpleLineBreaks:!0,requireSpaceBeforeHeadingText:!0,ghCompatibleHeaderId:!0,ghMentions:!0,backslashEscapesHTMLTags:!0,emoji:!0,splitAdjacentBlockquotes:!0},original:{noHeaderId:!0,ghCodeBlocks:!1},ghost:{omitExtraWLInCodeBlocks:!0,parseImgDimensions:!0,simplifiedAutoLink:!0,excludeTrailingPunctuationFromURLs:!0,literalMidWordUnderscores:!0,strikethrough:!0,tables:!0,tablesHeaderId:!0,ghCodeBlocks:!0,tasklists:!0,smoothLivePreview:!0,simpleLineBreaks:!0,requireSpaceBeforeHeadingText:!0,ghMentions:!1,encodeEmails:!0},vanilla:a(!0),allOn:function(){"use strict";var e,r=a(!0),t={};for(e in r)r.hasOwnProperty(e)&&(t[e]=!0);return t}()};function g(e,r){"use strict";var t=r?"Error in "+r+" extension->":"Error in unnamed extension",a={valid:!0,error:""};x.helper.isArray(e)||(e=[e]);for(var n=0;n").replace(/&/g,"&")};function u(e,r,t,a){"use strict";var n,s,o,i=-1<(a=a||"").indexOf("g"),l=new RegExp(r+"|"+t,"g"+a.replace(/g/g,"")),c=new RegExp(r,a.replace(/g/g,"")),u=[];do{for(n=0;p=l.exec(e);)if(c.test(p[0]))n++||(o=(s=l.lastIndex)-p[0].length);else if(n&&!--n){var d=p.index+p[0].length,p={left:{start:o,end:s},match:{start:s,end:p.index},right:{start:p.index,end:d},wholeMatch:{start:o,end:d}};if(u.push(p),!i)return u}}while(n&&(l.lastIndex=s));return u}function s(u){"use strict";return function(e,r,t,a,n,s,o){var i=t=t.replace(x.helper.regexes.asteriskDashAndColon,x.helper.escapeCharactersCallback),l="",c="",r=r||"",o=o||"";return/^www\./i.test(t)&&(t=t.replace(/^www\./i,"http://www.")),u.excludeTrailingPunctuationFromURLs&&s&&(l=s),r+'"+i+" "+l+o}}function o(n,s){"use strict";return function(e,r,t){var a="mailto:";return r=r||"",t=x.subParser("unescapeSpecialChars")(t,n,s),n.encodeEmails?(a=x.helper.encodeEmailAddress(a+t),t=x.helper.encodeEmailAddress(t)):a+=t,r+''+t+" "}}x.helper.matchRecursiveRegExp=function(e,r,t,a){"use strict";for(var n=u(e,r,t,a),s=[],o=0;o>=0,t=String(t||" "),e.length>r?String(e):((r-=e.length)>t.length&&(t+=t.repeat(r/t.length)),String(e)+t.slice(0,r))},"undefined"==typeof console&&(console={warn:function(e){"use strict";alert(e)},log:function(e){"use strict";alert(e)},error:function(e){"use strict";throw e}}),x.helper.regexes={asteriskDashAndColon:/([*_:~])/g},x.helper.emojis={"+1":"👍","-1":"👎",100:"💯",1234:"🔢","1st_place_medal":"🥇","2nd_place_medal":"🥈","3rd_place_medal":"🥉","8ball":"🎱",a:"🅰️",ab:"🆎",abc:"🔤",abcd:"🔡",accept:"🉑",aerial_tramway:"🚡",airplane:"✈️",alarm_clock:"⏰",alembic:"⚗️",alien:"👽",ambulance:"🚑",amphora:"🏺",anchor:"⚓️",angel:"👼",anger:"💢",angry:"😠",anguished:"😧",ant:"🐜",apple:"🍎",aquarius:"♒️",aries:"♈️",arrow_backward:"◀️",arrow_double_down:"⏬",arrow_double_up:"⏫",arrow_down:"⬇️",arrow_down_small:"🔽",arrow_forward:"▶️",arrow_heading_down:"⤵️",arrow_heading_up:"⤴️",arrow_left:"⬅️",arrow_lower_left:"↙️",arrow_lower_right:"↘️",arrow_right:"➡️",arrow_right_hook:"↪️",arrow_up:"⬆️",arrow_up_down:"↕️",arrow_up_small:"🔼",arrow_upper_left:"↖️",arrow_upper_right:"↗️",arrows_clockwise:"🔃",arrows_counterclockwise:"🔄",art:"🎨",articulated_lorry:"🚛",artificial_satellite:"🛰",astonished:"😲",athletic_shoe:"👟",atm:"🏧",atom_symbol:"⚛️",avocado:"🥑",b:"🅱️",baby:"👶",baby_bottle:"🍼",baby_chick:"🐤",baby_symbol:"🚼",back:"🔙",bacon:"🥓",badminton:"🏸",baggage_claim:"🛄",baguette_bread:"🥖",balance_scale:"⚖️",balloon:"🎈",ballot_box:"🗳",ballot_box_with_check:"☑️",bamboo:"🎍",banana:"🍌",bangbang:"‼️",bank:"🏦",bar_chart:"📊",barber:"💈",baseball:"⚾️",basketball:"🏀",basketball_man:"⛹️",basketball_woman:"⛹️♀️",bat:"🦇",bath:"🛀",bathtub:"🛁",battery:"🔋",beach_umbrella:"🏖",bear:"🐻",bed:"🛏",bee:"🐝",beer:"🍺",beers:"🍻",beetle:"🐞",beginner:"🔰",bell:"🔔",bellhop_bell:"🛎",bento:"🍱",biking_man:"🚴",bike:"🚲",biking_woman:"🚴♀️",bikini:"👙",biohazard:"☣️",bird:"🐦",birthday:"🎂",black_circle:"⚫️",black_flag:"🏴",black_heart:"🖤",black_joker:"🃏",black_large_square:"⬛️",black_medium_small_square:"◾️",black_medium_square:"◼️",black_nib:"✒️",black_small_square:"▪️",black_square_button:"🔲",blonde_man:"👱",blonde_woman:"👱♀️",blossom:"🌼",blowfish:"🐡",blue_book:"📘",blue_car:"🚙",blue_heart:"💙",blush:"😊",boar:"🐗",boat:"⛵️",bomb:"💣",book:"📖",bookmark:"🔖",bookmark_tabs:"📑",books:"📚",boom:"💥",boot:"👢",bouquet:"💐",bowing_man:"🙇",bow_and_arrow:"🏹",bowing_woman:"🙇♀️",bowling:"🎳",boxing_glove:"🥊",boy:"👦",bread:"🍞",bride_with_veil:"👰",bridge_at_night:"🌉",briefcase:"💼",broken_heart:"💔",bug:"🐛",building_construction:"🏗",bulb:"💡",bullettrain_front:"🚅",bullettrain_side:"🚄",burrito:"🌯",bus:"🚌",business_suit_levitating:"🕴",busstop:"🚏",bust_in_silhouette:"👤",busts_in_silhouette:"👥",butterfly:"🦋",cactus:"🌵",cake:"🍰",calendar:"📆",call_me_hand:"🤙",calling:"📲",camel:"🐫",camera:"📷",camera_flash:"📸",camping:"🏕",cancer:"♋️",candle:"🕯",candy:"🍬",canoe:"🛶",capital_abcd:"🔠",capricorn:"♑️",car:"🚗",card_file_box:"🗃",card_index:"📇",card_index_dividers:"🗂",carousel_horse:"🎠",carrot:"🥕",cat:"🐱",cat2:"🐈",cd:"💿",chains:"⛓",champagne:"🍾",chart:"💹",chart_with_downwards_trend:"📉",chart_with_upwards_trend:"📈",checkered_flag:"🏁",cheese:"🧀",cherries:"🍒",cherry_blossom:"🌸",chestnut:"🌰",chicken:"🐔",children_crossing:"🚸",chipmunk:"🐿",chocolate_bar:"🍫",christmas_tree:"🎄",church:"⛪️",cinema:"🎦",circus_tent:"🎪",city_sunrise:"🌇",city_sunset:"🌆",cityscape:"🏙",cl:"🆑",clamp:"🗜",clap:"👏",clapper:"🎬",classical_building:"🏛",clinking_glasses:"🥂",clipboard:"📋",clock1:"🕐",clock10:"🕙",clock1030:"🕥",clock11:"🕚",clock1130:"🕦",clock12:"🕛",clock1230:"🕧",clock130:"🕜",clock2:"🕑",clock230:"🕝",clock3:"🕒",clock330:"🕞",clock4:"🕓",clock430:"🕟",clock5:"🕔",clock530:"🕠",clock6:"🕕",clock630:"🕡",clock7:"🕖",clock730:"🕢",clock8:"🕗",clock830:"🕣",clock9:"🕘",clock930:"🕤",closed_book:"📕",closed_lock_with_key:"🔐",closed_umbrella:"🌂",cloud:"☁️",cloud_with_lightning:"🌩",cloud_with_lightning_and_rain:"⛈",cloud_with_rain:"🌧",cloud_with_snow:"🌨",clown_face:"🤡",clubs:"♣️",cocktail:"🍸",coffee:"☕️",coffin:"⚰️",cold_sweat:"😰",comet:"☄️",computer:"💻",computer_mouse:"🖱",confetti_ball:"🎊",confounded:"😖",confused:"😕",congratulations:"㊗️",construction:"🚧",construction_worker_man:"👷",construction_worker_woman:"👷♀️",control_knobs:"🎛",convenience_store:"🏪",cookie:"🍪",cool:"🆒",policeman:"👮",copyright:"©️",corn:"🌽",couch_and_lamp:"🛋",couple:"👫",couple_with_heart_woman_man:"💑",couple_with_heart_man_man:"👨❤️👨",couple_with_heart_woman_woman:"👩❤️👩",couplekiss_man_man:"👨❤️💋👨",couplekiss_man_woman:"💏",couplekiss_woman_woman:"👩❤️💋👩",cow:"🐮",cow2:"🐄",cowboy_hat_face:"🤠",crab:"🦀",crayon:"🖍",credit_card:"💳",crescent_moon:"🌙",cricket:"🏏",crocodile:"🐊",croissant:"🥐",crossed_fingers:"🤞",crossed_flags:"🎌",crossed_swords:"⚔️",crown:"👑",cry:"😢",crying_cat_face:"😿",crystal_ball:"🔮",cucumber:"🥒",cupid:"💘",curly_loop:"➰",currency_exchange:"💱",curry:"🍛",custard:"🍮",customs:"🛃",cyclone:"🌀",dagger:"🗡",dancer:"💃",dancing_women:"👯",dancing_men:"👯♂️",dango:"🍡",dark_sunglasses:"🕶",dart:"🎯",dash:"💨",date:"📅",deciduous_tree:"🌳",deer:"🦌",department_store:"🏬",derelict_house:"🏚",desert:"🏜",desert_island:"🏝",desktop_computer:"🖥",male_detective:"🕵️",diamond_shape_with_a_dot_inside:"💠",diamonds:"♦️",disappointed:"😞",disappointed_relieved:"😥",dizzy:"💫",dizzy_face:"😵",do_not_litter:"🚯",dog:"🐶",dog2:"🐕",dollar:"💵",dolls:"🎎",dolphin:"🐬",door:"🚪",doughnut:"🍩",dove:"🕊",dragon:"🐉",dragon_face:"🐲",dress:"👗",dromedary_camel:"🐪",drooling_face:"🤤",droplet:"💧",drum:"🥁",duck:"🦆",dvd:"📀","e-mail":"📧",eagle:"🦅",ear:"👂",ear_of_rice:"🌾",earth_africa:"🌍",earth_americas:"🌎",earth_asia:"🌏",egg:"🥚",eggplant:"🍆",eight_pointed_black_star:"✴️",eight_spoked_asterisk:"✳️",electric_plug:"🔌",elephant:"🐘",email:"✉️",end:"🔚",envelope_with_arrow:"📩",euro:"💶",european_castle:"🏰",european_post_office:"🏤",evergreen_tree:"🌲",exclamation:"❗️",expressionless:"😑",eye:"👁",eye_speech_bubble:"👁🗨",eyeglasses:"👓",eyes:"👀",face_with_head_bandage:"🤕",face_with_thermometer:"🤒",fist_oncoming:"👊",factory:"🏭",fallen_leaf:"🍂",family_man_woman_boy:"👪",family_man_boy:"👨👦",family_man_boy_boy:"👨👦👦",family_man_girl:"👨👧",family_man_girl_boy:"👨👧👦",family_man_girl_girl:"👨👧👧",family_man_man_boy:"👨👨👦",family_man_man_boy_boy:"👨👨👦👦",family_man_man_girl:"👨👨👧",family_man_man_girl_boy:"👨👨👧👦",family_man_man_girl_girl:"👨👨👧👧",family_man_woman_boy_boy:"👨👩👦👦",family_man_woman_girl:"👨👩👧",family_man_woman_girl_boy:"👨👩👧👦",family_man_woman_girl_girl:"👨👩👧👧",family_woman_boy:"👩👦",family_woman_boy_boy:"👩👦👦",family_woman_girl:"👩👧",family_woman_girl_boy:"👩👧👦",family_woman_girl_girl:"👩👧👧",family_woman_woman_boy:"👩👩👦",family_woman_woman_boy_boy:"👩👩👦👦",family_woman_woman_girl:"👩👩👧",family_woman_woman_girl_boy:"👩👩👧👦",family_woman_woman_girl_girl:"👩👩👧👧",fast_forward:"⏩",fax:"📠",fearful:"😨",feet:"🐾",female_detective:"🕵️♀️",ferris_wheel:"🎡",ferry:"⛴",field_hockey:"🏑",file_cabinet:"🗄",file_folder:"📁",film_projector:"📽",film_strip:"🎞",fire:"🔥",fire_engine:"🚒",fireworks:"🎆",first_quarter_moon:"🌓",first_quarter_moon_with_face:"🌛",fish:"🐟",fish_cake:"🍥",fishing_pole_and_fish:"🎣",fist_raised:"✊",fist_left:"🤛",fist_right:"🤜",flags:"🎏",flashlight:"🔦",fleur_de_lis:"⚜️",flight_arrival:"🛬",flight_departure:"🛫",floppy_disk:"💾",flower_playing_cards:"🎴",flushed:"😳",fog:"🌫",foggy:"🌁",football:"🏈",footprints:"👣",fork_and_knife:"🍴",fountain:"⛲️",fountain_pen:"🖋",four_leaf_clover:"🍀",fox_face:"🦊",framed_picture:"🖼",free:"🆓",fried_egg:"🍳",fried_shrimp:"🍤",fries:"🍟",frog:"🐸",frowning:"😦",frowning_face:"☹️",frowning_man:"🙍♂️",frowning_woman:"🙍",middle_finger:"🖕",fuelpump:"⛽️",full_moon:"🌕",full_moon_with_face:"🌝",funeral_urn:"⚱️",game_die:"🎲",gear:"⚙️",gem:"💎",gemini:"♊️",ghost:"👻",gift:"🎁",gift_heart:"💝",girl:"👧",globe_with_meridians:"🌐",goal_net:"🥅",goat:"🐐",golf:"⛳️",golfing_man:"🏌️",golfing_woman:"🏌️♀️",gorilla:"🦍",grapes:"🍇",green_apple:"🍏",green_book:"📗",green_heart:"💚",green_salad:"🥗",grey_exclamation:"❕",grey_question:"❔",grimacing:"😬",grin:"😁",grinning:"😀",guardsman:"💂",guardswoman:"💂♀️",guitar:"🎸",gun:"🔫",haircut_woman:"💇",haircut_man:"💇♂️",hamburger:"🍔",hammer:"🔨",hammer_and_pick:"⚒",hammer_and_wrench:"🛠",hamster:"🐹",hand:"✋",handbag:"👜",handshake:"🤝",hankey:"💩",hatched_chick:"🐥",hatching_chick:"🐣",headphones:"🎧",hear_no_evil:"🙉",heart:"❤️",heart_decoration:"💟",heart_eyes:"😍",heart_eyes_cat:"😻",heartbeat:"💓",heartpulse:"💗",hearts:"♥️",heavy_check_mark:"✔️",heavy_division_sign:"➗",heavy_dollar_sign:"💲",heavy_heart_exclamation:"❣️",heavy_minus_sign:"➖",heavy_multiplication_x:"✖️",heavy_plus_sign:"➕",helicopter:"🚁",herb:"🌿",hibiscus:"🌺",high_brightness:"🔆",high_heel:"👠",hocho:"🔪",hole:"🕳",honey_pot:"🍯",horse:"🐴",horse_racing:"🏇",hospital:"🏥",hot_pepper:"🌶",hotdog:"🌭",hotel:"🏨",hotsprings:"♨️",hourglass:"⌛️",hourglass_flowing_sand:"⏳",house:"🏠",house_with_garden:"🏡",houses:"🏘",hugs:"🤗",hushed:"😯",ice_cream:"🍨",ice_hockey:"🏒",ice_skate:"⛸",icecream:"🍦",id:"🆔",ideograph_advantage:"🉐",imp:"👿",inbox_tray:"📥",incoming_envelope:"📨",tipping_hand_woman:"💁",information_source:"ℹ️",innocent:"😇",interrobang:"⁉️",iphone:"📱",izakaya_lantern:"🏮",jack_o_lantern:"🎃",japan:"🗾",japanese_castle:"🏯",japanese_goblin:"👺",japanese_ogre:"👹",jeans:"👖",joy:"😂",joy_cat:"😹",joystick:"🕹",kaaba:"🕋",key:"🔑",keyboard:"⌨️",keycap_ten:"🔟",kick_scooter:"🛴",kimono:"👘",kiss:"💋",kissing:"😗",kissing_cat:"😽",kissing_closed_eyes:"😚",kissing_heart:"😘",kissing_smiling_eyes:"😙",kiwi_fruit:"🥝",koala:"🐨",koko:"🈁",label:"🏷",large_blue_circle:"🔵",large_blue_diamond:"🔷",large_orange_diamond:"🔶",last_quarter_moon:"🌗",last_quarter_moon_with_face:"🌜",latin_cross:"✝️",laughing:"😆",leaves:"🍃",ledger:"📒",left_luggage:"🛅",left_right_arrow:"↔️",leftwards_arrow_with_hook:"↩️",lemon:"🍋",leo:"♌️",leopard:"🐆",level_slider:"🎚",libra:"♎️",light_rail:"🚈",link:"🔗",lion:"🦁",lips:"👄",lipstick:"💄",lizard:"🦎",lock:"🔒",lock_with_ink_pen:"🔏",lollipop:"🍭",loop:"➿",loud_sound:"🔊",loudspeaker:"📢",love_hotel:"🏩",love_letter:"💌",low_brightness:"🔅",lying_face:"🤥",m:"Ⓜ️",mag:"🔍",mag_right:"🔎",mahjong:"🀄️",mailbox:"📫",mailbox_closed:"📪",mailbox_with_mail:"📬",mailbox_with_no_mail:"📭",man:"👨",man_artist:"👨🎨",man_astronaut:"👨🚀",man_cartwheeling:"🤸♂️",man_cook:"👨🍳",man_dancing:"🕺",man_facepalming:"🤦♂️",man_factory_worker:"👨🏭",man_farmer:"👨🌾",man_firefighter:"👨🚒",man_health_worker:"👨⚕️",man_in_tuxedo:"🤵",man_judge:"👨⚖️",man_juggling:"🤹♂️",man_mechanic:"👨🔧",man_office_worker:"👨💼",man_pilot:"👨✈️",man_playing_handball:"🤾♂️",man_playing_water_polo:"🤽♂️",man_scientist:"👨🔬",man_shrugging:"🤷♂️",man_singer:"👨🎤",man_student:"👨🎓",man_teacher:"👨🏫",man_technologist:"👨💻",man_with_gua_pi_mao:"👲",man_with_turban:"👳",tangerine:"🍊",mans_shoe:"👞",mantelpiece_clock:"🕰",maple_leaf:"🍁",martial_arts_uniform:"🥋",mask:"😷",massage_woman:"💆",massage_man:"💆♂️",meat_on_bone:"🍖",medal_military:"🎖",medal_sports:"🏅",mega:"📣",melon:"🍈",memo:"📝",men_wrestling:"🤼♂️",menorah:"🕎",mens:"🚹",metal:"🤘",metro:"🚇",microphone:"🎤",microscope:"🔬",milk_glass:"🥛",milky_way:"🌌",minibus:"🚐",minidisc:"💽",mobile_phone_off:"📴",money_mouth_face:"🤑",money_with_wings:"💸",moneybag:"💰",monkey:"🐒",monkey_face:"🐵",monorail:"🚝",moon:"🌔",mortar_board:"🎓",mosque:"🕌",motor_boat:"🛥",motor_scooter:"🛵",motorcycle:"🏍",motorway:"🛣",mount_fuji:"🗻",mountain:"⛰",mountain_biking_man:"🚵",mountain_biking_woman:"🚵♀️",mountain_cableway:"🚠",mountain_railway:"🚞",mountain_snow:"🏔",mouse:"🐭",mouse2:"🐁",movie_camera:"🎥",moyai:"🗿",mrs_claus:"🤶",muscle:"💪",mushroom:"🍄",musical_keyboard:"🎹",musical_note:"🎵",musical_score:"🎼",mute:"🔇",nail_care:"💅",name_badge:"📛",national_park:"🏞",nauseated_face:"🤢",necktie:"👔",negative_squared_cross_mark:"❎",nerd_face:"🤓",neutral_face:"😐",new:"🆕",new_moon:"🌑",new_moon_with_face:"🌚",newspaper:"📰",newspaper_roll:"🗞",next_track_button:"⏭",ng:"🆖",no_good_man:"🙅♂️",no_good_woman:"🙅",night_with_stars:"🌃",no_bell:"🔕",no_bicycles:"🚳",no_entry:"⛔️",no_entry_sign:"🚫",no_mobile_phones:"📵",no_mouth:"😶",no_pedestrians:"🚷",no_smoking:"🚭","non-potable_water":"🚱",nose:"👃",notebook:"📓",notebook_with_decorative_cover:"📔",notes:"🎶",nut_and_bolt:"🔩",o:"⭕️",o2:"🅾️",ocean:"🌊",octopus:"🐙",oden:"🍢",office:"🏢",oil_drum:"🛢",ok:"🆗",ok_hand:"👌",ok_man:"🙆♂️",ok_woman:"🙆",old_key:"🗝",older_man:"👴",older_woman:"👵",om:"🕉",on:"🔛",oncoming_automobile:"🚘",oncoming_bus:"🚍",oncoming_police_car:"🚔",oncoming_taxi:"🚖",open_file_folder:"📂",open_hands:"👐",open_mouth:"😮",open_umbrella:"☂️",ophiuchus:"⛎",orange_book:"📙",orthodox_cross:"☦️",outbox_tray:"📤",owl:"🦉",ox:"🐂",package:"📦",page_facing_up:"📄",page_with_curl:"📃",pager:"📟",paintbrush:"🖌",palm_tree:"🌴",pancakes:"🥞",panda_face:"🐼",paperclip:"📎",paperclips:"🖇",parasol_on_ground:"⛱",parking:"🅿️",part_alternation_mark:"〽️",partly_sunny:"⛅️",passenger_ship:"🛳",passport_control:"🛂",pause_button:"⏸",peace_symbol:"☮️",peach:"🍑",peanuts:"🥜",pear:"🍐",pen:"🖊",pencil2:"✏️",penguin:"🐧",pensive:"😔",performing_arts:"🎭",persevere:"😣",person_fencing:"🤺",pouting_woman:"🙎",phone:"☎️",pick:"⛏",pig:"🐷",pig2:"🐖",pig_nose:"🐽",pill:"💊",pineapple:"🍍",ping_pong:"🏓",pisces:"♓️",pizza:"🍕",place_of_worship:"🛐",plate_with_cutlery:"🍽",play_or_pause_button:"⏯",point_down:"👇",point_left:"👈",point_right:"👉",point_up:"☝️",point_up_2:"👆",police_car:"🚓",policewoman:"👮♀️",poodle:"🐩",popcorn:"🍿",post_office:"🏣",postal_horn:"📯",postbox:"📮",potable_water:"🚰",potato:"🥔",pouch:"👝",poultry_leg:"🍗",pound:"💷",rage:"😡",pouting_cat:"😾",pouting_man:"🙎♂️",pray:"🙏",prayer_beads:"📿",pregnant_woman:"🤰",previous_track_button:"⏮",prince:"🤴",princess:"👸",printer:"🖨",purple_heart:"💜",purse:"👛",pushpin:"📌",put_litter_in_its_place:"🚮",question:"❓",rabbit:"🐰",rabbit2:"🐇",racehorse:"🐎",racing_car:"🏎",radio:"📻",radio_button:"🔘",radioactive:"☢️",railway_car:"🚃",railway_track:"🛤",rainbow:"🌈",rainbow_flag:"🏳️🌈",raised_back_of_hand:"🤚",raised_hand_with_fingers_splayed:"🖐",raised_hands:"🙌",raising_hand_woman:"🙋",raising_hand_man:"🙋♂️",ram:"🐏",ramen:"🍜",rat:"🐀",record_button:"⏺",recycle:"♻️",red_circle:"🔴",registered:"®️",relaxed:"☺️",relieved:"😌",reminder_ribbon:"🎗",repeat:"🔁",repeat_one:"🔂",rescue_worker_helmet:"⛑",restroom:"🚻",revolving_hearts:"💞",rewind:"⏪",rhinoceros:"🦏",ribbon:"🎀",rice:"🍚",rice_ball:"🍙",rice_cracker:"🍘",rice_scene:"🎑",right_anger_bubble:"🗯",ring:"💍",robot:"🤖",rocket:"🚀",rofl:"🤣",roll_eyes:"🙄",roller_coaster:"🎢",rooster:"🐓",rose:"🌹",rosette:"🏵",rotating_light:"🚨",round_pushpin:"📍",rowing_man:"🚣",rowing_woman:"🚣♀️",rugby_football:"🏉",running_man:"🏃",running_shirt_with_sash:"🎽",running_woman:"🏃♀️",sa:"🈂️",sagittarius:"♐️",sake:"🍶",sandal:"👡",santa:"🎅",satellite:"📡",saxophone:"🎷",school:"🏫",school_satchel:"🎒",scissors:"✂️",scorpion:"🦂",scorpius:"♏️",scream:"😱",scream_cat:"🙀",scroll:"📜",seat:"💺",secret:"㊙️",see_no_evil:"🙈",seedling:"🌱",selfie:"🤳",shallow_pan_of_food:"🥘",shamrock:"☘️",shark:"🦈",shaved_ice:"🍧",sheep:"🐑",shell:"🐚",shield:"🛡",shinto_shrine:"⛩",ship:"🚢",shirt:"👕",shopping:"🛍",shopping_cart:"🛒",shower:"🚿",shrimp:"🦐",signal_strength:"📶",six_pointed_star:"🔯",ski:"🎿",skier:"⛷",skull:"💀",skull_and_crossbones:"☠️",sleeping:"😴",sleeping_bed:"🛌",sleepy:"😪",slightly_frowning_face:"🙁",slightly_smiling_face:"🙂",slot_machine:"🎰",small_airplane:"🛩",small_blue_diamond:"🔹",small_orange_diamond:"🔸",small_red_triangle:"🔺",small_red_triangle_down:"🔻",smile:"😄",smile_cat:"😸",smiley:"😃",smiley_cat:"😺",smiling_imp:"😈",smirk:"😏",smirk_cat:"😼",smoking:"🚬",snail:"🐌",snake:"🐍",sneezing_face:"🤧",snowboarder:"🏂",snowflake:"❄️",snowman:"⛄️",snowman_with_snow:"☃️",sob:"😭",soccer:"⚽️",soon:"🔜",sos:"🆘",sound:"🔉",space_invader:"👾",spades:"♠️",spaghetti:"🍝",sparkle:"❇️",sparkler:"🎇",sparkles:"✨",sparkling_heart:"💖",speak_no_evil:"🙊",speaker:"🔈",speaking_head:"🗣",speech_balloon:"💬",speedboat:"🚤",spider:"🕷",spider_web:"🕸",spiral_calendar:"🗓",spiral_notepad:"🗒",spoon:"🥄",squid:"🦑",stadium:"🏟",star:"⭐️",star2:"🌟",star_and_crescent:"☪️",star_of_david:"✡️",stars:"🌠",station:"🚉",statue_of_liberty:"🗽",steam_locomotive:"🚂",stew:"🍲",stop_button:"⏹",stop_sign:"🛑",stopwatch:"⏱",straight_ruler:"📏",strawberry:"🍓",stuck_out_tongue:"😛",stuck_out_tongue_closed_eyes:"😝",stuck_out_tongue_winking_eye:"😜",studio_microphone:"🎙",stuffed_flatbread:"🥙",sun_behind_large_cloud:"🌥",sun_behind_rain_cloud:"🌦",sun_behind_small_cloud:"🌤",sun_with_face:"🌞",sunflower:"🌻",sunglasses:"😎",sunny:"☀️",sunrise:"🌅",sunrise_over_mountains:"🌄",surfing_man:"🏄",surfing_woman:"🏄♀️",sushi:"🍣",suspension_railway:"🚟",sweat:"😓",sweat_drops:"💦",sweat_smile:"😅",sweet_potato:"🍠",swimming_man:"🏊",swimming_woman:"🏊♀️",symbols:"🔣",synagogue:"🕍",syringe:"💉",taco:"🌮",tada:"🎉",tanabata_tree:"🎋",taurus:"♉️",taxi:"🚕",tea:"🍵",telephone_receiver:"📞",telescope:"🔭",tennis:"🎾",tent:"⛺️",thermometer:"🌡",thinking:"🤔",thought_balloon:"💭",ticket:"🎫",tickets:"🎟",tiger:"🐯",tiger2:"🐅",timer_clock:"⏲",tipping_hand_man:"💁♂️",tired_face:"😫",tm:"™️",toilet:"🚽",tokyo_tower:"🗼",tomato:"🍅",tongue:"👅",top:"🔝",tophat:"🎩",tornado:"🌪",trackball:"🖲",tractor:"🚜",traffic_light:"🚥",train:"🚋",train2:"🚆",tram:"🚊",triangular_flag_on_post:"🚩",triangular_ruler:"📐",trident:"🔱",triumph:"😤",trolleybus:"🚎",trophy:"🏆",tropical_drink:"🍹",tropical_fish:"🐠",truck:"🚚",trumpet:"🎺",tulip:"🌷",tumbler_glass:"🥃",turkey:"🦃",turtle:"🐢",tv:"📺",twisted_rightwards_arrows:"🔀",two_hearts:"💕",two_men_holding_hands:"👬",two_women_holding_hands:"👭",u5272:"🈹",u5408:"🈴",u55b6:"🈺",u6307:"🈯️",u6708:"🈷️",u6709:"🈶",u6e80:"🈵",u7121:"🈚️",u7533:"🈸",u7981:"🈲",u7a7a:"🈳",umbrella:"☔️",unamused:"😒",underage:"🔞",unicorn:"🦄",unlock:"🔓",up:"🆙",upside_down_face:"🙃",v:"✌️",vertical_traffic_light:"🚦",vhs:"📼",vibration_mode:"📳",video_camera:"📹",video_game:"🎮",violin:"🎻",virgo:"♍️",volcano:"🌋",volleyball:"🏐",vs:"🆚",vulcan_salute:"🖖",walking_man:"🚶",walking_woman:"🚶♀️",waning_crescent_moon:"🌘",waning_gibbous_moon:"🌖",warning:"⚠️",wastebasket:"🗑",watch:"⌚️",water_buffalo:"🐃",watermelon:"🍉",wave:"👋",wavy_dash:"〰️",waxing_crescent_moon:"🌒",wc:"🚾",weary:"😩",wedding:"💒",weight_lifting_man:"🏋️",weight_lifting_woman:"🏋️♀️",whale:"🐳",whale2:"🐋",wheel_of_dharma:"☸️",wheelchair:"♿️",white_check_mark:"✅",white_circle:"⚪️",white_flag:"🏳️",white_flower:"💮",white_large_square:"⬜️",white_medium_small_square:"◽️",white_medium_square:"◻️",white_small_square:"▫️",white_square_button:"🔳",wilted_flower:"🥀",wind_chime:"🎐",wind_face:"🌬",wine_glass:"🍷",wink:"😉",wolf:"🐺",woman:"👩",woman_artist:"👩🎨",woman_astronaut:"👩🚀",woman_cartwheeling:"🤸♀️",woman_cook:"👩🍳",woman_facepalming:"🤦♀️",woman_factory_worker:"👩🏭",woman_farmer:"👩🌾",woman_firefighter:"👩🚒",woman_health_worker:"👩⚕️",woman_judge:"👩⚖️",woman_juggling:"🤹♀️",woman_mechanic:"👩🔧",woman_office_worker:"👩💼",woman_pilot:"👩✈️",woman_playing_handball:"🤾♀️",woman_playing_water_polo:"🤽♀️",woman_scientist:"👩🔬",woman_shrugging:"🤷♀️",woman_singer:"👩🎤",woman_student:"👩🎓",woman_teacher:"👩🏫",woman_technologist:"👩💻",woman_with_turban:"👳♀️",womans_clothes:"👚",womans_hat:"👒",women_wrestling:"🤼♀️",womens:"🚺",world_map:"🗺",worried:"😟",wrench:"🔧",writing_hand:"✍️",x:"❌",yellow_heart:"💛",yen:"💴",yin_yang:"☯️",yum:"😋",zap:"⚡️",zipper_mouth_face:"🤐",zzz:"💤",octocat:' ',showdown:"S "},x.Converter=function(e){"use strict";var r,t,n={},i=[],l=[],o={},a=h,s={parsed:{},raw:"",format:""};for(r in e=e||{},p)p.hasOwnProperty(r)&&(n[r]=p[r]);if("object"!=typeof e)throw Error("Converter expects the passed parameter to be an object, but "+typeof e+" was passed instead.");for(t in e)e.hasOwnProperty(t)&&(n[t]=e[t]);function c(e,r){if(r=r||null,x.helper.isString(e)){if(r=e=x.helper.stdExtName(e),x.extensions[e]){console.warn("DEPRECATION WARNING: "+e+" is an old extension that uses a deprecated loading method.Please inform the developer that the extension should be updated!");var t=x.extensions[e],a=e;if("function"==typeof t&&(t=t(new x.Converter)),x.helper.isArray(t)||(t=[t]),!(a=g(t,a)).valid)throw Error(a.error);for(var n=0;n [ \t]+,">¨NBSP;<"),!r){if(!window||!window.document)throw new Error("HTMLParser is undefined. If in a webworker or nodejs environment, you need to provide a WHATWG DOM and HTML such as JSDOM");r=window.document}for(var r=r.createElement("div"),t=(r.innerHTML=e,{preList:function(e){for(var r=e.querySelectorAll("pre"),t=[],a=0;a'}else t.push(r[a].innerHTML),r[a].innerHTML="",r[a].setAttribute("prenum",a.toString());return t}(r)}),a=(!function e(r){for(var t=0;t? ?(['"].*['"])?\)$/m))a="";else if(!a){if(a="#"+(t=t||r.toLowerCase().replace(/ ?\n/g," ")),x.helper.isUndefined(l.gUrls[t]))return e;a=l.gUrls[t],x.helper.isUndefined(l.gTitles[t])||(o=l.gTitles[t])}return e='"+r+" "}return e=(e=(e=(e=(e=l.converter._dispatch("anchors.before",e,i,l)).replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g,r)).replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,r)).replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,r)).replace(/\[([^\[\]]+)]()()()()()/g,r),i.ghMentions&&(e=e.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gim,function(e,r,t,a,n){if("\\"===t)return r+a;if(!x.helper.isString(i.ghMentionsLink))throw new Error("ghMentionsLink option must be a string");t="";return r+'"+a+" "})),e=l.converter._dispatch("anchors.after",e,i,l)});var i=/([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi,l=/([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi,c=/()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi,m=/(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gim,f=/<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi;x.subParser("autoLinks",function(e,r,t){"use strict";return e=(e=(e=t.converter._dispatch("autoLinks.before",e,r,t)).replace(c,s(r))).replace(f,o(r,t)),e=t.converter._dispatch("autoLinks.after",e,r,t)}),x.subParser("simplifiedAutoLinks",function(e,r,t){"use strict";return r.simplifiedAutoLink?(e=t.converter._dispatch("simplifiedAutoLinks.before",e,r,t),e=(e=r.excludeTrailingPunctuationFromURLs?e.replace(l,s(r)):e.replace(i,s(r))).replace(m,o(r,t)),t.converter._dispatch("simplifiedAutoLinks.after",e,r,t)):e}),x.subParser("blockGamut",function(e,r,t){"use strict";return e=t.converter._dispatch("blockGamut.before",e,r,t),e=x.subParser("blockQuotes")(e,r,t),e=x.subParser("headers")(e,r,t),e=x.subParser("horizontalRule")(e,r,t),e=x.subParser("lists")(e,r,t),e=x.subParser("codeBlocks")(e,r,t),e=x.subParser("tables")(e,r,t),e=x.subParser("hashHTMLBlocks")(e,r,t),e=x.subParser("paragraphs")(e,r,t),e=t.converter._dispatch("blockGamut.after",e,r,t)}),x.subParser("blockQuotes",function(e,r,t){"use strict";e=t.converter._dispatch("blockQuotes.before",e,r,t);var a=/(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm;return r.splitAdjacentBlockquotes&&(a=/^ {0,3}>[\s\S]*?(?:\n\n)/gm),e=(e+="\n\n").replace(a,function(e){return e=(e=(e=e.replace(/^[ \t]*>[ \t]?/gm,"")).replace(/¨0/g,"")).replace(/^[ \t]+$/gm,""),e=x.subParser("githubCodeBlocks")(e,r,t),e=(e=(e=x.subParser("blockGamut")(e,r,t)).replace(/(^|\n)/g,"$1 ")).replace(/(\s*[^\r]+?<\/pre>)/gm,function(e,r){return r.replace(/^ /gm,"¨0").replace(/¨0/g,"")}),x.subParser("hashBlock")("\n"+e+"\n ",r,t)}),e=t.converter._dispatch("blockQuotes.after",e,r,t)}),x.subParser("codeBlocks",function(e,n,s){"use strict";e=s.converter._dispatch("codeBlocks.before",e,n,s);return e=(e=(e+="¨0").replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g,function(e,r,t){var a="\n",r=x.subParser("outdent")(r,n,s);return r=x.subParser("encodeCode")(r,n,s),r=""+(r=(r=(r=x.subParser("detab")(r,n,s)).replace(/^\n+/g,"")).replace(/\n+$/g,""))+(a=n.omitExtraWLInCodeBlocks?"":a)+" ",x.subParser("hashBlock")(r,n,s)+t})).replace(/¨0/,""),e=s.converter._dispatch("codeBlocks.after",e,n,s)}),x.subParser("codeSpans",function(e,n,s){"use strict";return e=(e=void 0===(e=s.converter._dispatch("codeSpans.before",e,n,s))?"":e).replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,function(e,r,t,a){return a=(a=a.replace(/^([ \t]*)/g,"")).replace(/[ \t]*$/g,""),a=r+""+(a=x.subParser("encodeCode")(a,n,s))+"",a=x.subParser("hashHTMLSpans")(a,n,s)}),e=s.converter._dispatch("codeSpans.after",e,n,s)}),x.subParser("completeHTMLDocument",function(e,r,t){"use strict";if(!r.completeHTMLDocument)return e;e=t.converter._dispatch("completeHTMLDocument.before",e,r,t);var a,n="html",s="\n",o="",i=' \n',l="",c="";for(a in void 0!==t.metadata.parsed.doctype&&(s="\n","html"!==(n=t.metadata.parsed.doctype.toString().toLowerCase())&&"html5"!==n||(i=' ')),t.metadata.parsed)if(t.metadata.parsed.hasOwnProperty(a))switch(a.toLowerCase()){case"doctype":break;case"title":o=""+t.metadata.parsed.title+" \n";break;case"charset":i="html"===n||"html5"===n?' \n':' \n';break;case"language":case"lang":l=' lang="'+t.metadata.parsed[a]+'"',c+=' \n';break;default:c+=' \n'}return e=s+"\n\n"+o+i+c+"\n\n"+e.trim()+"\n\n",e=t.converter._dispatch("completeHTMLDocument.after",e,r,t)}),x.subParser("detab",function(e,r,t){"use strict";return e=(e=(e=(e=(e=(e=t.converter._dispatch("detab.before",e,r,t)).replace(/\t(?=\t)/g," ")).replace(/\t/g,"¨A¨B")).replace(/¨B(.+?)¨A/g,function(e,r){for(var t=r,a=4-t.length%4,n=0;n/g,">"),e=t.converter._dispatch("encodeAmpsAndAngles.after",e,r,t)}),x.subParser("encodeBackslashEscapes",function(e,r,t){"use strict";return e=(e=(e=t.converter._dispatch("encodeBackslashEscapes.before",e,r,t)).replace(/\\(\\)/g,x.helper.escapeCharactersCallback)).replace(/\\([`*_{}\[\]()>#+.!~=|:-])/g,x.helper.escapeCharactersCallback),e=t.converter._dispatch("encodeBackslashEscapes.after",e,r,t)}),x.subParser("encodeCode",function(e,r,t){"use strict";return e=(e=t.converter._dispatch("encodeCode.before",e,r,t)).replace(/&/g,"&").replace(//g,">").replace(/([*_{}\[\]\\=~-])/g,x.helper.escapeCharactersCallback),e=t.converter._dispatch("encodeCode.after",e,r,t)}),x.subParser("escapeSpecialCharsWithinTagAttributes",function(e,r,t){"use strict";return e=(e=(e=t.converter._dispatch("escapeSpecialCharsWithinTagAttributes.before",e,r,t)).replace(/<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi,function(e){return e.replace(/(.)<\/?code>(?=.)/g,"$1`").replace(/([\\`*_~=|])/g,x.helper.escapeCharactersCallback)})).replace(/-]|-[^>])(?:[^-]|-[^-])*)--)>/gi,function(e){return e.replace(/([\\`*_~=|])/g,x.helper.escapeCharactersCallback)}),e=t.converter._dispatch("escapeSpecialCharsWithinTagAttributes.after",e,r,t)}),x.subParser("githubCodeBlocks",function(e,s,o){"use strict";return s.ghCodeBlocks?(e=o.converter._dispatch("githubCodeBlocks.before",e,s,o),e=(e=(e+="¨0").replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g,function(e,r,t,a){var n=s.omitExtraWLInCodeBlocks?"":"\n";return a=x.subParser("encodeCode")(a,s,o),a=""+(a=(a=(a=x.subParser("detab")(a,s,o)).replace(/^\n+/g,"")).replace(/\n+$/g,""))+n+" ",a=x.subParser("hashBlock")(a,s,o),"\n\n¨G"+(o.ghCodeBlocks.push({text:e,codeblock:a})-1)+"G\n\n"})).replace(/¨0/,""),o.converter._dispatch("githubCodeBlocks.after",e,s,o)):e}),x.subParser("hashBlock",function(e,r,t){"use strict";return e=(e=t.converter._dispatch("hashBlock.before",e,r,t)).replace(/(^\n+|\n+$)/g,""),e="\n\n¨K"+(t.gHtmlBlocks.push(e)-1)+"K\n\n",e=t.converter._dispatch("hashBlock.after",e,r,t)}),x.subParser("hashCodeTags",function(e,n,s){"use strict";e=s.converter._dispatch("hashCodeTags.before",e,n,s);return e=x.helper.replaceRecursiveRegExp(e,function(e,r,t,a){t=t+x.subParser("encodeCode")(r,n,s)+a;return"¨C"+(s.gHtmlSpans.push(t)-1)+"C"},"]*>","","gim"),e=s.converter._dispatch("hashCodeTags.after",e,n,s)}),x.subParser("hashElement",function(e,r,t){"use strict";return function(e,r){return r=(r=(r=r.replace(/\n\n/g,"\n")).replace(/^\n/,"")).replace(/\n+$/g,""),r="\n\n¨K"+(t.gHtmlBlocks.push(r)-1)+"K\n\n"}}),x.subParser("hashHTMLBlocks",function(e,r,n){"use strict";e=n.converter._dispatch("hashHTMLBlocks.before",e,r,n);function t(e,r,t,a){return-1!==t.search(/\bmarkdown\b/)&&(e=t+n.converter.makeHtml(r)+a),"\n\n¨K"+(n.gHtmlBlocks.push(e)-1)+"K\n\n"}var a=["pre","div","h1","h2","h3","h4","h5","h6","blockquote","table","dl","ol","ul","script","noscript","form","fieldset","iframe","math","style","section","header","footer","nav","article","aside","address","audio","canvas","figure","hgroup","output","video","p"];r.backslashEscapesHTMLTags&&(e=e.replace(/\\<(\/?[^>]+?)>/g,function(e,r){return"<"+r+">"}));for(var s=0;s ]*>)","im"),i="<"+a[s]+"\\b[^>]*>",l=""+a[s]+">";-1!==(c=x.helper.regexIndexOf(e,o));){var c=x.helper.splitAtIndex(e,c),u=x.helper.replaceRecursiveRegExp(c[1],t,i,l,"im");if(u===c[1])break;e=c[0].concat(u)}return e=e.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,x.subParser("hashElement")(e,r,n)),e=(e=x.helper.replaceRecursiveRegExp(e,function(e){return"\n\n¨K"+(n.gHtmlBlocks.push(e)-1)+"K\n\n"},"^ {0,3}\x3c!--","--\x3e","gm")).replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,x.subParser("hashElement")(e,r,n)),e=n.converter._dispatch("hashHTMLBlocks.after",e,r,n)}),x.subParser("hashHTMLSpans",function(e,r,t){"use strict";function a(e){return"¨C"+(t.gHtmlSpans.push(e)-1)+"C"}return e=(e=(e=(e=(e=t.converter._dispatch("hashHTMLSpans.before",e,r,t)).replace(/<[^>]+?\/>/gi,a)).replace(/<([^>]+?)>[\s\S]*?<\/\1>/g,a)).replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g,a)).replace(/<[^>]+?>/gi,a),e=t.converter._dispatch("hashHTMLSpans.after",e,r,t)}),x.subParser("unhashHTMLSpans",function(e,r,t){"use strict";e=t.converter._dispatch("unhashHTMLSpans.before",e,r,t);for(var a=0;a]*>\\s*]*>","^ {0,3}\\s* ","gim"),e=s.converter._dispatch("hashPreCodeTags.after",e,n,s)}),x.subParser("headers",function(e,n,s){"use strict";e=s.converter._dispatch("headers.before",e,n,s);var o=isNaN(parseInt(n.headerLevelStart))?1:parseInt(n.headerLevelStart),r=n.smoothLivePreview?/^(.+)[ \t]*\n={2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n=+[ \t]*\n+/gm,t=n.smoothLivePreview?/^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm:/^(.+)[ \t]*\n-+[ \t]*\n+/gm,r=(e=(e=e.replace(r,function(e,r){var t=x.subParser("spanGamut")(r,n,s),r=n.noHeaderId?"":' id="'+i(r)+'"',r=""+t+" ";return x.subParser("hashBlock")(r,n,s)})).replace(t,function(e,r){var t=x.subParser("spanGamut")(r,n,s),r=n.noHeaderId?"":' id="'+i(r)+'"',a=o+1,r=""+t+" ";return x.subParser("hashBlock")(r,n,s)}),n.requireSpaceBeforeHeadingText?/^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm:/^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm);function i(e){var r=e=n.customizedHeaderId&&(r=e.match(/\{([^{]+?)}\s*$/))&&r[1]?r[1]:e,e=x.helper.isString(n.prefixHeaderId)?n.prefixHeaderId:!0===n.prefixHeaderId?"section-":"";return n.rawPrefixHeaderId||(r=e+r),r=(n.ghCompatibleHeaderId?r.replace(/ /g,"-").replace(/&/g,"").replace(/¨T/g,"").replace(/¨D/g,"").replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g,""):n.rawHeaderId?r.replace(/ /g,"-").replace(/&/g,"&").replace(/¨T/g,"¨").replace(/¨D/g,"$").replace(/["']/g,"-"):r.replace(/[^\w]/g,"")).toLowerCase(),n.rawPrefixHeaderId&&(r=e+r),s.hashLinkCounts[r]?r=r+"-"+s.hashLinkCounts[r]++:s.hashLinkCounts[r]=1,r}return e=e.replace(r,function(e,r,t){var a=t,a=(n.customizedHeaderId&&(a=t.replace(/\s?\{([^{]+?)}\s*$/,"")),x.subParser("spanGamut")(a,n,s)),t=n.noHeaderId?"":' id="'+i(t)+'"',r=o-1+r.length,t=""+a+" ";return x.subParser("hashBlock")(t,n,s)}),e=s.converter._dispatch("headers.after",e,n,s)}),x.subParser("horizontalRule",function(e,r,t){"use strict";e=t.converter._dispatch("horizontalRule.before",e,r,t);var a=x.subParser("hashBlock")(" ",r,t);return e=(e=(e=e.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm,a)).replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm,a)).replace(/^ {0,2}( ?_){3,}[ \t]*$/gm,a),e=t.converter._dispatch("horizontalRule.after",e,r,t)}),x.subParser("images",function(e,r,d){"use strict";function l(e,r,t,a,n,s,o,i){var l=d.gUrls,c=d.gTitles,u=d.gDimensions;if(t=t.toLowerCase(),i=i||"",-1? ?(['"].*['"])?\)$/m))a="";else if(""===a||null===a){if(a="#"+(t=""!==t&&null!==t?t:r.toLowerCase().replace(/ ?\n/g," ")),x.helper.isUndefined(l[t]))return e;a=l[t],x.helper.isUndefined(c[t])||(i=c[t]),x.helper.isUndefined(u[t])||(n=u[t].width,s=u[t].height)}r=r.replace(/"/g,""").replace(x.helper.regexes.asteriskDashAndColon,x.helper.escapeCharactersCallback);e=' "}return e=(e=(e=(e=(e=(e=d.converter._dispatch("images.before",e,r,d)).replace(/!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g,l)).replace(/!\[([^\]]*?)][ \t]*()\([ \t]?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,function(e,r,t,a,n,s,o,i){return l(e,r,t,a=a.replace(/\s/g,""),n,s,0,i)})).replace(/!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g,l)).replace(/!\[([^\]]*?)][ \t]*()\([ \t]?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,l)).replace(/!\[([^\[\]]+)]()()()()()/g,l),e=d.converter._dispatch("images.after",e,r,d)}),x.subParser("italicsAndBold",function(e,r,t){"use strict";return e=t.converter._dispatch("italicsAndBold.before",e,r,t),e=r.literalMidWordUnderscores?(e=(e=e.replace(/\b___(\S[\s\S]*?)___\b/g,function(e,r){return""+r+" "})).replace(/\b__(\S[\s\S]*?)__\b/g,function(e,r){return""+r+" "})).replace(/\b_(\S[\s\S]*?)_\b/g,function(e,r){return""+r+" "}):(e=(e=e.replace(/___(\S[\s\S]*?)___/g,function(e,r){return/\S$/.test(r)?""+r+" ":e})).replace(/__(\S[\s\S]*?)__/g,function(e,r){return/\S$/.test(r)?""+r+" ":e})).replace(/_([^\s_][\s\S]*?)_/g,function(e,r){return/\S$/.test(r)?""+r+" ":e}),e=r.literalMidWordAsterisks?(e=(e=e.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g,function(e,r,t){return r+""+t+" "})).replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g,function(e,r,t){return r+""+t+" "})).replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g,function(e,r,t){return r+""+t+" "}):(e=(e=e.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g,function(e,r){return/\S$/.test(r)?""+r+" ":e})).replace(/\*\*(\S[\s\S]*?)\*\*/g,function(e,r){return/\S$/.test(r)?""+r+" ":e})).replace(/\*([^\s*][\s\S]*?)\*/g,function(e,r){return/\S$/.test(r)?""+r+" ":e}),e=t.converter._dispatch("italicsAndBold.after",e,r,t)}),x.subParser("lists",function(e,d,c){"use strict";function p(e,r){c.gListLevel++,e=e.replace(/\n{2,}$/,"\n");var t=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm,l=/\n[ \t]*\n(?!¨0)/.test(e+="¨0");return d.disableForced4SpacesIndentedSublists&&(t=/(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm),e=(e=e.replace(t,function(e,r,t,a,n,s,o){o=o&&""!==o.trim();var n=x.subParser("outdent")(n,d,c),i="";return s&&d.tasklists&&(i=' class="task-list-item" style="list-style-type: none;"',n=n.replace(/^[ \t]*\[(x|X| )?]/m,function(){var e=' "})),n=n.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g,function(e){return"¨A"+e}),n=""+(n=(n=r||-1\n"})).replace(/¨0/g,""),c.gListLevel--,e=r?e.replace(/\s+$/,""):e}function h(e,r){if("ol"===r){r=e.match(/^ *(\d+)\./);if(r&&"1"!==r[1])return' start="'+r[1]+'"'}return""}function n(n,s,o){var e,i=d.disableForced4SpacesIndentedSublists?/^ ?\d+\.[ \t]/gm:/^ {0,3}\d+\.[ \t]/gm,l=d.disableForced4SpacesIndentedSublists?/^ ?[*+-][ \t]/gm:/^ {0,3}[*+-][ \t]/gm,c="ul"===s?i:l,u="";return-1!==n.search(c)?function e(r){var t=r.search(c),a=h(n,s);-1!==t?(u+="\n\n<"+s+a+">\n"+p(r.slice(0,t),!!o)+""+s+">\n",c="ul"===(s="ul"===s?"ol":"ul")?i:l,e(r.slice(t))):u+="\n\n<"+s+a+">\n"+p(r,!!o)+""+s+">\n"}(n):(e=h(n,s),u="\n\n<"+s+e+">\n"+p(n,!!o)+""+s+">\n"),u}return e=c.converter._dispatch("lists.before",e,d,c),e+="¨0",e=(e=c.gListLevel?e.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,function(e,r,t){return n(r,-1"),i+="",n.push(i))}for(s=n.length,o=0;o]*>\s*]*>/.test(c)&&(u=!0)}n[o]=c}return e=(e=(e=n.join("\n")).replace(/^\n+/g,"")).replace(/\n+$/g,""),t.converter._dispatch("paragraphs.after",e,r,t)}),x.subParser("runExtension",function(e,r,t,a){"use strict";return e.filter?r=e.filter(r,a.converter,t):e.regex&&((a=e.regex)instanceof RegExp||(a=new RegExp(a,"g")),r=r.replace(a,e.replace)),r}),x.subParser("spanGamut",function(e,r,t){"use strict";return e=t.converter._dispatch("spanGamut.before",e,r,t),e=x.subParser("codeSpans")(e,r,t),e=x.subParser("escapeSpecialCharsWithinTagAttributes")(e,r,t),e=x.subParser("encodeBackslashEscapes")(e,r,t),e=x.subParser("images")(e,r,t),e=x.subParser("anchors")(e,r,t),e=x.subParser("autoLinks")(e,r,t),e=x.subParser("simplifiedAutoLinks")(e,r,t),e=x.subParser("emoji")(e,r,t),e=x.subParser("underline")(e,r,t),e=x.subParser("italicsAndBold")(e,r,t),e=x.subParser("strikethrough")(e,r,t),e=x.subParser("ellipsis")(e,r,t),e=x.subParser("hashHTMLSpans")(e,r,t),e=x.subParser("encodeAmpsAndAngles")(e,r,t),r.simpleLineBreaks?/\n\n¨K/.test(e)||(e=e.replace(/\n+/g," \n")):e=e.replace(/ +\n/g," \n"),e=t.converter._dispatch("spanGamut.after",e,r,t)}),x.subParser("strikethrough",function(e,t,a){"use strict";return t.strikethrough&&(e=(e=a.converter._dispatch("strikethrough.before",e,t,a)).replace(/(?:~){2}([\s\S]+?)(?:~){2}/g,function(e,r){return r=r,""+(r=t.simplifiedAutoLink?x.subParser("simplifiedAutoLinks")(r,t,a):r)+""}),e=a.converter._dispatch("strikethrough.after",e,t,a)),e}),x.subParser("stripLinkDefinitions",function(i,l,c){"use strict";function e(e,r,t,a,n,s,o){return r=r.toLowerCase(),i.toLowerCase().split(r).length-1<2?e:(t.match(/^data:.+?\/.+?;base64,/)?c.gUrls[r]=t.replace(/\s/g,""):c.gUrls[r]=x.subParser("encodeAmpsAndAngles")(t,l,c),s?s+o:(o&&(c.gTitles[r]=o.replace(/"|'/g,""")),l.parseImgDimensions&&a&&n&&(c.gDimensions[r]={width:a,height:n}),""))}return i=(i=(i=(i+="¨0").replace(/^ {0,3}\[([^\]]+)]:[ \t]*\n?[ \t]*(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n\n|(?=¨0)|(?=\n\[))/gm,e)).replace(/^ {0,3}\[([^\]]+)]:[ \t]*\n?[ \t]*([^>\s]+)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm,e)).replace(/¨0/,"")}),x.subParser("tables",function(e,y,P){"use strict";if(!y.tables)return e;function r(e){for(var r=e.split("\n"),t=0;t"+(n=x.subParser("spanGamut")(n,y,P))+"\n"));for(t=0;t"+x.subParser("spanGamut")(i,y,P)+"\n"));h.push(_)}for(var m=d,f=h,b="\n\n\n",w=m.length,k=0;k\n \n\n",k=0;k\n";for(var v=0;v\n"}return b+=" \n
\n"}return e=(e=(e=(e=P.converter._dispatch("tables.before",e,y,P)).replace(/\\(\|)/g,x.helper.escapeCharactersCallback)).replace(/^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm,r)).replace(/^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm,r),e=P.converter._dispatch("tables.after",e,y,P)}),x.subParser("underline",function(e,r,t){"use strict";return r.underline?(e=t.converter._dispatch("underline.before",e,r,t),e=(e=r.literalMidWordUnderscores?(e=e.replace(/\b___(\S[\s\S]*?)___\b/g,function(e,r){return""+r+" "})).replace(/\b__(\S[\s\S]*?)__\b/g,function(e,r){return""+r+" "}):(e=e.replace(/___(\S[\s\S]*?)___/g,function(e,r){return/\S$/.test(r)?""+r+" ":e})).replace(/__(\S[\s\S]*?)__/g,function(e,r){return/\S$/.test(r)?""+r+" ":e})).replace(/(_)/g,x.helper.escapeCharactersCallback),t.converter._dispatch("underline.after",e,r,t)):e}),x.subParser("unescapeSpecialChars",function(e,r,t){"use strict";return e=(e=t.converter._dispatch("unescapeSpecialChars.before",e,r,t)).replace(/¨E(\d+)E/g,function(e,r){r=parseInt(r);return String.fromCharCode(r)}),e=t.converter._dispatch("unescapeSpecialChars.after",e,r,t)}),x.subParser("makeMarkdown.blockquote",function(e,r){"use strict";var t="";if(e.hasChildNodes())for(var a=e.childNodes,n=a.length,s=0;s ")}),x.subParser("makeMarkdown.codeBlock",function(e,r){"use strict";var t=e.getAttribute("language"),e=e.getAttribute("precodenum");return"```"+t+"\n"+r.preList[e]+"\n```"}),x.subParser("makeMarkdown.codeSpan",function(e){"use strict";return"`"+e.innerHTML+"`"}),x.subParser("makeMarkdown.emphasis",function(e,r){"use strict";var t="";if(e.hasChildNodes()){t+="*";for(var a=e.childNodes,n=a.length,s=0;s",e.hasAttribute("width")&&e.hasAttribute("height")&&(r+=" ="+e.getAttribute("width")+"x"+e.getAttribute("height")),e.hasAttribute("title")&&(r+=' "'+e.getAttribute("title")+'"'),r+=")"),r}),x.subParser("makeMarkdown.links",function(e,r){"use strict";var t="";if(e.hasChildNodes()&&e.hasAttribute("href")){for(var a=e.childNodes,n=a.length,t="[",s=0;s"),e.hasAttribute("title")&&(t+=' "'+e.getAttribute("title")+'"'),t+=")"}return t}),x.subParser("makeMarkdown.list",function(e,r,t){"use strict";var a="";if(!e.hasChildNodes())return"";for(var n=e.childNodes,s=n.length,o=e.getAttribute("start")||1,i=0;i"+r.preList[e]+""}),x.subParser("makeMarkdown.strikethrough",function(e,r){"use strict";var t="";if(e.hasChildNodes()){t+="~~";for(var a=e.childNodes,n=a.length,s=0;str>th"),s=e.querySelectorAll("tbody>tr"),o=0;o/g,"\\$1>")).replace(/^#/gm,"\\#")).replace(/^(\s*)([-=]{3,})(\s*)$/,"$1\\$2$3")).replace(/^( {0,3}\d+)\./gm,"$1\\.")).replace(/^( {0,3})([+-])/gm,"$1\\$2")).replace(/]([\s]*)\(/g,"\\]$1\\(")).replace(/^ {0,3}\[([\S \t]*?)]:/gm,"\\[$1]:")});"function"==typeof define&&define.amd?define(function(){"use strict";return x}):"undefined"!=typeof module&&module.exports?module.exports=x:this.showdown=x}.call(this);
-//# sourceMappingURL=showdown.min.js.map
diff --git a/src/frontend/wwwroot/task/employee.html b/src/frontend/wwwroot/task/employee.html
deleted file mode 100644
index 96ed0e495..000000000
--- a/src/frontend/wwwroot/task/employee.html
+++ /dev/null
@@ -1,136 +0,0 @@
-
-
-
-
- Task
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cancel
-
-
-
-
-
-
-
-
-
-
- Status:
- In Progress
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 0 /1000
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/frontend/wwwroot/task/task.css b/src/frontend/wwwroot/task/task.css
deleted file mode 100644
index ed365aaeb..000000000
--- a/src/frontend/wwwroot/task/task.css
+++ /dev/null
@@ -1,272 +0,0 @@
-@import "../app.css";
-@import "../assets/bulma-switch.css";
-
-.task-stats {
- min-height: 70px;
-}
-
-.section {
- min-height: 100%;
-}
-
-.task-asside {
- min-height: 100vh;
- max-width: 500px;
-}
-
-.task-asside.is-audit {
- max-width: 700px;
-}
-
-.task-asside .task-menu {
- margin: 3rem 1rem;
-}
-
-
-.task-asside .title {
- font-size: 1.25rem;
- height: 30px;
- display: flex;
- align-items: center;
-}
-
-.task-details {
- width: 100%;
- padding: 2rem;
-}
-.colChatSec {
- width: 55%;
-}
-/*Notification message styles start*/
-/* Ensures block-level elements (like ,
, etc.) wrap inside the message */
-.notification p,
-.notification pre {
- margin: 0;
- word-wrap: break-word;
- white-space: pre-wrap; /* Allow preformatted text to wrap */
-}
-.message-content {
- max-width: 100%;
- overflow: hidden;
- word-break: break-word;
- line-height: 1.4;
-}
-/* Optional: Add word-breaking for URLs */
-.notification a {
- word-wrap: break-word;
- word-break: break-word;
- text-decoration: underline;
-}
-/*Notification message styles end*/
-
-.task-progress {
- height: 40vh;
- overflow-y: auto;
- background-color: white;
- border-radius: var(--bulma-radius);
-}
-
-@media (min-height: 1200px) {
- .task-progress {
- height: 50vh;
- }
-}
-
-@media (min-height: 1400px) {
- .task-progress {
- height: 60vh;
- }
-}
-
-.task-progress .notification {
- padding: 0.5rem 1rem;
- display: block;
- max-width: 100%;
- word-wrap: break-word;
- box-sizing: border-box;
- overflow-wrap: break-word;
-}
-
-.menu-list .menu-item,
-.menu-list a,
-.menu-list button {
- background-color: transparent;
-}
-
-.menu-list ul.menu-stages {
- border-inline-start: 3px solid var(--bulma-border);
- padding-inline-start: 0;
-}
-
-.menu-list ul.menu-stages li {
- margin-left: calc(-1.4rem - 5px);
-}
-
-.menu-list a.menu-stage {
- display: flex;
- align-items: center;
- position: relative;
- padding: 0.5em 0 0.5rem 0.75em;
- width: calc(100% + 1.4rem - 5px);
-}
-
-.menu-list a.menu-stage > i {
- font-size: 1.4rem;
- margin-top: 3px;
- border-radius: 50%;
- background-color: rgb(247, 249, 251);
- padding: 5px;
-}
-
-.menu-list a.menu-stage span {
- flex: 1;
- word-break: break-word; /*this for stages span alignment*/
-}
-
-.menu-list a.menu-stage.rejected span {
- text-decoration: line-through;
- opacity: 0.5;
-}
-
-.menu-list a.menu-stage.action_requested span {
- font-weight: 500;
-}
-
-.menu-list a.menu-stage div {
- display: flex;
- align-items: center;
-}
-
-.menu-stage-actions i {
- font-size: 1.4rem;
-}
-
-.business-animation {
- position: relative;
- border-radius: var(--bulma-radius-large);
-}
-
-#taskLoader {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- position: absolute;
- inset: 0;
- color: black;
- background-color: rgb(247, 249, 251);
- z-index: 1000;
- font-weight: 500;
-}
-
-#taskLoader span::before {
- content: "Getting task plan...";
- animation: taskLoaderAnimation infinite 3s linear;
-}
-
-#taskLoader.is-hidden {
- display: none;
-}
-
-@keyframes taskLoaderAnimation {
- 0% {
- content: "Getting task plan...";
- }
-
- 50% {
- content: "Contacting agents...";
- }
-
- 75% {
- content: "Loading conversations...";
- }
-}
-
-#taskLoader i {
- font-size: 3rem;
-}
-
-.task-stage-divider {
- text-align: center;
- margin: 1rem 0;
- font-size: 0.85rem;
- font-weight: 500;
- border: 1px solid rgb(71, 80, 235);
- border-left-width: 0;
- border-right-width: 0;
- border-bottom-width: 0;
-}
-
-.task-stage-divider legend {
- color: rgb(71, 80, 235);
- -webkit-padding-start: 1rem;
- -webkit-padding-end: 1rem;
- background: transparent;
-}
-
-.text-input-container {
- position: relative;
- border: 1px solid #ccc;
- border-radius: 8px;
- background-color: white;
-}
-
-textarea {
- width: 98%;
- padding: 16px 0px 0px 0px;
- border: none;
- border-radius: 8px 8px 0 0;
- font-size: 16px;
- line-height: 1.5;
- resize: none;
- outline: none;
- overflow: hidden;
- margin: 0 10px;
- align-items: center;
- background-color: white;
-}
-
-.star-icon {
- margin-right: 10px;
- cursor: pointer;
-}
-
-.char-count {
- font-size: 14px;
- color: #888;
-}
-
-.middle-bar {
- display: flex;
- justify-content: space-between;
- align-items: left;
- padding: 0px 5px;
-}
-
-.bottom-bar {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 3px 10px;
- border-top: none;
- border-bottom: 4px solid #0f6cbd;
-}
-
-.send-button {
- border: none;
- background: none;
- font-size: 18px;
- cursor: pointer;
- color: #007bff;
- padding: 4px;
- outline: none;
-}
-
-.send-button:hover {
- color: #0056b3;
-}
-
-.menu.task-menu {
- position: sticky;
- top: 0;
-}
\ No newline at end of file
diff --git a/src/frontend/wwwroot/task/task.js b/src/frontend/wwwroot/task/task.js
deleted file mode 100644
index 5766d9001..000000000
--- a/src/frontend/wwwroot/task/task.js
+++ /dev/null
@@ -1,916 +0,0 @@
-(() => {
- const markdownConverter = new showdown.Converter();
- const apiEndpoint = getStoredData("apiEndpoint");
- const taskStore = JSON.parse(getStoredData("task"));
- const taskName = document.getElementById("taskName");
- const taskStatusTag = document.getElementById("taskStatusTag");
- const taskStagesMenu = document.getElementById("taskStagesMenu");
- const taskPauseButton = document.getElementById("taskPauseButton");
- const taskAgentsButton = document.getElementById("taskAgentsButton");
- const taskWokFlowButton = document.getElementById("taskWokFlowButton");
- const taskMessageTextarea = document.getElementById("taskMessageTextarea");
- const taskMessageAddButton = document.getElementById("taskMessageAddButton");
- const taskMessages = document.getElementById("taskMessages");
- const taskDetailsAgents = document.getElementById("taskDetailsAgents");
- const taskProgress = document.getElementById("taskProgress");
- const taskProgressPercentage = document.getElementById(
- "taskProgressPercentage"
- );
- const taskProgressBar = document.getElementById("taskProgressBar");
- const taskLoader = document.getElementById("taskLoader");
- const taskAgentsHumans = document.getElementById("taskAgentsHumans");
- const taskStatusDetails = document.getElementById("taskStatusDetails");
- const taskCancelButton = document.getElementById("taskCancelButton");
- const startTaskButtonContainer = document.querySelector(".send-button");
- const startTaskButtonImg = startTaskButtonContainer
- ? startTaskButtonContainer.querySelector("img")
- : null;
-
- const textInputContainer = document.getElementsByClassName("text-input-container");
- const notyf = new Notyf({
- position: { x: "right", y: "top" },
- ripple: false,
- duration: 3000,
- types: [
- {
- type: "info",
- background: "rgb(71, 80, 235)",
- icon: ' ',
- },
- ],
- });
-
- const updateButtonImage = () => {
- if (startTaskButtonImg) {
- const newTaskPrompt = document.getElementById("taskMessageTextarea");
- if (newTaskPrompt && newTaskPrompt.value.trim() === "") {
- startTaskButtonImg.src = "../assets/images/air-button.svg";
- startTaskButton.disabled = true;
- } else {
- startTaskButtonImg.src = "/assets/Send.svg";
- startTaskButtonImg.style.width = "16px";
- startTaskButtonImg.style.height = "16px";
- startTaskButton.disabled = false;
- }
- }
- };
-
- let taskSessionId = null;
- let taskLastStageId = null;
- let taskLastAction = null;
- let taskAgents = [];
- let taskAgentsVsHumans = [];
-
- const agentToIcon = (agentName) => {
- let agentIcon = "";
-
- switch (agentName) {
- case "Marketing_Agent":
- agentIcon = "unknown";
- break;
- case "Hr_Agent":
- agentIcon = "hr_agent";
- break;
- case "Expense_Billing_Agent":
- agentIcon = "expense_billing_agent";
- break;
- case "Invoice_Reconciliation_Agent":
- agentIcon = "invoice_reconciliation_agent";
- break;
- case "Tech_Support_Agent":
- agentIcon = "tech_agent";
- break;
- case "Procurement_Agent":
- agentIcon = "procurement_agent";
- break;
- case "Product_Agent":
- agentIcon = "product_agent";
- break;
- case "Group_Chat_Manager":
- agentIcon = "manager";
- break;
- case "Generic_Agent":
- agentIcon = "manager";
- break;
- case "Human_Agent":
- let userNumber = getStoredData("userNumber");
- if (userNumber == null) {
- // Generate a random number between 0 and 6
- userNumber = Math.floor(Math.random() * 6);
- // Create the icon name by concatenating 'user' with the random number
- setStoredData("userNumber", userNumber);
- }
- let iconName = "user" + userNumber;
- agentIcon = iconName;
- break;
- case "Done":
- agentIcon = "done";
- break;
- default:
- agentIcon = "marketing_agent";
- }
-
- return ` `;
- };
-
- const toDateTime = (timestamp) => {
- // Handle ISO date string format (e.g., 2025-04-25T03:01:13.093260)
- // instead of Unix timestamp
- const date = new Date(timestamp);
-
- // Check if date is valid
- if (isNaN(date.getTime())) {
- console.warn("Invalid date format:", timestamp);
- return "Invalid date";
- }
-
- const options = { month: "short", day: "numeric" };
- const timeOptions = { hour: "numeric", minute: "numeric", hour12: true };
- return `${date.toLocaleDateString(
- "en-US",
- options
- )} at ${date.toLocaleTimeString("en-US", timeOptions)}`;
- };
-
- const removeClassesExcept = (element, classToKeep) => {
- element.className = classToKeep;
- };
-
- const handleDisableOfActions = (status) => {
- if(status === "completed"){
- taskPauseButton.disabled=true;
- taskCancelButton.disabled=true;
- taskMessageTextarea.disabled = true;
- taskMessageTextarea.style.backgroundColor = "#efefef";
- taskMessageTextarea.style.cursor = 'not-allowed';
- taskMessageAddButton.setAttribute('disabled', true)
- taskMessageAddButton.style.cursor = 'not-allowed';
- textInputContainer[0].style.backgroundColor = '#efefef';
- textInputContainer[0].style.cursor = 'not-allowed';
- } else {
- taskPauseButton.disabled = false;
- taskCancelButton.disabled = false;
- }
- }
-
- const taskHeaderActions = () => {
- if (taskPauseButton) {
- taskPauseButton.addEventListener("click", (event) => {
- const iconElement = taskPauseButton.querySelector("i");
- if (iconElement) {
- iconElement.classList.toggle("fa-circle-pause");
- iconElement.classList.toggle("fa-circle-play");
- if (iconElement.classList.contains("fa-circle-play")) {
- taskPauseButton.classList.add("has-text-success");
- removeClassesExcept(taskStatusTag, "tag");
- taskStatusTag.classList.add("is-warning");
- taskStatusTag.textContent = "Paused";
- } else {
- taskPauseButton.classList.remove("has-text-success");
- removeClassesExcept(taskStatusTag, "tag");
- taskStatusTag.classList.add("is-info");
- taskStatusTag.textContent = "Restarting";
- taskDetails();
- }
- }
- });
- }
-
- if (taskCancelButton) {
- taskCancelButton.addEventListener("click", (event) => {
- const apiTaskStore = JSON.parse(getStoredData("apiTask"));
- handleDisableOfActions("completed")
-
- // Explicitly disable chatbox and message button
- taskMessageTextarea.disabled = true;
- taskMessageTextarea.style.backgroundColor = "#efefef";
- taskMessageTextarea.style.cursor = 'not-allowed';
-
- taskMessageAddButton.disabled = true;
- taskMessageAddButton.style.cursor = 'not-allowed';
-
- const textInputContainer = document.getElementsByClassName("text-input-container");
- if (textInputContainer[0]) {
- textInputContainer[0].style.backgroundColor = '#efefef';
- textInputContainer[0].style.cursor = 'not-allowed';
- }
-
- actionStages(apiTaskStore, false);
- });
- }
- };
-
- const updateTaskDetailsAgents = (agents) => {
- taskDetailsAgents.innerHTML = "";
- taskAgentsVsHumans = [];
-
- agents.forEach((agent) => {
- const isAvatar = agent === "Human_Agent" ? "is-human" : "is-avatar";
-
- taskDetailsAgents.innerHTML += `
-
- ${agentToIcon(agent)}
-
- `;
-
- agent === "Human_Agent"
- ? taskAgentsVsHumans.push("Human")
- : taskAgentsVsHumans.push("Agent");
- });
-
- const humansInv = taskAgentsVsHumans.filter((agent) => agent === "Human");
- const humanInvText = humansInv.length > 1 ? "humans" : "human";
-
- const agentsInv = taskAgentsVsHumans.filter((agent) => agent === "Agent");
- const agentsInvText = agentsInv.length > 1 ? "agents" : "agent";
-
- taskAgentsHumans.innerHTML = `Team selected: ${humansInv.length} ${humanInvText}, ${agentsInv.length} ${agentsInvText}`;
- };
-
- const updateTaskStatusDetails = (task) => {
- taskStatusDetails.innerHTML = "";
-
- taskStatusDetails.innerHTML = `
- Summary: ${task.summary}
- Created: ${toDateTime(task.timestamp)}
- `;
- };
-
- const fetchPlanDetails = async (session_id) => {
- const headers = await window.headers;
-
- return fetch(apiEndpoint + "/plans?session_id=" + session_id, {
- method: "GET",
- headers: headers,
- })
- .then((response) => response.json())
- .then((data) => {
- updateTaskStatusDetails(data[0]);
- updateTaskProgress(data[0]);
- fetchTaskStages(data[0]);
-
- setStoredData("apiTask", JSON.stringify(data[0]));
- //const isHumanClarificationRequestNull = data?.[0]?.human_clarification_request === null
- const isHumanClarificationResponseNotNull = data?.[0]?.human_clarification_response !== null;
- const taskMessageTextareaElement = document.getElementById("taskMessageTextarea");
- const taskMessageAddButton = document.getElementById("taskMessageAddButton");
- const textInputContainer = document.getElementsByClassName("text-input-container");
-
- if (isHumanClarificationResponseNotNull) {
- // Update the local state to set human_clarification_request to null
- data[0].human_clarification_request = null;
- console.log("Human clarification request set to null locally.");
- }
-
- const isHumanClarificationRequestNull = data?.[0]?.human_clarification_request === null
-
- if (isHumanClarificationRequestNull && taskMessageTextareaElement) {
- taskMessageTextareaElement.setAttribute('disabled', true)
- taskMessageTextareaElement.style.backgroundColor = "#efefef";
- taskMessageTextareaElement.style.cursor = 'not-allowed';
- }
-
- if (isHumanClarificationRequestNull && taskMessageAddButton) {
- taskMessageAddButton.setAttribute('disabled', true)
- taskMessageAddButton.style.cursor = 'not-allowed';
- }
-
- if (isHumanClarificationRequestNull && textInputContainer[0]) {
- textInputContainer[0].style.backgroundColor = '#efefef';
- textInputContainer[0].style.cursor = 'not-allowed';
- }
-
- })
- .catch((error) => {
- console.error("Error:", error);
- });
- };
-
- const fetchTaskStages = (task) => {
- window.headers.then((headers) => {
- fetch(apiEndpoint + "/steps/" + task.id, {
- method: "GET",
- headers: headers,
- })
- .then((response) => response.json())
- .then((data) => {
- if (taskStagesMenu) taskStagesMenu.innerHTML = "";
- let taskStageCount = 0;
- let taskStageApprovalStatus = 0;
-
- if (data && data.length > 0) {
- taskAgents = [];
-
- data.forEach((stage) => {
- const stageItem = document.createElement("li");
- const stageBase64 = btoa(
- encodeURIComponent(JSON.stringify(stage))
- );
-
- let stageStatusIcon = "";
- let stageActions = "";
- let stageRejected = "";
-
- switch (stage.status) {
- case "planned":
- stageStatusIcon = ` `;
- break;
- case "awaiting_feedback":
- stageStatusIcon = ` `;
- break;
- case "approved":
- stageStatusIcon = ` `;
- break;
- case "rejected":
- stageStatusIcon = ` `;
- break;
- case "action_requested":
- stageStatusIcon = ` `;
- break;
- case "completed":
- stageStatusIcon = ` `;
- break;
- case "failed":
- stageStatusIcon = ` `;
- break;
- default:
- stageStatusIcon = ` `;
- }
-
- if (stage.human_approval_status === "rejected") {
- stageRejected = "rejected";
- stageStatusIcon = ` `;
- }
-
- if (stage.human_approval_status === "requested")
- stageActions = `
-
- `;
-
- stageItem.innerHTML = `
-
- `;
-
- if (taskStagesMenu) taskStagesMenu.appendChild(stageItem);
-
- taskSessionId = stage.session_id;
- taskLastStageId = stage.id;
- taskLastAction = stage.action;
- taskAgents.push(stage.agent);
-
- stageItem
- .querySelectorAll(".menu-stage-action")
- .forEach((action) => {
- action.addEventListener("click", (event) => {
- actionStage(
- event.target.dataset.action,
- event.target.dataset.stage
- );
-
- action.parentElement.style.display = "none";
- });
- });
-
- if (stage.human_approval_status === "requested")
- taskStageApprovalStatus++;
-
- taskStageCount++;
- });
-
- updateTaskDetailsAgents([...new Set(taskAgents)]);
-
- setStoredData("showApproveAll", false);
-
- // Feature approve all removed for this version
- // if (isHumanFeedbackPending()) {
- // setStoredData('showApproveAll', false);
- // console.log('showApproveAll status', "showApproveAll is false");
-
- // } else {
- // setStoredData('showApproveAll', taskStageApprovalStatus === taskStageCount);
- // console.log('showApproveAll status', taskStageApprovalStatus === taskStageCount);
-
- // }
- }
-
- fetchTaskMessages(task);
-
- window.parent.postMessage(
- {
- action: "taskStarted",
- },
- "*"
- );
- })
- .catch((error) => {
- console.error("Error:", error);
- });
- });
- };
-
- const fetchTaskMessages = (task) => {
- window.headers.then((headers) => {
- fetch(apiEndpoint + "/agent_messages/" + task.session_id, {
- method: "GET",
- headers: headers,
- })
- .then((response) => response.json())
- .then((data) => {
- const toAgentName = (str) => {
- console.log("toAgentName", str);
- let new_name = str.replace(/_/g, " ");
- console.log("toAgentName", new_name);
- return new_name;
- };
-
- const groupByStepId = (messages) => {
- const groupedMessages = {};
-
- messages.forEach((message) => {
- const stepId = message.step_id || "planner";
- if (!groupedMessages[stepId]) {
- groupedMessages[stepId] = [];
- }
- groupedMessages[stepId].push(message);
- });
-
- return groupedMessages;
- };
-
- const contextFilter = (messages) => {
- const filteredMessages = [];
-
- messages.forEach((message) => {
- if (
- message.source !== "Planner_Agent" &&
- message.source !== "Group_Chat_Manager"
- ) {
- filteredMessages.push(message);
- }
- });
-
- return filteredMessages;
- };
-
- taskMessages.innerHTML = "";
-
- // console.log(groupByStepId(data));
-
- if (
- getStoredData("context") &&
- getStoredData("context") === "customer"
- ) {
- data = contextFilter(data);
- }
-
- if (data) {
- let stageCount = 0;
- let messageCount = 1;
- const groupedData = groupByStepId(data);
-
- Object.keys(groupedData).forEach((stage) => {
- const messages = groupedData[stage];
- const messageGroupItem = document.createElement("fieldset");
-
- messageGroupItem.classList.add("task-stage-divider");
- messageGroupItem.classList.add("has-text-info");
-
- messageGroupItem.innerHTML =
- stageCount === 0
- ? "Planning "
- : `Stage ${stageCount} `;
- taskMessages.appendChild(messageGroupItem);
-
- messages.forEach((message) => {
- const messageItem = document.createElement("div");
- const showApproveAll =
- getStoredData("showApproveAll") === "true" &&
- data.length === messageCount;
-
- let approveAllStagesButton = "";
-
- messageItem.classList.add("media");
- const isAvatar =
- message.source === "Human_Agent" ? "is-human" : "is-avatar";
- const isActive =
- message.source === "Planner_Agent"
- ? "has-status-busy"
- : "has-status-active";
-
- if (
- getStoredData("context") &&
- getStoredData("context") !== "customer"
- ) {
- if (showApproveAll) {
- console.log("Creating approveAllStagesButton");
- approveAllStagesButton = `If you are happy with the plan, you can approve all stages. Approve all stages `;
- }
- }
- const messageLeft = `
-
-
- ${agentToIcon(message.source)}
-
-
-
-
-
- ${toAgentName(
- message.source
- )} • ${toDateTime(
- message.timestamp
- )} AI-generated content may be incorrect
-
-
- ${markdownConverter.makeHtml(
- message.content
- )} ${approveAllStagesButton}
- ${message.source !== "Planner_Agent" && message.source !== "Group_Chat_Manager" ? `
-
- Disclaimer: Example function stub - not implemented
-
- ` : ''}
-
-
-
-
- `;
- const messageRight = `
-
-
-
- You • ${toDateTime(message.timestamp)}
-
-
- ${markdownConverter.makeHtml(
- message.content
- )}
-
-
-
-
-
- ${agentToIcon(message.source)}
-
-
- `;
-
- const messageTemplate =
- message.source === "Human_Agent" ? messageRight : messageLeft;
- messageItem.innerHTML = messageTemplate;
- taskMessages.appendChild(messageItem);
-
- if (
- getStoredData("context") &&
- getStoredData("context") !== "customer"
- ) {
- if (showApproveAll) {
- document
- .getElementById("approveAllStagesButton")
- .addEventListener("click", (event) =>
- actionStages(task, true)
- );
- }
- }
-
- messageCount++;
- });
-
- stageCount++;
- });
-
- const mediaContents = document.querySelectorAll(".media-content");
- if (mediaContents.length > 0) {
- mediaContents[mediaContents.length - 1].scrollIntoView({
- behavior: "smooth",
- });
- }
-
- if (
- getStoredData("context") &&
- getStoredData("context") === "customer" &&
- !getStoredData("actionStagesRun")
- .includes(task.session_id)
- ) {
- actionStages(task, true);
-
- let actionStagesRun = JSON.parse(
- getStoredData("actionStagesRun") || "[]"
- );
-
- actionStagesRun.push(task.session_id);
- setStoredData(
- "actionStagesRun",
- JSON.stringify(actionStagesRun)
- );
- }
-
- setTimeout(() => {
- taskLoader.classList.add("is-hidden");
- }, 500);
- }
- })
- .catch((error) => {
- console.error("Error:", error);
- });
- });
- };
-
- const updateTaskProgress = (task) => {
- const taskStatusToLabel = (str) => {
- return str
- .split("_")
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
- .join(" ");
- };
-
- const totalSteps = task.total_steps;
- const completedSteps = task.completed;
- const approvalRequired = task.steps_requiring_approval;
-
- const percentage = (completedSteps / totalSteps) * 100;
- const progressString = `Progress ${completedSteps}/${totalSteps}`;
- const percentageString = `${percentage.toFixed(0)}%`;
-
- taskProgress.textContent = progressString;
- taskProgressPercentage.textContent = percentageString;
- taskProgressBar.value = parseFloat(percentageString);
-
- taskStatusTag.textContent = taskStatusToLabel(task.overall_status);
-
- if (task.overall_status === "completed") {
- removeClassesExcept(taskStatusTag, "tag");
- taskStatusTag.classList.add("is-success");
- } else if (task.overall_status === "in_progress") {
- removeClassesExcept(taskStatusTag, "tag");
- taskStatusTag.classList.add("is-info");
- const iconElement = taskPauseButton.querySelector("i");
- if (iconElement.classList.contains("fa-circle-play")) {
- iconElement.classList.remove("fa-circle-play");
- iconElement.classList.add("fa-circle-pause");
- }
-
- }
- handleDisableOfActions(task.overall_status)
- };
-
- const isHumanFeedbackPending = () => {
- const storedData = getStoredData("apiTask");
- const planDetails = JSON.parse(storedData);
- return (
- planDetails.human_clarification_request !== null &&
- planDetails.human_clarification_response === null
- );
- };
-
- const actionStage = (action, stage) => {
- if (isHumanFeedbackPending()) {
- notyf.error("You must first provide feedback to the planner.");
- return;
- }
-
- const stageObj = JSON.parse(decodeURIComponent(atob(stage)));
-
- console.log("actionStage", {
- step_id: stageObj.id,
- plan_id: stageObj.plan_id,
- session_id: stageObj.session_id,
- approved: action === "approved" ? true : false,
- });
-
- notyf.open({
- type: "info",
- message: `Request sent for "${stageObj.action}"`,
- });
-
- window.headers.then((headers) => {
- fetch(apiEndpoint + "/approve_step_or_steps", {
- method: "POST",
- headers: headers,
- body: JSON.stringify({
- step_id: stageObj.id,
- plan_id: stageObj.plan_id,
- session_id: stageObj.session_id,
- approved: action === "approved" ? true : false,
- }),
- })
- .then((response) => response.json())
- .then((data) => {
- action === "approved"
- ? notyf.success(`Stage "${stageObj.action}" approved.`)
- : notyf.error(`Stage "${stageObj.action}" rejected.`);
-
- taskDetails();
- })
- .catch((error) => {
- console.error("Error:", error);
- });
- });
- };
-
- const actionStages = (task, approve) => {
- console.log("approveStages", {
- plan_id: task.id,
- session_id: task.session_id,
- approved: approve,
- });
-
- notyf.open({
- type: "info",
- message: `Request sent to action on all stages.`,
- });
-
- // document.querySelectorAll('.menu-stage-actions').forEach(element => {
- // element.style.display = 'none';
- // });
-
- window.headers.then((headers) => {
- fetch(apiEndpoint + "/approve_step_or_steps", {
- method: "POST",
- headers: headers,
- body: JSON.stringify({
- plan_id: task.id,
- session_id: task.session_id,
- approved: approve,
- }),
- })
- .then((response) => response.json())
- .then((data) => {
- console.log("approveStages", data);
- approve
- ? notyf.success(`All stages approved.`)
- : notyf.error(`All stages cancelled.`);
- taskDetails();
- })
- .catch((error) => {
- console.error("Error:", error);
- });
- });
- };
-
- const taskDetailsActions = () => {
- if (taskAgentsButton) {
- taskAgentsButton.addEventListener("click", (event) => {
- window.parent.postMessage(
- {
- button: "taskAgentsButton",
- id: taskStore.id,
- name: taskStore.name,
- },
- "*"
- );
- });
- }
-
- if (taskWokFlowButton) {
- taskWokFlowButton.addEventListener("click", (event) => {
- window.parent.postMessage(
- {
- button: "taskWokFlowButton",
- id: taskStore.id,
- name: taskStore.name,
- },
- "*"
- );
- });
- }
- };
-
- let lastDataHash = null;
- //Refresh timer
- const taskDetails = () => {
- if (taskStore) {
- taskName.innerHTML = taskStore.name;
-
- const fetchLoop = async (id) => {
- try {
- // Fetch the new data from the server
- const newData = await fetchPlanDetails(id);
-
- // Generate a hash of the new data
- const newDataHash = await GenerateHash(newData);
-
- // Check if the new data's hash is different from the last fetched data's hash
- if (newDataHash === lastDataHash) {
- console.log("Data hasn't changed. Skipping next poll.");
- return; // Skip polling if no changes
- }
-
- // Update the lastDataHash to the new hash
- lastDataHash = newDataHash;
-
-
- } catch (error) {
- console.error("Error in fetchLoop:", error);
- }
- };
-
- fetchLoop(taskStore.id); // Start the fetch loop
- }
- };
-
- const taskMessage = () => {
- const taskMessageTextarea = document.getElementById("taskMessageTextarea");
-
- if (taskMessageAddButton) {
- taskMessageAddButton.addEventListener("click", (event) => {
- const messageContent = taskMessageTextarea.value;
-
- if (!messageContent) {
- notyf.error("Please enter a message.");
- return;
- }
-
- taskMessageTextarea.disabled = true;
- taskMessageAddButton.disabled = true;
- taskMessageAddButton.classList.add("is-loading");
-
- console.log({
- plan_id: taskStore.id,
- session_id: taskSessionId,
- human_clarification: taskMessageTextarea.value,
- });
-
- window.headers.then((headers) => {
- fetch(apiEndpoint + "/human_clarification_on_plan", {
- method: "POST",
- headers: headers,
- body: JSON.stringify({
- plan_id: taskStore.id,
- session_id: taskSessionId,
- human_clarification: taskMessageTextarea.value,
- }),
- })
- .then((response) => response.json())
- .then((data) => {
- taskMessageTextarea.disabled = false;
- taskMessageAddButton.disabled = false;
- taskMessageAddButton.classList.remove("is-loading");
-
- taskMessageTextarea.value = "";
- fetchPlanDetails(taskStore.id);
-
- // Reset character count to 0
- const charCount = document.getElementById("charCount");
- if (charCount) {
- charCount.textContent = "0";
- }
- updateButtonImage();
-
- notyf.success("Additional details registered in plan.");
- })
- .catch((error) => {
- console.error("Error:", error);
- });
- });
- });
- }
- };
-
- const handleTextAreaTyping = () => {
- const newTaskPrompt = document.getElementById("taskMessageTextarea");
- newTaskPrompt.addEventListener("input", () => {
- // whenever text is sent to the text area, we want to update the character count and dynamically resize the text area
- const textInput = document.getElementById("taskMessageTextarea");
- const charCount = document.getElementById("charCount");
-
- // Update character count
- charCount.textContent = textInput.value.length;
-
- // Dynamically adjust height
- textInput.style.height = "auto";
- textInput.style.height = textInput.scrollHeight + "px";
- updateButtonImage();
- });
- newTaskPrompt.addEventListener("keydown", (event) => {
- const textValue = newTaskPrompt.value.trim();
- if (event.key === "Enter" && !event.shiftKey) {
- if (textValue === "") {
- event.preventDefault();
- } else {
- startTaskButton.click();
- }
- } else if (event.key === "Enter" && event.shiftKey) {
- return;
- }
- });
- };
- updateButtonImage();
- taskHeaderActions();
- taskDetailsActions();
- taskDetails();
- taskMessage();
- handleTextAreaTyping();
-})();
diff --git a/src/frontend/wwwroot/utils.js b/src/frontend/wwwroot/utils.js
deleted file mode 100644
index 61e5fe561..000000000
--- a/src/frontend/wwwroot/utils.js
+++ /dev/null
@@ -1,102 +0,0 @@
-
-// Utility to generate a SHA-256 hash of a string
-window.GenerateHash = async (data) => {
- const encoder = new TextEncoder();
- const dataBuffer = encoder.encode(JSON.stringify(data)); // Convert the object to a string
- const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);
- const hashArray = Array.from(new Uint8Array(hashBuffer)); // Convert buffer to byte array
- const hashHex = hashArray.map(byte => byte.toString(16).padStart(2, '0')).join('');
- return hashHex; // Return the hash as a hex string
-};
-
-// Function to fetch authentication details from EasyAuth
-window.GetAuthDetails = async () => {
- // Check if we are running on the server (production environment)
- if (window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1') {
- // This code runs on the server
- try {
- const authResponse = await fetch('/.auth/me');
-
- // Check if the request is successful
- if (!authResponse.ok) {
- if(getStoredData('authEnabled') === 'false') {
- //Authentication is disabled. Will use mock user
- console.log("Authentication Disabled. Using mock user details.");
-
- const headers = getMockUserHeaders();
-
- return headers;
- }
- console.log("Failed to fetch authentication details. Access to chat will be blocked.");
- return null;
- }
-
- // Parse the response to get user details
- const authData = await authResponse.json();
-
- // Extract the user details (Azure returns an array, so we pick the first element)
- const userDetails = authData[0] || {};
-
- // Construct headers using the global config object
- const headers = {
- 'Content-Type': 'application/json',
- 'X-Ms-Client-Principal': userDetails?.client_principal || '',
- 'X-Ms-Client-Principal-Id': userDetails?.user_claims?.find(claim => claim.typ === 'http://schemas.microsoft.com/identity/claims/objectidentifier')?.val || '',
- 'X-Ms-Client-Principal-Name': userDetails?.user_claims?.find(claim => claim.typ === 'name')?.val || '',
- 'X-Ms-Client-Principal-Idp': userDetails?.identity_provider || '',
- };
-
- return headers;
- } catch (error) {
- console.error("Error fetching authentication details:", error);
- return null;
- }
- } else {
- // This code runs locally so setup mock headers
- console.log("Running locally. Skipping authentication details fetch.");
-
- const headers = getMockUserHeaders();
-
- return headers;
- }
-
- function getMockUserHeaders() {
- const mockUserDetails = {
- client_principal: 'mock-client-principal-id',
- user_claims: [
- { typ: 'http://schemas.microsoft.com/identity/claims/objectidentifier', val: '12345678-abcd-efgh-ijkl-9876543210ab' }, // Mock Object ID
- { typ: 'name', val: 'Local User' }, // Mock Name
- { typ: 'email', val: 'localuser@example.com' }, // Mock Email (optional claim)
- ],
- identity_provider: 'mock-identity-provider', // Mock Identity Provider
- };
-
- const headers = {
- 'Content-Type': 'application/json',
- 'X-Ms-Client-Principal': mockUserDetails.client_principal || '',
- 'X-Ms-Client-Principal-Id': mockUserDetails.user_claims?.find(claim => claim.typ === 'http://schemas.microsoft.com/identity/claims/objectidentifier')?.val || '',
- 'X-Ms-Client-Principal-Name': mockUserDetails.user_claims?.find(claim => claim.typ === 'name')?.val || '',
- 'X-Ms-Client-Principal-Idp': mockUserDetails.identity_provider || '',
- };
- return headers;
- }
-};
-
-window.getStoredData = (key)=> {
- let data = localStorage.getItem(key);
-
- // If not found in localStorage, check sessionStorage
- if (!data) {
- data = sessionStorage.getItem(key);
- if (data) {
- // Move data from sessionStorage to localStorage
- setStoredData(key, data);
- sessionStorage.removeItem(key); // Optional cleanup
- }
- }
- return data;
-}
-
-window.setStoredData = (key, value)=> {
- localStorage.setItem(key, value)
-}
\ No newline at end of file