Task Management |
Time Tracking |
@@ -27,6 +45,24 @@
Worklenz is a project management tool designed to help organizations improve their efficiency. It provides a
comprehensive solution for managing projects, tasks, and collaboration within teams.
+## Table of Contents
+
+- [Features](#features)
+- [Tech Stack](#tech-stack)
+- [Getting Started](#getting-started)
+ - [Quick Start (Docker)](#-quick-start-docker---recommended)
+ - [Manual Installation](#๏ธ-manual-installation-for-development)
+- [Deployment](#deployment)
+ - [Local Development](#local-development-with-docker)
+ - [Remote Server Deployment](#remote-server-deployment)
+- [Configuration](#configuration)
+- [MinIO Integration](#minio-integration)
+- [Security](#security)
+- [Analytics](#analytics)
+- [Screenshots](#screenshots)
+- [Contributing](#contributing)
+- [License](#license)
+
## Features
- **Project Planning**: Create and organize projects, assign tasks to team members.
@@ -50,41 +86,80 @@ This repository contains the frontend and backend code for Worklenz.
## Getting Started
-These instructions will help you set up and run the Worklenz project on your local machine for development and testing purposes.
+Choose your preferred setup method below. Docker is recommended for quick setup and testing.
-### Prerequisites
+### ๐ Quick Start (Docker - Recommended)
-- Node.js (version 18 or higher)
-- PostgreSQL database
-- An S3-compatible storage service (like MinIO) or Azure Blob Storage
+The fastest way to get Worklenz running locally with all dependencies included.
-### Option 1: Manual Installation
+**Prerequisites:**
+- Docker and Docker Compose installed on your system
+- Git
-1. Clone the repository
+**Steps:**
+
+1. Clone the repository:
```bash
git clone https://github.com/Worklenz/worklenz.git
cd worklenz
```
-2. Set up environment variables
- - Copy the example environment files
- ```bash
- cp worklenz-backend/.env.template worklenz-backend/.env
- ```
- - Update the environment variables with your configuration
-
-3. Install dependencies
+2. Start the Docker containers:
```bash
-# Install backend dependencies
+docker-compose up -d
+```
+
+3. Access the application:
+ - **Frontend**: http://localhost:5000
+ - **Backend API**: http://localhost:3000
+ - **MinIO Console**: http://localhost:9001 (login: minioadmin/minioadmin)
+
+4. To stop the services:
+```bash
+docker-compose down
+```
+
+**Alternative startup methods:**
+- **Windows**: Run `start.bat`
+- **Linux/macOS**: Run `./start.sh`
+
+**Video Guide**: For a visual walkthrough of the local Docker deployment process, check out our [step-by-step video guide](https://www.youtube.com/watch?v=AfwAKxJbqLg).
+
+### ๐ ๏ธ Manual Installation (For Development)
+
+For developers who want to run the services individually or customize the setup.
+
+**Prerequisites:**
+- Node.js (version 18 or higher)
+- PostgreSQL (version 15 or higher)
+- An S3-compatible storage service (like MinIO) or Azure Blob Storage
+
+**Steps:**
+
+1. Clone the repository:
+```bash
+git clone https://github.com/Worklenz/worklenz.git
+cd worklenz
+```
+
+2. Set up environment variables:
+```bash
+cp worklenz-backend/.env.template worklenz-backend/.env
+# Update the environment variables with your configuration
+```
+
+3. Install dependencies:
+```bash
+# Backend dependencies
cd worklenz-backend
npm install
-# Install frontend dependencies
+# Frontend dependencies
cd ../worklenz-frontend
npm install
```
-4. Set up the database
+4. Set up the database:
```bash
# Create a PostgreSQL database named worklenz_db
cd worklenz-backend
@@ -100,49 +175,47 @@ psql -U your_username -d worklenz_db -f database/sql/2_dml.sql
psql -U your_username -d worklenz_db -f database/sql/5_database_user.sql
```
-5. Start the development servers
+5. Start the development servers:
```bash
-# In one terminal, start the backend
+# Terminal 1: Start the backend
cd worklenz-backend
npm run dev
-# In another terminal, start the frontend
+# Terminal 2: Start the frontend
cd worklenz-frontend
npm run dev
```
6. Access the application at http://localhost:5000
-### Option 2: Docker Setup
+## Deployment
-The project includes a fully configured Docker setup with:
-- Frontend React application
-- Backend server
-- PostgreSQL database
-- MinIO for S3-compatible storage
+For local development, follow the [Quick Start (Docker)](#-quick-start-docker---recommended) section above.
-1. Clone the repository:
-```bash
-git clone https://github.com/Worklenz/worklenz.git
-cd worklenz
-```
+### Remote Server Deployment
-2. Start the Docker containers (choose one option):
+When deploying to a remote server:
-**Using Docker Compose directly**
-```bash
-docker-compose up -d
-```
+1. Set up the environment files with your server's hostname:
+ ```bash
+ # For HTTP/WS
+ ./update-docker-env.sh your-server-hostname
+
+ # For HTTPS/WSS
+ ./update-docker-env.sh your-server-hostname true
+ ```
-3. The application will be available at:
- - Frontend: http://localhost:5000
- - Backend API: http://localhost:3000
- - MinIO Console: http://localhost:9001 (login with minioadmin/minioadmin)
+2. Pull and run the latest Docker images:
+ ```bash
+ docker-compose pull
+ docker-compose up -d
+ ```
-4. To stop the services:
-```bash
-docker-compose down
-```
+3. Access the application through your server's hostname:
+ - Frontend: http://your-server-hostname:5000
+ - Backend API: http://your-server-hostname:3000
+
+4. **Video Guide**: For a complete walkthrough of deploying Worklenz to a remote server, check out our [deployment video guide](https://www.youtube.com/watch?v=CAZGu2iOXQs&t=10s).
## Configuration
@@ -157,16 +230,46 @@ Worklenz requires several environment variables to be configured for proper oper
Please refer to the `.env.example` files for a full list of required variables.
-### MinIO Integration
+The Docker setup uses environment variables to configure the services:
+
+- **Frontend:**
+ - `VITE_API_URL`: URL of the backend API (default: http://backend:3000 for container networking)
+ - `VITE_SOCKET_URL`: WebSocket URL for real-time communication (default: ws://backend:3000)
+
+- **Backend:**
+ - Database connection parameters
+ - Storage configuration
+ - Other backend settings
+
+For custom configuration, edit the `.env` file or the `update-docker-env.sh` script.
+
+## MinIO Integration
The project uses MinIO as an S3-compatible object storage service, which provides an open-source alternative to AWS S3 for development and production.
+### Working with MinIO
+
+MinIO provides an S3-compatible API, so any code that works with S3 will work with MinIO by simply changing the endpoint URL. The backend has been configured to use MinIO by default, with no additional configuration required.
+
- **MinIO Console**: http://localhost:9001
- Username: minioadmin
- Password: minioadmin
- **Default Bucket**: worklenz-bucket (created automatically when the containers start)
+### Backend Storage Configuration
+
+The backend is pre-configured to use MinIO with the following settings:
+
+```javascript
+// S3 credentials with MinIO defaults
+export const REGION = process.env.AWS_REGION || "us-east-1";
+export const BUCKET = process.env.AWS_BUCKET || "worklenz-bucket";
+export const S3_URL = process.env.S3_URL || "http://minio:9000/worklenz-bucket";
+export const S3_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID || "minioadmin";
+export const S3_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY || "minioadmin";
+```
+
### Security Considerations
For production deployments:
@@ -177,20 +280,12 @@ For production deployments:
4. Enable HTTPS for all public endpoints
5. Review and update dependencies regularly
-## Contributing
-
-We welcome contributions from the community! If you'd like to contribute, please follow our [contributing guidelines](CONTRIBUTING.md).
-
## Security
If you believe you have found a security vulnerability in Worklenz, we encourage you to responsibly disclose this and not open a public issue. We will investigate all legitimate reports.
Email [info@worklenz.com](mailto:info@worklenz.com) to disclose any security vulnerabilities.
-## License
-
-This project is licensed under the [MIT License](LICENSE).
-
## Analytics
Worklenz uses Google Analytics to understand how the application is being used. This helps us improve the application and make better decisions about future development.
@@ -260,215 +355,13 @@ If you've previously opted in and want to opt-out:
-### Contributing
+## Contributing
-We welcome contributions from the community! If you'd like to contribute, please follow
-our [contributing guidelines](CONTRIBUTING.md).
+We welcome contributions from the community! If you'd like to contribute, please follow our [contributing guidelines](CONTRIBUTING.md).
-### License
+## License
Worklenz is open source and released under the [GNU Affero General Public License Version 3 (AGPLv3)](LICENSE).
By contributing to Worklenz, you agree that your contributions will be licensed under its AGPL.
-# Worklenz React
-
-This repository contains the React version of Worklenz with a Docker setup for easy development and deployment.
-
-## Getting Started with Docker
-
-The project includes a fully configured Docker setup with:
-- Frontend React application
-- Backend server
-- PostgreSQL database
-- MinIO for S3-compatible storage
-
-### Prerequisites
-
-- Docker and Docker Compose installed on your system
-- Git
-
-### Quick Start
-
-1. Clone the repository:
-```bash
-git clone https://github.com/Worklenz/worklenz.git
-cd worklenz
-```
-
-2. Start the Docker containers (choose one option):
-
-**Option 1: Using the provided scripts (easiest)**
-- On Windows:
- ```
- start.bat
- ```
-- On Linux/macOS:
- ```bash
- ./start.sh
- ```
-
-**Option 2: Using Docker Compose directly**
-```bash
-docker-compose up -d
-```
-
-3. The application will be available at:
- - Frontend: http://localhost:5000
- - Backend API: http://localhost:3000
- - MinIO Console: http://localhost:9001 (login with minioadmin/minioadmin)
-
-4. To stop the services (choose one option):
-
-**Option 1: Using the provided scripts**
-- On Windows:
- ```
- stop.bat
- ```
-- On Linux/macOS:
- ```bash
- ./stop.sh
- ```
-
-**Option 2: Using Docker Compose directly**
-```bash
-docker-compose down
-```
-
-
-## MinIO Integration
-
-The project uses MinIO as an S3-compatible object storage service, which provides an open-source alternative to AWS S3 for development and production.
-
-### Working with MinIO
-
-MinIO provides an S3-compatible API, so any code that works with S3 will work with MinIO by simply changing the endpoint URL. The backend has been configured to use MinIO by default, with no additional configuration required.
-
-- **MinIO Console**: http://localhost:9001
- - Username: minioadmin
- - Password: minioadmin
-
-- **Default Bucket**: worklenz-bucket (created automatically when the containers start)
-
-### Backend Storage Configuration
-
-The backend is pre-configured to use MinIO with the following settings:
-
-```javascript
-// S3 credentials with MinIO defaults
-export const REGION = process.env.AWS_REGION || "us-east-1";
-export const BUCKET = process.env.AWS_BUCKET || "worklenz-bucket";
-export const S3_URL = process.env.S3_URL || "http://minio:9000/worklenz-bucket";
-export const S3_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID || "minioadmin";
-export const S3_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY || "minioadmin";
-```
-
-The S3 client is initialized with special MinIO configuration:
-
-```javascript
-const s3Client = new S3Client({
- region: REGION,
- credentials: {
- accessKeyId: S3_ACCESS_KEY_ID || "",
- secretAccessKey: S3_SECRET_ACCESS_KEY || "",
- },
- endpoint: getEndpointFromUrl(), // Extracts endpoint from S3_URL
- forcePathStyle: true, // Required for MinIO
-});
-```
-
-### Environment Configuration
-
-The project uses the following environment file structure:
-
-- **Frontend**:
- - `worklenz-frontend/.env.development` - Development environment variables
- - `worklenz-frontend/.env.production` - Production build variables
-
-- **Backend**:
- - `worklenz-backend/.env` - Backend environment variables
-
-### Setting Up Environment Files
-
-The Docker environment script will create or overwrite all environment files:
-
-```bash
-# For HTTP/WS
-./update-docker-env.sh your-hostname
-
-# For HTTPS/WSS
-./update-docker-env.sh your-hostname true
-```
-
-This script generates properly configured environment files for both development and production environments.
-
-## Docker Deployment
-
-### Local Development with Docker
-
-1. Set up the environment files:
- ```bash
- # For HTTP/WS
- ./update-docker-env.sh
-
- # For HTTPS/WSS
- ./update-docker-env.sh localhost true
- ```
-
-2. Run the application using Docker Compose:
- ```bash
- docker-compose up -d
- ```
-
-3. Access the application:
- - Frontend: http://localhost:5000
- - Backend API: http://localhost:3000 (or https://localhost:3000 with SSL)
-
-4. Video Guide
-
- For a visual walkthrough of the local Docker deployment process, check out our [step-by-step video guide](https://www.youtube.com/watch?v=AfwAKxJbqLg).
-
-### Remote Server Deployment
-
-When deploying to a remote server:
-
-1. Set up the environment files with your server's hostname:
- ```bash
- # For HTTP/WS
- ./update-docker-env.sh your-server-hostname
-
- # For HTTPS/WSS
- ./update-docker-env.sh your-server-hostname true
- ```
-
- This ensures that the frontend correctly connects to the backend API.
-
-2. Pull and run the latest Docker images:
- ```bash
- docker-compose pull
- docker-compose up -d
- ```
-
-3. Access the application through your server's hostname:
- - Frontend: http://your-server-hostname:5000
- - Backend API: http://your-server-hostname:3000
-
-4. Video Guide
-
- For a complete walkthrough of deploying Worklenz to a remote server, check out our [deployment video guide](https://www.youtube.com/watch?v=CAZGu2iOXQs&t=10s).
-
-### Environment Configuration
-
-The Docker setup uses environment variables to configure the services:
-
-- Frontend:
- - `VITE_API_URL`: URL of the backend API (default: http://backend:3000 for container networking)
- - `VITE_SOCKET_URL`: WebSocket URL for real-time communication (default: ws://backend:3000)
-
-- Backend:
- - Database connection parameters
- - Storage configuration
- - Other backend settings
-
-For custom configuration, edit the `.env` file or the `update-docker-env.sh` script.
-
diff --git a/SETUP_THE_PROJECT.md b/SETUP_THE_PROJECT.md
index c8917ac1..9a3568cd 100644
--- a/SETUP_THE_PROJECT.md
+++ b/SETUP_THE_PROJECT.md
@@ -4,7 +4,7 @@ Getting started with development is a breeze! Follow these steps and you'll be c
## Requirements
-- Node.js version v16 or newer - [Node.js](https://nodejs.org/en/download/)
+- Node.js version v20 or newer - [Node.js](https://nodejs.org/en/download/)
- PostgreSQL version v15 or newer - [PostgreSQL](https://www.postgresql.org/download/)
- S3-compatible storage (like MinIO) for file storage
@@ -38,7 +38,7 @@ Getting started with development is a breeze! Follow these steps and you'll be c
npm start
```
-4. Navigate to [http://localhost:5173](http://localhost:5173)
+4. Navigate to [http://localhost:5173](http://localhost:5173) (development server)
### Backend installation
@@ -126,7 +126,7 @@ For an easier setup, you can use Docker and Docker Compose:
```
3. Access the application:
- - Frontend: http://localhost:5000
+ - Frontend: http://localhost:5000 (Docker production build)
- Backend API: http://localhost:3000
- MinIO Console: http://localhost:9001 (login with minioadmin/minioadmin)
diff --git a/backup.sh b/backup.sh
new file mode 100644
index 00000000..8f16e1c7
--- /dev/null
+++ b/backup.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+set -eu
+
+# Adjust these as needed:
+CONTAINER=worklenz_db
+DB_NAME=worklenz_db
+DB_USER=postgres
+BACKUP_DIR=./pg_backups
+mkdir -p "$BACKUP_DIR"
+
+timestamp=$(date +%Y-%m-%d_%H-%M-%S)
+outfile="${BACKUP_DIR}/${DB_NAME}_${timestamp}.sql"
+echo "Creating backup $outfile ..."
+
+docker exec -t "$CONTAINER" pg_dump -U "$DB_USER" -d "$DB_NAME" > "$outfile"
+echo "Backup saved to $outfile"
diff --git a/docker-compose.yml b/docker-compose.yml
index 363f2006..6522ddff 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -83,7 +83,11 @@ services:
POSTGRES_DB: ${DB_NAME:-worklenz_db}
POSTGRES_PASSWORD: ${DB_PASSWORD:-password}
healthcheck:
- test: [ "CMD-SHELL", "pg_isready -d ${DB_NAME:-worklenz_db} -U ${DB_USER:-postgres}" ]
+ test:
+ [
+ "CMD-SHELL",
+ "pg_isready -d ${DB_NAME:-worklenz_db} -U ${DB_USER:-postgres}",
+ ]
interval: 10s
timeout: 5s
retries: 5
@@ -93,23 +97,65 @@ services:
volumes:
- worklenz_postgres_data:/var/lib/postgresql/data
- type: bind
- source: ./worklenz-backend/database
- target: /docker-entrypoint-initdb.d
+ source: ./worklenz-backend/database/sql
+ target: /docker-entrypoint-initdb.d/sql
consistency: cached
+ - type: bind
+ source: ./worklenz-backend/database/migrations
+ target: /docker-entrypoint-initdb.d/migrations
+ consistency: cached
+ - type: bind
+ source: ./worklenz-backend/database/00_init.sh
+ target: /docker-entrypoint-initdb.d/00_init.sh
+ consistency: cached
+ - type: bind
+ source: ./pg_backups
+ target: /docker-entrypoint-initdb.d/pg_backups
command: >
- bash -c ' if command -v apt-get >/dev/null 2>&1; then
- apt-get update && apt-get install -y dos2unix
- elif command -v apk >/dev/null 2>&1; then
- apk add --no-cache dos2unix
- fi && find /docker-entrypoint-initdb.d -type f -name "*.sh" -exec sh -c '\''
- dos2unix "{}" 2>/dev/null || true
- chmod +x "{}"
- '\'' \; && exec docker-entrypoint.sh postgres '
+ bash -c '
+ if command -v apt-get >/dev/null 2>&1; then
+ apt-get update && apt-get install -y dos2unix
+ elif command -v apk >/dev/null 2>&1; then
+ apk add --no-cache dos2unix
+ fi
+
+ find /docker-entrypoint-initdb.d -type f -name "*.sh" -exec sh -c '"'"'
+ for f; do
+ dos2unix "$f" 2>/dev/null || true
+ chmod +x "$f"
+ done
+ '"'"' sh {} +
+
+ exec docker-entrypoint.sh postgres
+ '
+ db-backup:
+ image: postgres:15
+ container_name: worklenz_db_backup
+ environment:
+ POSTGRES_USER: ${DB_USER:-postgres}
+ POSTGRES_DB: ${DB_NAME:-worklenz_db}
+ POSTGRES_PASSWORD: ${DB_PASSWORD:-password}
+ depends_on:
+ db:
+ condition: service_healthy
+ volumes:
+ - ./pg_backups:/pg_backups #host dir for backups files
+ #setup bassh loop to backup data evey 24h
+ command: >
+ bash -c 'while true; do
+ sleep 86400;
+ PGPASSWORD=$$POSTGRES_PASSWORD pg_dump -h worklenz_db -U $$POSTGRES_USER -d $$POSTGRES_DB \
+ > /pg_backups/worklenz_db_$$(date +%Y-%m-%d_%H-%M-%S).sql;
+ find /pg_backups -type f -name "*.sql" -mtime +30 -delete;
+ done'
+ restart: unless-stopped
+ networks:
+ - worklenz
volumes:
worklenz_postgres_data:
worklenz_minio_data:
-
+ pgdata:
networks:
worklenz:
diff --git a/docs/enhanced-task-management-technical-guide.md b/docs/enhanced-task-management-technical-guide.md
new file mode 100644
index 00000000..af808cd6
--- /dev/null
+++ b/docs/enhanced-task-management-technical-guide.md
@@ -0,0 +1,429 @@
+# Enhanced Task Management: Technical Guide
+
+## Overview
+The Enhanced Task Management system is a comprehensive React-based interface built on top of WorkLenz's existing task infrastructure. It provides a modern, grouped view with drag-and-drop functionality, bulk operations, and responsive design.
+
+## Architecture
+
+### Component Structure
+```
+src/components/task-management/
+โโโ TaskListBoard.tsx # Main container with DnD context
+โโโ TaskGroup.tsx # Individual group with collapse/expand
+โโโ TaskRow.tsx # Task display with rich metadata
+โโโ GroupingSelector.tsx # Grouping method switcher
+โโโ BulkActionBar.tsx # Bulk operations toolbar
+```
+
+### Integration Points
+The system integrates with existing WorkLenz infrastructure:
+
+- **Redux Store:** Uses `tasks.slice.ts` for state management
+- **Types:** Leverages existing TypeScript interfaces
+- **API Services:** Works with existing task API endpoints
+- **WebSocket:** Supports real-time updates via existing socket system
+
+## Core Components
+
+### TaskListBoard.tsx
+Main orchestrator component that provides:
+
+- **DnD Context:** @dnd-kit drag-and-drop functionality
+- **State Management:** Redux integration for task data
+- **Event Handling:** Drag events and bulk operations
+- **Layout Structure:** Header controls and group container
+
+#### Key Props
+```typescript
+interface TaskListBoardProps {
+ projectId: string; // Required: Project identifier
+ className?: string; // Optional: Additional CSS classes
+}
+```
+
+#### Redux Selectors Used
+```typescript
+const {
+ taskGroups, // ITaskListGroup[] - Grouped task data
+ loadingGroups, // boolean - Loading state
+ error, // string | null - Error state
+ groupBy, // IGroupBy - Current grouping method
+ search, // string | null - Search filter
+ archived, // boolean - Show archived tasks
+} = useSelector((state: RootState) => state.taskReducer);
+```
+
+### TaskGroup.tsx
+Renders individual task groups with:
+
+- **Collapsible Headers:** Expand/collapse functionality
+- **Progress Indicators:** Visual completion progress
+- **Drop Zones:** Accept dropped tasks from other groups
+- **Group Statistics:** Task counts and completion rates
+
+#### Key Props
+```typescript
+interface TaskGroupProps {
+ group: ITaskListGroup; // Group data with tasks
+ projectId: string; // Project context
+ currentGrouping: IGroupBy; // Current grouping mode
+ selectedTaskIds: string[]; // Selected task IDs
+ onAddTask?: (groupId: string) => void;
+ onToggleCollapse?: (groupId: string) => void;
+}
+```
+
+### TaskRow.tsx
+Individual task display featuring:
+
+- **Rich Metadata:** Progress, assignees, labels, due dates
+- **Drag Handles:** Sortable within and between groups
+- **Selection:** Multi-select with checkboxes
+- **Subtask Support:** Expandable hierarchy display
+
+#### Key Props
+```typescript
+interface TaskRowProps {
+ task: IProjectTask; // Task data
+ projectId: string; // Project context
+ groupId: string; // Parent group ID
+ currentGrouping: IGroupBy; // Current grouping mode
+ isSelected: boolean; // Selection state
+ isDragOverlay?: boolean; // Drag overlay rendering
+ index?: number; // Position in group
+ onSelect?: (taskId: string, selected: boolean) => void;
+ onToggleSubtasks?: (taskId: string) => void;
+}
+```
+
+## State Management
+
+### Redux Integration
+The system uses existing WorkLenz Redux patterns:
+
+```typescript
+// Primary slice used
+import {
+ fetchTaskGroups, // Async thunk for loading data
+ reorderTasks, // Update task order/group
+ setGroup, // Change grouping method
+ updateTaskStatus, // Update individual task status
+ updateTaskPriority, // Update individual task priority
+ // ... other existing actions
+} from '@/features/tasks/tasks.slice';
+```
+
+### Data Flow
+1. **Component Mount:** `TaskListBoard` dispatches `fetchTaskGroups(projectId)`
+2. **Group Changes:** `setGroup(newGroupBy)` triggers data reorganization
+3. **Drag Operations:** `reorderTasks()` updates task positions and properties
+4. **Real-time Updates:** WebSocket events update Redux state automatically
+
+## Drag and Drop Implementation
+
+### DnD Kit Integration
+Uses @dnd-kit for modern, accessible drag-and-drop:
+
+```typescript
+// Sensors for different input methods
+const sensors = useSensors(
+ useSensor(PointerSensor, {
+ activationConstraint: { distance: 8 }
+ }),
+ useSensor(KeyboardSensor, {
+ coordinateGetter: sortableKeyboardCoordinates
+ })
+);
+```
+
+### Drag Event Handling
+```typescript
+const handleDragEnd = (event: DragEndEvent) => {
+ const { active, over } = event;
+
+ // Determine source and target
+ const sourceGroup = findTaskGroup(active.id);
+ const targetGroup = findTargetGroup(over?.id);
+
+ // Update task arrays and dispatch changes
+ dispatch(reorderTasks({
+ activeGroupId: sourceGroup.id,
+ overGroupId: targetGroup.id,
+ fromIndex: sourceIndex,
+ toIndex: targetIndex,
+ task: movedTask,
+ updatedSourceTasks,
+ updatedTargetTasks,
+ }));
+};
+```
+
+### Smart Property Updates
+When tasks are moved between groups, properties update automatically:
+
+- **Status Grouping:** Moving to "Done" group sets task status to "done"
+- **Priority Grouping:** Moving to "High" group sets task priority to "high"
+- **Phase Grouping:** Moving to "Testing" group sets task phase to "testing"
+
+## Bulk Operations
+
+### Selection State Management
+```typescript
+// Local state for task selection
+const [selectedTaskIds, setSelectedTaskIds] = useState([]);
+
+// Selection handlers
+const handleTaskSelect = (taskId: string, selected: boolean) => {
+ if (selected) {
+ setSelectedTaskIds(prev => [...prev, taskId]);
+ } else {
+ setSelectedTaskIds(prev => prev.filter(id => id !== taskId));
+ }
+};
+```
+
+### Context-Aware Actions
+Bulk actions adapt to current grouping:
+
+```typescript
+// Only show status changes when not grouped by status
+{currentGrouping !== 'status' && (
+
+
+
+)}
+```
+
+## Performance Optimizations
+
+### Memoized Selectors
+```typescript
+// Expensive group calculations are memoized
+const taskGroups = useMemo(() => {
+ return createGroupsFromTasks(tasks, currentGrouping);
+}, [tasks, currentGrouping]);
+```
+
+### Virtual Scrolling Ready
+For large datasets, the system is prepared for react-window integration:
+
+```typescript
+// Large group detection
+const shouldVirtualize = group.tasks.length > 100;
+
+return shouldVirtualize ? (
+
+) : (
+
+);
+```
+
+### Optimistic Updates
+UI updates immediately while API calls process in background:
+
+```typescript
+// Immediate UI update
+dispatch(updateTaskStatusOptimistically(taskId, newStatus));
+
+// API call with rollback on error
+try {
+ await updateTaskStatus(taskId, newStatus);
+} catch (error) {
+ dispatch(rollbackTaskStatusUpdate(taskId));
+}
+```
+
+## Responsive Design
+
+### Breakpoint Strategy
+```css
+/* Mobile-first responsive design */
+.task-row {
+ padding: 12px;
+}
+
+@media (min-width: 768px) {
+ .task-row {
+ padding: 16px;
+ }
+}
+
+@media (min-width: 1024px) {
+ .task-row {
+ padding: 20px;
+ }
+}
+```
+
+### Progressive Enhancement
+- **Mobile:** Essential information only
+- **Tablet:** Additional metadata visible
+- **Desktop:** Full feature set with optimal layout
+
+## Accessibility
+
+### ARIA Implementation
+```typescript
+// Proper ARIA labels for screen readers
+
+
+
+```
+
+### Keyboard Navigation
+- **Tab:** Navigate between elements
+- **Space:** Select/deselect tasks
+- **Enter:** Activate buttons
+- **Arrows:** Navigate sortable lists with keyboard sensor
+
+### Focus Management
+```typescript
+// Maintain focus during dynamic updates
+useEffect(() => {
+ if (shouldFocusTask) {
+ taskRef.current?.focus();
+ }
+}, [taskGroups]);
+```
+
+## WebSocket Integration
+
+### Real-time Updates
+The system subscribes to existing WorkLenz WebSocket events:
+
+```typescript
+// Socket event handlers (existing WorkLenz patterns)
+socket.on('TASK_STATUS_CHANGED', (data) => {
+ dispatch(updateTaskStatus(data));
+});
+
+socket.on('TASK_PROGRESS_UPDATED', (data) => {
+ dispatch(updateTaskProgress(data));
+});
+```
+
+### Live Collaboration
+- Multiple users can work simultaneously
+- Changes appear in real-time
+- Conflict resolution through server-side validation
+
+## API Integration
+
+### Existing Endpoints Used
+```typescript
+// Uses existing WorkLenz API services
+import { tasksApiService } from '@/api/tasks/tasks.api.service';
+
+// Task data fetching
+tasksApiService.getTaskList(config);
+
+// Task updates
+tasksApiService.updateTask(taskId, changes);
+
+// Bulk operations
+tasksApiService.bulkUpdateTasks(taskIds, changes);
+```
+
+### Error Handling
+```typescript
+try {
+ await dispatch(fetchTaskGroups(projectId));
+} catch (error) {
+ // Display user-friendly error message
+ message.error('Failed to load tasks. Please try again.');
+ logger.error('Task loading error:', error);
+}
+```
+
+## Testing Strategy
+
+### Component Testing
+```typescript
+// Example test structure
+describe('TaskListBoard', () => {
+ it('should render task groups correctly', () => {
+ const mockTasks = generateMockTasks(10);
+ render();
+
+ expect(screen.getByText('Tasks (10)')).toBeInTheDocument();
+ });
+
+ it('should handle drag and drop operations', async () => {
+ // Test drag and drop functionality
+ });
+});
+```
+
+### Integration Testing
+- Redux state management
+- API service integration
+- WebSocket event handling
+- Drag and drop operations
+
+## Development Guidelines
+
+### Code Organization
+- Follow existing WorkLenz patterns
+- Use TypeScript strictly
+- Implement proper error boundaries
+- Maintain accessibility standards
+
+### Performance Considerations
+- Memoize expensive calculations
+- Implement virtual scrolling for large datasets
+- Debounce user input operations
+- Optimize re-render cycles
+
+### Styling Standards
+- Use existing Ant Design components
+- Follow WorkLenz design system
+- Implement responsive breakpoints
+- Maintain dark mode compatibility
+
+## Future Enhancements
+
+### Planned Features
+- Custom column integration
+- Advanced filtering capabilities
+- Kanban board view
+- Enhanced time tracking
+- Task templates
+
+### Extension Points
+The system is designed for easy extension:
+
+```typescript
+// Plugin architecture ready
+interface TaskViewPlugin {
+ name: string;
+ component: React.ComponentType;
+ supportedGroupings: IGroupBy[];
+}
+
+const plugins: TaskViewPlugin[] = [
+ { name: 'kanban', component: KanbanView, supportedGroupings: ['status'] },
+ { name: 'timeline', component: TimelineView, supportedGroupings: ['phase'] },
+];
+```
+
+## Deployment Considerations
+
+### Bundle Size
+- Tree-shake unused dependencies
+- Code-split large components
+- Optimize asset loading
+
+### Browser Compatibility
+- Modern browsers (ES2020+)
+- Graceful degradation for older browsers
+- Progressive enhancement approach
+
+### Performance Monitoring
+- Track component render times
+- Monitor API response times
+- Measure user interaction latency
\ No newline at end of file
diff --git a/docs/enhanced-task-management-user-guide.md b/docs/enhanced-task-management-user-guide.md
new file mode 100644
index 00000000..34a50e85
--- /dev/null
+++ b/docs/enhanced-task-management-user-guide.md
@@ -0,0 +1,275 @@
+# Enhanced Task Management: User Guide
+
+## What Is Enhanced Task Management?
+The Enhanced Task Management system provides a modern, grouped view of your tasks with advanced features like drag-and-drop, bulk operations, and dynamic grouping. This system builds on WorkLenz's existing task infrastructure while offering improved productivity and organization tools.
+
+## Why Use Enhanced Task Management?
+- **Better Organization:** Group tasks by Status, Priority, or Phase for clearer project overview
+- **Increased Productivity:** Bulk operations let you update multiple tasks at once
+- **Intuitive Interface:** Drag-and-drop functionality makes task management feel natural
+- **Rich Task Display:** See progress, assignees, labels, and due dates at a glance
+- **Responsive Design:** Works seamlessly on desktop, tablet, and mobile devices
+
+## Getting Started
+
+### Accessing Enhanced Task Management
+1. Navigate to your project workspace
+2. Look for the enhanced task view option in your project interface
+3. The system will display your tasks grouped by the current grouping method (default: Status)
+
+### Understanding the Interface
+The enhanced task management interface consists of several key areas:
+
+- **Header Controls:** Task count, grouping selector, and action buttons
+- **Task Groups:** Collapsible sections containing related tasks
+- **Individual Tasks:** Rich task cards with metadata and actions
+- **Bulk Action Bar:** Appears when multiple tasks are selected (blue bar)
+
+## Task Grouping
+
+### Available Grouping Options
+You can organize your tasks using three different grouping methods:
+
+#### 1. Status Grouping (Default)
+Groups tasks by their current status:
+- **To Do:** Tasks not yet started
+- **Doing:** Tasks currently in progress
+- **Done:** Completed tasks
+
+#### 2. Priority Grouping
+Groups tasks by their priority level:
+- **Critical:** Highest priority, urgent tasks
+- **High:** Important tasks requiring attention
+- **Medium:** Standard priority tasks
+- **Low:** Tasks that can be addressed later
+
+#### 3. Phase Grouping
+Groups tasks by project phases:
+- **Planning:** Tasks in the planning stage
+- **Development:** Implementation and development tasks
+- **Testing:** Quality assurance and testing tasks
+- **Deployment:** Release and deployment tasks
+
+### Switching Between Groupings
+1. Locate the "Group by" dropdown in the header controls
+2. Select your preferred grouping method (Status, Priority, or Phase)
+3. Tasks will automatically reorganize into the new groups
+4. Your grouping preference is saved for future sessions
+
+### Group Features
+Each task group includes:
+- **Color-coded headers** with visual indicators
+- **Task count badges** showing the number of tasks in each group
+- **Progress indicators** showing completion percentage
+- **Collapse/expand functionality** to hide or show group contents
+- **Add task buttons** to quickly create tasks in specific groups
+
+## Drag and Drop
+
+### Moving Tasks Within Groups
+1. Hover over a task to reveal the drag handle (โฎโฎ icon)
+2. Click and hold the drag handle
+3. Drag the task to your desired position within the same group
+4. Release to drop the task in its new position
+
+### Moving Tasks Between Groups
+1. Click and hold the drag handle on any task
+2. Drag the task over a different group
+3. The target group will highlight to show it can accept the task
+4. Release to drop the task into the new group
+5. The task's properties (status, priority, or phase) will automatically update
+
+### Drag and Drop Benefits
+- **Instant Updates:** Task properties change automatically when moved between groups
+- **Visual Feedback:** Clear indicators show where tasks can be dropped
+- **Keyboard Accessible:** Alternative keyboard controls for accessibility
+- **Mobile Friendly:** Touch-friendly drag operations on mobile devices
+
+## Multi-Select and Bulk Operations
+
+### Selecting Tasks
+You can select multiple tasks using several methods:
+
+#### Individual Selection
+- Click the checkbox next to any task to select it
+- Click again to deselect
+
+#### Range Selection
+- Select the first task in your desired range
+- Hold Shift and click the last task in the range
+- All tasks between the first and last will be selected
+
+#### Multiple Selection
+- Hold Ctrl (or Cmd on Mac) while clicking tasks
+- This allows you to select non-consecutive tasks
+
+### Bulk Actions
+When you have tasks selected, a blue bulk action bar appears with these options:
+
+#### Change Status (when not grouped by Status)
+- Update the status of all selected tasks at once
+- Choose from available status options in your project
+
+#### Set Priority (when not grouped by Priority)
+- Assign the same priority level to all selected tasks
+- Options include Critical, High, Medium, and Low
+
+#### More Actions
+Additional bulk operations include:
+- **Assign to Member:** Add team members to multiple tasks
+- **Add Labels:** Apply labels to selected tasks
+- **Archive Tasks:** Move multiple tasks to archive
+
+#### Delete Tasks
+- Permanently remove multiple tasks at once
+- Confirmation dialog prevents accidental deletions
+
+### Bulk Action Tips
+- The bulk action bar only shows relevant options based on your current grouping
+- You can clear your selection at any time using the "Clear" button
+- Bulk operations provide immediate feedback and can be undone if needed
+
+## Task Display Features
+
+### Rich Task Information
+Each task displays comprehensive information:
+
+#### Basic Information
+- **Task Key:** Unique identifier (e.g., PROJ-123)
+- **Task Name:** Clear, descriptive title
+- **Description:** Additional details when available
+
+#### Visual Indicators
+- **Progress Bar:** Shows completion percentage (0-100%)
+- **Priority Indicator:** Color-coded dot showing task importance
+- **Status Color:** Left border color indicates current status
+
+#### Team and Collaboration
+- **Assignee Avatars:** Profile pictures of assigned team members (up to 3 visible)
+- **Labels:** Color-coded tags for categorization
+- **Comment Count:** Number of comments and discussions
+- **Attachment Count:** Number of files attached to the task
+
+#### Timing Information
+- **Due Dates:** When tasks are scheduled to complete
+ - Red text: Overdue tasks
+ - Orange text: Due today or within 3 days
+ - Gray text: Future due dates
+- **Time Tracking:** Estimated vs. logged time when available
+
+### Subtask Support
+Tasks with subtasks include additional features:
+
+#### Expanding Subtasks
+- Click the "+X" button next to task names to expand subtasks
+- Subtasks appear indented below the parent task
+- Click "โX" to collapse subtasks
+
+#### Subtask Progress
+- Parent task progress reflects completion of all subtasks
+- Individual subtask progress is visible when expanded
+- Subtask counts show total number of child tasks
+
+## Advanced Features
+
+### Real-time Updates
+- Changes made by team members appear instantly
+- Live collaboration with multiple users
+- WebSocket connections ensure data synchronization
+
+### Search and Filtering
+- Use existing project search and filter capabilities
+- Enhanced task management respects current filter settings
+- Search results maintain grouping organization
+
+### Responsive Design
+The interface adapts to different screen sizes:
+
+#### Desktop (Large Screens)
+- Full feature set with all metadata visible
+- Optimal drag-and-drop experience
+- Multi-column layouts where appropriate
+
+#### Tablet (Medium Screens)
+- Condensed but functional interface
+- Touch-friendly interactions
+- Simplified metadata display
+
+#### Mobile (Small Screens)
+- Stacked layout for easy navigation
+- Large touch targets for selections
+- Essential information prioritized
+
+## Best Practices
+
+### Organizing Your Tasks
+1. **Choose the Right Grouping:** Select the grouping method that best fits your workflow
+2. **Use Labels Consistently:** Apply meaningful labels for better categorization
+3. **Keep Groups Balanced:** Avoid having too many tasks in a single group
+4. **Regular Maintenance:** Review and update task organization periodically
+
+### Collaboration Tips
+1. **Clear Task Names:** Use descriptive titles that everyone understands
+2. **Proper Assignment:** Assign tasks to appropriate team members
+3. **Progress Updates:** Keep progress percentages current for accurate project tracking
+4. **Use Comments:** Communicate about tasks using the comment system
+
+### Productivity Techniques
+1. **Batch Similar Operations:** Use bulk actions for efficiency
+2. **Prioritize Effectively:** Use priority grouping during planning phases
+3. **Track Progress:** Monitor completion rates using group progress indicators
+4. **Plan Ahead:** Use due dates and time estimates for better scheduling
+
+## Keyboard Shortcuts
+
+### Navigation
+- **Tab:** Move focus between elements
+- **Enter:** Activate focused button or link
+- **Esc:** Close open dialogs or clear selections
+
+### Selection
+- **Space:** Select/deselect focused task
+- **Shift + Click:** Range selection
+- **Ctrl + Click:** Multi-selection (Cmd + Click on Mac)
+
+### Actions
+- **Delete:** Remove selected tasks (with confirmation)
+- **Ctrl + A:** Select all visible tasks (Cmd + A on Mac)
+
+## Troubleshooting
+
+### Common Issues
+
+#### Tasks Not Moving Between Groups
+- Ensure you have edit permissions for the tasks
+- Check that you're dragging from the drag handle (โฎโฎ icon)
+- Verify the target group allows the task type
+
+#### Bulk Actions Not Working
+- Confirm tasks are actually selected (checkboxes checked)
+- Ensure you have appropriate permissions
+- Check that the action is available for your current grouping
+
+#### Missing Task Information
+- Some metadata may be hidden on smaller screens
+- Try expanding to full screen or using desktop view
+- Check that task has the required information (assignees, labels, etc.)
+
+### Performance Tips
+- For projects with hundreds of tasks, consider using filters to reduce visible tasks
+- Collapse groups you're not actively working with
+- Clear selections when not performing bulk operations
+
+## Getting Help
+- Contact your workspace administrator for permission-related issues
+- Check the main WorkLenz documentation for general task management help
+- Report bugs or feature requests through your organization's support channels
+
+## What's New
+This enhanced task management system builds on WorkLenz's solid foundation while adding:
+- Modern drag-and-drop interfaces
+- Flexible grouping options
+- Powerful bulk operation capabilities
+- Rich visual task displays
+- Mobile-responsive design
+- Improved accessibility features
\ No newline at end of file
diff --git a/docs/recurring-tasks-user-guide.md b/docs/recurring-tasks-user-guide.md
new file mode 100644
index 00000000..3d91572a
--- /dev/null
+++ b/docs/recurring-tasks-user-guide.md
@@ -0,0 +1,60 @@
+# Recurring Tasks: User Guide
+
+## What Are Recurring Tasks?
+Recurring tasks are tasks that repeat automatically on a schedule you choose. This helps you save time and ensures important work is never forgotten. For example, you can set up a recurring task for weekly team meetings, monthly reports, or daily check-ins.
+
+## Why Use Recurring Tasks?
+- **Save time:** No need to create the same task over and over.
+- **Stay organized:** Tasks appear automatically when needed.
+- **Never miss a deadline:** Tasks are created on time, every time.
+
+## How to Set Up a Recurring Task
+1. Go to the tasks section in your workspace.
+2. Choose to create a new task and look for the option to make it recurring.
+3. Fill in the task details (name, description, assignees, etc.).
+4. Select your preferred schedule (see options below).
+5. Save the task. It will now be created automatically based on your chosen schedule.
+
+## Schedule Options
+You can choose how often your task repeats. Here are the available options:
+
+- **Daily:** The task is created every day.
+- **Weekly:** The task is created once a week. You can pick one or more days (e.g., every Monday and Thursday).
+- **Monthly:** The task is created once a month. You have two options:
+ - **On a specific date:** Choose a date from 1 to 28 (limited to 28 to ensure consistency across all months)
+ - **On a specific day:** Choose a week (first, second, third, fourth, or last) and a day of the week
+- **Every X Days:** The task is created every specified number of days (e.g., every 3 days)
+- **Every X Weeks:** The task is created every specified number of weeks (e.g., every 2 weeks)
+- **Every X Months:** The task is created every specified number of months (e.g., every 3 months)
+
+### Examples
+- "Send team update" every Friday (weekly)
+- "Submit expense report" on the 15th of each month (monthly, specific date)
+- "Monthly team meeting" on the first Monday of each month (monthly, specific day)
+- "Check backups" every day (daily)
+- "Review project status" every Monday and Thursday (weekly, multiple days)
+- "Quarterly report" every 3 months (every X months)
+
+## Future Task Creation
+The system automatically creates tasks up to a certain point in the future to ensure timely scheduling:
+
+- **Daily Tasks:** Created up to 7 days in advance
+- **Weekly Tasks:** Created up to 2 weeks in advance
+- **Monthly Tasks:** Created up to 2 months in advance
+- **Every X Days/Weeks/Months:** Created up to 2 intervals in advance
+
+This ensures that:
+- You always have upcoming tasks visible in your schedule
+- Tasks are created at appropriate intervals
+- The system maintains a reasonable number of future tasks
+
+## Tips
+- You can edit or stop a recurring task at any time.
+- Assign team members and labels to recurring tasks for better organization.
+- Check your task list regularly to see newly created recurring tasks.
+- For monthly tasks, dates are limited to 1-28 to ensure the task occurs on the same date every month.
+- Tasks are created automatically within the future limit window - you don't need to manually create them.
+- If you need to see tasks further in the future, they will be created automatically as the current tasks are completed.
+
+## Need Help?
+If you have questions or need help setting up recurring tasks, contact your workspace admin or support team.
\ No newline at end of file
diff --git a/docs/recurring-tasks.md b/docs/recurring-tasks.md
new file mode 100644
index 00000000..71448719
--- /dev/null
+++ b/docs/recurring-tasks.md
@@ -0,0 +1,104 @@
+# Recurring Tasks Cron Job Documentation
+
+## Overview
+The recurring tasks cron job automates the creation of tasks based on predefined templates and schedules. It ensures that tasks are generated at the correct intervals without manual intervention, supporting efficient project management and timely task assignment.
+
+## Purpose
+- Automatically create tasks according to recurring schedules defined in the database.
+- Prevent duplicate task creation for the same schedule and date.
+- Assign team members and labels to newly created tasks as specified in the template.
+
+## Scheduling Logic
+- The cron job is scheduled using the [cron](https://www.npmjs.com/package/cron) package.
+- The schedule is defined by a cron expression (e.g., `*/2 * * * *` for every 2 minutes, or `0 11 */1 * 1-5` for 11:00 UTC on weekdays).
+- On each tick, the job:
+ 1. Fetches all recurring task templates and their schedules.
+ 2. Determines the next occurrence for each template using `calculateNextEndDate`.
+ 3. Checks if a task for the next occurrence already exists.
+ 4. Creates a new task if it does not exist and the next occurrence is within the allowed future window.
+
+## Future Limit Logic
+The system implements different future limits based on the schedule type to maintain an appropriate number of future tasks:
+
+```typescript
+const FUTURE_LIMITS = {
+ daily: moment.duration(7, 'days'),
+ weekly: moment.duration(2, 'weeks'),
+ monthly: moment.duration(2, 'months'),
+ every_x_days: (interval: number) => moment.duration(interval * 2, 'days'),
+ every_x_weeks: (interval: number) => moment.duration(interval * 2, 'weeks'),
+ every_x_months: (interval: number) => moment.duration(interval * 2, 'months')
+};
+```
+
+### Implementation Details
+- **Base Calculation:**
+ ```typescript
+ const futureLimit = moment(template.last_checked_at || template.created_at)
+ .add(getFutureLimit(schedule.schedule_type, schedule.interval), 'days');
+ ```
+
+- **Task Creation Rules:**
+ 1. Only create tasks if the next occurrence is before the future limit
+ 2. Skip creation if a task already exists for that date
+ 3. Update `last_checked_at` after processing
+
+- **Benefits:**
+ - Prevents excessive task creation
+ - Maintains system performance
+ - Ensures timely task visibility
+ - Allows for schedule modifications
+
+## Date Handling
+- **Monthly Tasks:**
+ - Dates are limited to 1-28 to ensure consistency across all months
+ - This prevents issues with months having different numbers of days
+ - No special handling needed for February or months with 30/31 days
+- **Weekly Tasks:**
+ - Supports multiple days of the week (0-6, where 0 is Sunday)
+ - Tasks are created for each selected day
+- **Interval-based Tasks:**
+ - Every X days/weeks/months from the last task's end date
+ - Minimum interval is 1 day/week/month
+ - No maximum limit, but tasks are only created up to the future limit
+
+## Database Interactions
+- **Templates and Schedules:**
+ - Templates are stored in `task_recurring_templates`.
+ - Schedules are stored in `task_recurring_schedules`.
+ - The job joins these tables to get all necessary data for task creation.
+- **Task Creation:**
+ - Uses a stored procedure `create_quick_task` to insert new tasks.
+ - Assigns team members and labels by calling appropriate functions/controllers.
+- **State Tracking:**
+ - Updates `last_checked_at` and `last_created_task_end_date` in the schedule after processing.
+ - Maintains future limits based on schedule type.
+
+## Task Creation Process
+1. **Fetch Templates:** Retrieve all templates and their associated schedules.
+2. **Determine Next Occurrence:** Use the last task's end date or the schedule's creation date to calculate the next due date.
+3. **Check for Existing Task:** Ensure no duplicate task is created for the same schedule and date.
+4. **Create Task:**
+ - Insert the new task using the template's data.
+ - Assign team members and labels as specified.
+5. **Update Schedule:** Record the last checked and created dates for accurate future runs.
+
+## Configuration & Extension Points
+- **Cron Expression:** Modify the `TIME` constant in the code to change the schedule.
+- **Task Template Structure:** Extend the template or schedule interfaces to support additional fields.
+- **Task Creation Logic:** Customize the task creation process or add new assignment/labeling logic as needed.
+- **Future Window:** Adjust the future limits by modifying the `FUTURE_LIMITS` configuration.
+
+## Error Handling
+- Errors are logged using the `log_error` utility.
+- The job continues processing other templates even if one fails.
+- Failed task creations are not retried automatically.
+
+## References
+- Source: `src/cron_jobs/recurring-tasks.ts`
+- Utilities: `src/shared/utils.ts`
+- Database: `src/config/db.ts`
+- Controllers: `src/controllers/tasks-controller.ts`
+
+---
+For further customization or troubleshooting, refer to the source code and update the documentation as needed.
\ No newline at end of file
diff --git a/docs/task-progress-guide-for-users.md b/docs/task-progress-guide-for-users.md
new file mode 100644
index 00000000..1eeb15c1
--- /dev/null
+++ b/docs/task-progress-guide-for-users.md
@@ -0,0 +1,223 @@
+# WorkLenz Task Progress Guide for Users
+
+## Introduction
+WorkLenz offers three different ways to track and calculate task progress, each designed for different project management needs. This guide explains how each method works and when to use them.
+
+## Default Progress Method
+
+WorkLenz uses a simple completion-based approach as the default progress calculation method. This method is applied when no special progress methods are enabled.
+
+### Example
+
+If you have a parent task with four subtasks and two of the subtasks are marked complete:
+- Parent task: Not done
+- 2 subtasks: Done
+- 2 subtasks: Not done
+
+The parent task will show as 40% complete (2 completed out of 5 total tasks).
+
+## Available Progress Tracking Methods
+
+WorkLenz provides these progress tracking methods:
+
+1. **Manual Progress** - Directly input progress percentages for tasks
+2. **Weighted Progress** - Assign importance levels (weights) to tasks
+3. **Time-based Progress** - Calculate progress based on estimated time
+
+Only one method can be enabled at a time for a project. If none are enabled, progress will be calculated based on task completion status.
+
+## How to Select a Progress Method
+
+1. Open the project drawer by clicking on the project settings icon or creating a new project
+2. In the project settings, find the "Progress Calculation Method" section
+3. Select your preferred method
+4. Save your changes
+
+## Manual Progress Method
+
+### How It Works
+
+- You directly enter progress percentages (0-100%) for tasks without subtasks
+- Parent task progress is calculated as the average of all subtask progress values
+- Progress is updated in real-time as you adjust values
+
+### When to Use Manual Progress
+
+- For creative or subjective work where completion can't be measured objectively
+- When task progress doesn't follow a linear path
+- For projects where team members need flexibility in reporting progress
+
+### Example
+
+If you have a parent task with three subtasks:
+- Subtask A: 30% complete
+- Subtask B: 60% complete
+- Subtask C: 90% complete
+
+The parent task will show as 60% complete (average of 30%, 60%, and 90%).
+
+## Weighted Progress Method
+
+### How It Works
+
+- You assign "weight" values to tasks to indicate their importance
+- More important tasks have higher weights and influence the overall progress more
+- You still enter manual progress percentages for tasks without subtasks
+- Parent task progress is calculated using a weighted average
+
+### When to Use Weighted Progress
+
+- When some tasks are more important or time-consuming than others
+- For projects where all tasks aren't equal
+- When you want key deliverables to have more impact on overall progress
+
+### Example
+
+If you have a parent task with three subtasks:
+- Subtask A: 50% complete, Weight 60% (important task)
+- Subtask B: 75% complete, Weight 20% (less important task)
+- Subtask C: 25% complete, Weight 100% (critical task)
+
+The parent task will be approximately 39% complete, with Subtask C having the greatest impact due to its higher weight.
+
+### Important Notes About Weights
+
+- Default weight is 100% if not specified
+- Weights range from 0% to 100%
+- Setting a weight to 0% removes that task from progress calculations
+- Only explicitly set weights for tasks that should have different importance
+- Weights are only relevant for subtasks, not for independent tasks
+
+### Detailed Weighted Progress Calculation Example
+
+To understand how weighted progress works with different weight values, consider this example:
+
+For a parent task with two subtasks:
+- Subtask A: 80% complete, Weight 50%
+- Subtask B: 40% complete, Weight 100%
+
+The calculation works as follows:
+
+1. Each subtask's contribution is: (weight ร progress) รท (sum of all weights)
+2. For Subtask A: (50 ร 80%) รท (50 + 100) = 26.7%
+3. For Subtask B: (100 ร 40%) รท (50 + 100) = 26.7%
+4. Total parent progress: 26.7% + 26.7% = 53.3%
+
+The parent task would be approximately 53% complete.
+
+This shows how the subtask with twice the weight (Subtask B) has twice the influence on the overall progress calculation, even though it has a lower completion percentage.
+
+## Time-based Progress Method
+
+### How It Works
+
+- Use the task's time estimate as its "weight" in the progress calculation
+- You still enter manual progress percentages for tasks without subtasks
+- Tasks with longer time estimates have more influence on overall progress
+- Parent task progress is calculated based on time-weighted averages
+
+### When to Use Time-based Progress
+
+- For projects with well-defined time estimates
+- When task importance correlates with its duration
+- For billing or time-tracking focused projects
+- When you already maintain accurate time estimates
+
+### Example
+
+If you have a parent task with three subtasks:
+- Subtask A: 40% complete, Estimated Time 2.5 hours
+- Subtask B: 80% complete, Estimated Time 1 hour
+- Subtask C: 10% complete, Estimated Time 4 hours
+
+The parent task will be approximately 29% complete, with the lengthy Subtask C pulling down the overall progress despite Subtask B being mostly complete.
+
+### Important Notes About Time Estimates
+
+- Tasks without time estimates don't influence progress calculations
+- Time is converted to minutes internally (a 2-hour task = 120 minutes)
+- Setting a time estimate to 0 removes that task from progress calculations
+- Time estimates serve dual purposes: scheduling/resource planning and progress weighting
+
+### Detailed Time-based Progress Calculation Example
+
+To understand how time-based progress works with different time estimates, consider this example:
+
+For a parent task with three subtasks:
+- Subtask A: 40% complete, Estimated Time 2.5 hours
+- Subtask B: 80% complete, Estimated Time 1 hour
+- Subtask C: 10% complete, Estimated Time 4 hours
+
+The calculation works as follows:
+
+1. Convert hours to minutes: A = 150 min, B = 60 min, C = 240 min
+2. Total estimated time: 150 + 60 + 240 = 450 minutes
+3. Each subtask's contribution is: (time estimate ร progress) รท (total time)
+4. For Subtask A: (150 ร 40%) รท 450 = 13.3%
+5. For Subtask B: (60 ร 80%) รท 450 = 10.7%
+6. For Subtask C: (240 ร 10%) รท 450 = 5.3%
+7. Total parent progress: 13.3% + 10.7% + 5.3% = 29.3%
+
+The parent task would be approximately 29% complete.
+
+This demonstrates how tasks with longer time estimates (like Subtask C) have more influence on the overall progress calculation. Even though Subtask B is 80% complete, its shorter time estimate means it contributes less to the overall progress than the partially-completed but longer Subtask A.
+
+### How It Works
+
+- Tasks are either 0% (not done) or 100% (done)
+- Parent task progress = (completed tasks / total tasks) ร 100%
+- Both the parent task and all subtasks count in this calculation
+
+### When to Use Default Progress
+
+- For simple projects with clear task completion criteria
+- When binary task status (done/not done) is sufficient
+- For teams new to project management who want simplicity
+
+### Example
+
+If you have a parent task with four subtasks and two of the subtasks are marked complete:
+- Parent task: Not done
+- 2 subtasks: Done
+- 2 subtasks: Not done
+
+The parent task will show as 40% complete (2 completed out of 5 total tasks).
+
+## Best Practices
+
+1. **Choose the Right Method for Your Project**
+ - Consider your team's workflow and reporting needs
+ - Match the method to your project's complexity
+
+2. **Be Consistent**
+ - Stick with one method throughout the project
+ - Changing methods mid-project can cause confusion
+
+3. **For Manual Progress**
+ - Update progress regularly
+ - Establish guidelines for progress reporting
+
+4. **For Weighted Progress**
+ - Assign weights based on objective criteria
+ - Don't overuse extreme weights
+
+5. **For Time-based Progress**
+ - Keep time estimates accurate and up to date
+ - Consider using time tracking to validate estimates
+
+## Frequently Asked Questions
+
+**Q: Can I change the progress method mid-project?**
+A: Yes, but it may cause progress values to change significantly. It's best to select a method at the project start.
+
+**Q: What happens to task progress when I mark a task complete?**
+A: When a task is marked complete, its progress automatically becomes 100%, regardless of the progress method.
+
+**Q: How do I enter progress for a task?**
+A: Open the task drawer, go to the Info tab, and use the progress slider for tasks without subtasks.
+
+**Q: Can different projects use different progress methods?**
+A: Yes, each project can have its own progress method.
+
+**Q: What if I don't see progress fields in my task drawer?**
+A: Progress input is only visible for tasks without subtasks. Parent tasks' progress is automatically calculated.
\ No newline at end of file
diff --git a/docs/task-progress-methods.md b/docs/task-progress-methods.md
new file mode 100644
index 00000000..b931b7f5
--- /dev/null
+++ b/docs/task-progress-methods.md
@@ -0,0 +1,550 @@
+# Task Progress Tracking Methods in WorkLenz
+
+## Overview
+WorkLenz supports three different methods for tracking task progress, each suitable for different project management approaches:
+
+1. **Manual Progress** - Direct input of progress percentages
+2. **Weighted Progress** - Tasks have weights that affect overall progress calculation
+3. **Time-based Progress** - Progress calculated based on estimated time vs. time spent
+
+These modes can be selected when creating or editing a project in the project drawer. Only one progress method can be enabled at a time. If none of these methods are enabled, progress will be calculated based on task completion status as described in the "Default Progress Tracking" section below.
+
+## 1. Manual Progress Mode
+
+This mode allows direct input of progress percentages for individual tasks without subtasks.
+
+**Implementation:**
+- Enabled by setting `use_manual_progress` to true in the project settings
+- Progress is updated through the `on-update-task-progress.ts` socket event handler
+- The UI shows a manual progress input slider in the task drawer for tasks without subtasks
+- Updates the database with `progress_value` and sets `manual_progress` flag to true
+
+**Calculation Logic:**
+- For tasks without subtasks: Uses the manually set progress value
+- For parent tasks: Calculates the average of all subtask progress values
+- Subtask progress comes from either manual values or completion status (0% or 100%)
+
+**Code Example:**
+```typescript
+// Manual progress update via socket.io
+socket?.emit(SocketEvents.UPDATE_TASK_PROGRESS.toString(), JSON.stringify({
+ task_id: task.id,
+ progress_value: value,
+ parent_task_id: task.parent_task_id
+}));
+```
+
+## 2. Weighted Progress Mode
+
+This mode allows assigning different weights to subtasks to reflect their relative importance in the overall task or project progress.
+
+**Implementation:**
+- Enabled by setting `use_weighted_progress` to true in the project settings
+- Weights are updated through the `on-update-task-weight.ts` socket event handler
+- The UI shows a weight input for subtasks in the task drawer
+- Manual progress input is still required for tasks without subtasks
+- Default weight is 100 if not specified
+- Weight values range from 0 to 100%
+
+**Calculation Logic:**
+- For tasks without subtasks: Uses the manually entered progress value
+- Progress is calculated using a weighted average: `SUM(progress_value * weight) / SUM(weight)`
+- This gives more influence to tasks with higher weights
+- A parent task's progress is the weighted average of its subtasks' progress values
+
+**Code Example:**
+```typescript
+// Weight update via socket.io
+socket?.emit(SocketEvents.UPDATE_TASK_WEIGHT.toString(), JSON.stringify({
+ task_id: task.id,
+ weight: value,
+ parent_task_id: task.parent_task_id
+}));
+```
+
+## 3. Time-based Progress Mode
+
+This mode calculates progress based on estimated time vs. actual time spent.
+
+**Implementation:**
+- Enabled by setting `use_time_progress` to true in the project settings
+- Uses task time estimates (hours and minutes) for calculation
+- Manual progress input is still required for tasks without subtasks
+- No separate socket handler needed as it's calculated automatically
+
+**Calculation Logic:**
+- For tasks without subtasks: Uses the manually entered progress value
+- Progress is calculated using time as the weight: `SUM(progress_value * estimated_minutes) / SUM(estimated_minutes)`
+- For tasks with time tracking, estimated vs. actual time can be factored in
+- Parent task progress is weighted by the estimated time of each subtask
+
+**SQL Example:**
+```sql
+WITH subtask_progress AS (
+ SELECT
+ CASE
+ WHEN manual_progress IS TRUE AND progress_value IS NOT NULL THEN
+ progress_value
+ ELSE
+ CASE
+ WHEN EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) THEN 100
+ ELSE 0
+ END
+ END AS progress_value,
+ COALESCE(total_hours * 60 + total_minutes, 0) AS estimated_minutes
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+)
+SELECT COALESCE(
+ SUM(progress_value * estimated_minutes) / NULLIF(SUM(estimated_minutes), 0),
+ 0
+)
+FROM subtask_progress
+INTO _ratio;
+```
+
+## Default Progress Tracking (when no special mode is selected)
+
+If no specific progress mode is enabled, the system falls back to a traditional completion-based calculation:
+
+**Implementation:**
+- Default mode when all three special modes are disabled
+- Based on task completion status only
+
+**Calculation Logic:**
+- For tasks without subtasks: 0% if not done, 100% if done
+- For parent tasks: `(completed_tasks / total_tasks) * 100`
+- Counts both the parent and all subtasks in the calculation
+
+**SQL Example:**
+```sql
+-- Traditional calculation based on completion status
+SELECT (CASE
+ WHEN EXISTS(SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = _task_id
+ AND is_done IS TRUE) THEN 1
+ ELSE 0 END)
+INTO _parent_task_done;
+
+SELECT COUNT(*)
+FROM tasks_with_status_view
+WHERE parent_task_id = _task_id
+ AND is_done IS TRUE
+INTO _sub_tasks_done;
+
+_total_completed = _parent_task_done + _sub_tasks_done;
+_total_tasks = _sub_tasks_count + 1; -- +1 for the parent task
+
+IF _total_tasks = 0 THEN
+ _ratio = 0;
+ELSE
+ _ratio = (_total_completed / _total_tasks) * 100;
+END IF;
+```
+
+## Technical Implementation Details
+
+The progress calculation logic is implemented in PostgreSQL functions, primarily in the `get_task_complete_ratio` function. Progress updates flow through the system as follows:
+
+1. **User Action**: User updates task progress or weight in the UI
+2. **Socket Event**: Client emits socket event (UPDATE_TASK_PROGRESS or UPDATE_TASK_WEIGHT)
+3. **Server Handler**: Server processes the event in the respective handler function
+4. **Database Update**: Progress/weight value is updated in the database
+5. **Recalculation**: If needed, parent task progress is recalculated
+6. **Broadcast**: Changes are broadcast to all clients in the project room
+7. **UI Update**: Client UI updates to reflect the new progress values
+
+This architecture allows for real-time updates and consistent progress calculation across all clients.
+
+## Manual Progress Input Implementation
+
+Regardless of which progress tracking method is selected for a project, tasks without subtasks (leaf tasks) require manual progress input. This section details how manual progress input is implemented and used across all progress tracking methods.
+
+### UI Component
+
+The manual progress input component is implemented in `worklenz-frontend/src/components/task-drawer/shared/info-tab/details/task-drawer-progress/task-drawer-progress.tsx` and includes:
+
+1. **Progress Slider**: A slider UI control that allows users to set progress values from 0% to 100%
+2. **Progress Input Field**: A numeric input field that accepts direct entry of progress percentage
+3. **Progress Display**: Visual representation of the current progress value
+
+The component is conditionally rendered in the task drawer for tasks that don't have subtasks.
+
+**Usage Across Progress Methods:**
+- In **Manual Progress Mode**: Only the progress slider/input is shown
+- In **Weighted Progress Mode**: Both the progress slider/input and weight input are shown
+- In **Time-based Progress Mode**: The progress slider/input is shown alongside time estimate fields
+
+### Progress Update Flow
+
+When a user updates a task's progress manually, the following process occurs:
+
+1. **User Input**: User adjusts the progress slider or enters a value in the input field
+2. **UI Event Handler**: The UI component captures the change event and validates the input
+3. **Socket Event Emission**: The component emits a `UPDATE_TASK_PROGRESS` socket event with:
+ ```typescript
+ {
+ task_id: task.id,
+ progress_value: value, // The new progress value (0-100)
+ parent_task_id: task.parent_task_id // For recalculation
+ }
+ ```
+4. **Server Processing**: The socket event handler on the server:
+ - Updates the task's `progress_value` in the database
+ - Sets the `manual_progress` flag to true
+ - Triggers recalculation of parent task progress
+
+### Progress Calculation Across Methods
+
+The calculation of progress differs based on the active progress method:
+
+1. **For Leaf Tasks (no subtasks)** in all methods:
+ - Progress is always the manually entered value (`progress_value`)
+ - If the task is marked as completed, progress is automatically set to 100%
+
+2. **For Parent Tasks**:
+ - **Manual Progress Mode**: Simple average of all subtask progress values
+ - **Weighted Progress Mode**: Weighted average where each subtask's progress is multiplied by its weight
+ - **Time-based Progress Mode**: Weighted average where each subtask's progress is multiplied by its estimated time
+ - **Default Mode**: Percentage of completed tasks (including parent) vs. total tasks
+
+### Detailed Calculation for Weighted Progress Method
+
+In Weighted Progress mode, both the manual progress input and weight assignment are critical components:
+
+1. **Manual Progress Input**:
+ - For leaf tasks (without subtasks), users must manually input progress percentages (0-100%)
+ - If a leaf task is marked as complete, its progress is automatically set to 100%
+ - If a leaf task's progress is not manually set, it defaults to 0% (or 100% if completed)
+
+2. **Weight Assignment**:
+ - Each task can be assigned a weight value between 0-100% (default 100% if not specified)
+ - Higher weight values give tasks more influence in parent task progress calculations
+ - A weight of 0% means the task doesn't contribute to the parent's progress calculation
+
+3. **Parent Task Calculation**:
+ The weighted progress formula is:
+ ```
+ ParentProgress = โ(SubtaskProgress * SubtaskWeight) / โ(SubtaskWeight)
+ ```
+
+ **Example Calculation**:
+ Consider a parent task with three subtasks:
+ - Subtask A: Progress 50%, Weight 60%
+ - Subtask B: Progress 75%, Weight 20%
+ - Subtask C: Progress 25%, Weight 100%
+
+ Calculation:
+ ```
+ ParentProgress = ((50 * 60) + (75 * 20) + (25 * 100)) / (60 + 20 + 100)
+ ParentProgress = (3000 + 1500 + 2500) / 180
+ ParentProgress = 7000 / 180
+ ParentProgress = 38.89%
+ ```
+
+ Notice that Subtask C, despite having the lowest progress, has a significant impact on the parent task progress due to its higher weight.
+
+4. **Zero Weight Handling**:
+ Tasks with zero weight are excluded from the calculation:
+ - Subtask A: Progress 40%, Weight 50%
+ - Subtask B: Progress 80%, Weight 0%
+
+ Calculation:
+ ```
+ ParentProgress = ((40 * 50) + (80 * 0)) / (50 + 0)
+ ParentProgress = 2000 / 50
+ ParentProgress = 40%
+ ```
+
+ In this case, only Subtask A influences the parent task progress because Subtask B has a weight of 0%.
+
+5. **Default Weight Behavior**:
+ When weights aren't explicitly assigned to some tasks:
+ - Subtask A: Progress 30%, Weight 60% (explicitly set)
+ - Subtask B: Progress 70%, Weight not set (defaults to 100%)
+ - Subtask C: Progress 90%, Weight not set (defaults to 100%)
+
+ Calculation:
+ ```
+ ParentProgress = ((30 * 60) + (70 * 100) + (90 * 100)) / (60 + 100 + 100)
+ ParentProgress = (1800 + 7000 + 9000) / 260
+ ParentProgress = 17800 / 260
+ ParentProgress = 68.46%
+ ```
+
+ Note that Subtasks B and C have more influence than Subtask A because they have higher default weights.
+
+6. **All Zero Weights Edge Case**:
+ If all subtasks have zero weight, the progress is calculated as 0%:
+ ```
+ ParentProgress = SUM(progress_value * 0) / SUM(0) = 0 / 0 = undefined
+ ```
+
+ The SQL implementation handles this with `NULLIF` and `COALESCE` to return 0% in this case.
+
+4. **Actual SQL Implementation**:
+ The database function implements the weighted calculation as follows:
+ ```sql
+ WITH subtask_progress AS (
+ SELECT
+ CASE
+ -- If subtask has manual progress, use that value
+ WHEN manual_progress IS TRUE AND progress_value IS NOT NULL THEN
+ progress_value
+ -- Otherwise use completion status (0 or 100)
+ ELSE
+ CASE
+ WHEN EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) THEN 100
+ ELSE 0
+ END
+ END AS progress_value,
+ COALESCE(weight, 100) AS weight
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ )
+ SELECT COALESCE(
+ SUM(progress_value * weight) / NULLIF(SUM(weight), 0),
+ 0
+ )
+ FROM subtask_progress
+ INTO _ratio;
+ ```
+
+ This SQL implementation:
+ - Gets all non-archived subtasks of the parent task
+ - For each subtask, determines its progress value:
+ - If manual progress is set, uses that value
+ - Otherwise, uses 100% if the task is done or 0% if not done
+ - Uses COALESCE to default weight to 100 if not specified
+ - Calculates the weighted average, handling the case where sum of weights might be zero
+ - Returns 0 if there are no subtasks with weights
+
+### Detailed Calculation for Time-based Progress Method
+
+In Time-based Progress mode, the task's estimated time serves as its weight in progress calculations:
+
+1. **Manual Progress Input**:
+ - As with weighted progress, leaf tasks require manual progress input
+ - Progress is entered as a percentage (0-100%)
+ - Completed tasks are automatically set to 100% progress
+
+2. **Time Estimation**:
+ - Each task has an estimated time in hours and minutes
+ - These values are stored in `total_hours` and `total_minutes` fields
+ - Time estimates effectively function as weights in progress calculations
+ - Tasks with longer estimated durations have more influence on parent task progress
+ - Tasks with zero or no time estimate don't contribute to the parent's progress calculation
+
+3. **Parent Task Calculation**:
+ The time-based progress formula is:
+ ```
+ ParentProgress = โ(SubtaskProgress * SubtaskEstimatedMinutes) / โ(SubtaskEstimatedMinutes)
+ ```
+ where `SubtaskEstimatedMinutes = (SubtaskHours * 60) + SubtaskMinutes`
+
+ **Example Calculation**:
+ Consider a parent task with three subtasks:
+ - Subtask A: Progress 40%, Estimated Time 2h 30m (150 minutes)
+ - Subtask B: Progress 80%, Estimated Time 1h (60 minutes)
+ - Subtask C: Progress 10%, Estimated Time 4h (240 minutes)
+
+ Calculation:
+ ```
+ ParentProgress = ((40 * 150) + (80 * 60) + (10 * 240)) / (150 + 60 + 240)
+ ParentProgress = (6000 + 4800 + 2400) / 450
+ ParentProgress = 13200 / 450
+ ParentProgress = 29.33%
+ ```
+
+ Note how Subtask C, with its large time estimate, significantly pulls down the overall progress despite Subtask B being mostly complete.
+
+4. **Zero Time Estimate Handling**:
+ Tasks with zero time estimate are excluded from the calculation:
+ - Subtask A: Progress 40%, Estimated Time 3h (180 minutes)
+ - Subtask B: Progress 80%, Estimated Time 0h (0 minutes)
+
+ Calculation:
+ ```
+ ParentProgress = ((40 * 180) + (80 * 0)) / (180 + 0)
+ ParentProgress = 7200 / 180
+ ParentProgress = 40%
+ ```
+
+ In this case, only Subtask A influences the parent task progress because Subtask B has no time estimate.
+
+5. **All Zero Time Estimates Edge Case**:
+ If all subtasks have zero time estimates, the progress is calculated as 0%:
+ ```
+ ParentProgress = SUM(progress_value * 0) / SUM(0) = 0 / 0 = undefined
+ ```
+
+ The SQL implementation handles this with `NULLIF` and `COALESCE` to return 0% in this case.
+
+6. **Actual SQL Implementation**:
+ The SQL function for this calculation first converts hours to minutes for consistent measurement:
+ ```sql
+ WITH subtask_progress AS (
+ SELECT
+ CASE
+ -- If subtask has manual progress, use that value
+ WHEN manual_progress IS TRUE AND progress_value IS NOT NULL THEN
+ progress_value
+ -- Otherwise use completion status (0 or 100)
+ ELSE
+ CASE
+ WHEN EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) THEN 100
+ ELSE 0
+ END
+ END AS progress_value,
+ COALESCE(total_hours * 60 + total_minutes, 0) AS estimated_minutes
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ )
+ SELECT COALESCE(
+ SUM(progress_value * estimated_minutes) / NULLIF(SUM(estimated_minutes), 0),
+ 0
+ )
+ FROM subtask_progress
+ INTO _ratio;
+ ```
+
+ This implementation:
+ - Gets all non-archived subtasks of the parent task
+ - Determines each subtask's progress value (manual or completion-based)
+ - Calculates total minutes by converting hours to minutes and adding them together
+ - Uses COALESCE to treat NULL time estimates as 0 minutes
+ - Uses NULLIF to handle cases where all time estimates are zero
+ - Returns 0% progress if there are no subtasks with time estimates
+
+### Common Implementation Considerations
+
+For both weighted and time-based progress calculation:
+
+1. **Null Handling**:
+ - Tasks with NULL progress values are treated as 0% progress (unless completed)
+ - Tasks with NULL weights default to 100 in weighted mode
+ - Tasks with NULL time estimates are treated as 0 minutes in time-based mode
+
+2. **Progress Propagation**:
+ - When a leaf task's progress changes, all ancestor tasks are recalculated
+ - Progress updates are propagated through socket events to all connected clients
+ - The recalculation happens server-side to ensure consistency
+
+3. **Edge Cases**:
+ - If all subtasks have zero weight/time, the system falls back to a simple average
+ - If a parent task has no subtasks, its own manual progress value is used
+ - If a task is archived, it's excluded from parent task calculations
+
+### Database Implementation
+
+The manual progress value is stored in the `tasks` table with these relevant fields:
+
+```sql
+tasks (
+ -- other fields
+ progress_value FLOAT, -- The manually entered progress value (0-100)
+ manual_progress BOOLEAN, -- Flag indicating if progress was manually set
+ weight INTEGER DEFAULT 100, -- For weighted progress calculation
+ total_hours INTEGER, -- For time-based progress calculation
+ total_minutes INTEGER -- For time-based progress calculation
+)
+```
+
+### Integration with Parent Task Calculation
+
+When a subtask's progress is updated manually, the parent task's progress is automatically recalculated based on the active progress method:
+
+```typescript
+// Pseudocode for parent task recalculation
+function recalculateParentTaskProgress(taskId, parentTaskId) {
+ if (!parentTaskId) return;
+
+ // Get project settings to determine active progress method
+ const project = getProjectByTaskId(taskId);
+
+ if (project.use_manual_progress) {
+ // Calculate average of all subtask progress values
+ updateParentProgress(parentTaskId, calculateAverageProgress(parentTaskId));
+ }
+ else if (project.use_weighted_progress) {
+ // Calculate weighted average using subtask weights
+ updateParentProgress(parentTaskId, calculateWeightedProgress(parentTaskId));
+ }
+ else if (project.use_time_progress) {
+ // Calculate weighted average using time estimates
+ updateParentProgress(parentTaskId, calculateTimeBasedProgress(parentTaskId));
+ }
+ else {
+ // Default: Calculate based on task completion
+ updateParentProgress(parentTaskId, calculateCompletionBasedProgress(parentTaskId));
+ }
+
+ // If this parent has a parent, continue recalculation up the tree
+ const grandparentId = getParentTaskId(parentTaskId);
+ if (grandparentId) {
+ recalculateParentTaskProgress(parentTaskId, grandparentId);
+ }
+}
+```
+
+This recursive approach ensures that changes to any task's progress are properly propagated up the task hierarchy.
+
+## Associated Files and Components
+
+### Backend Files
+
+1. **Socket Event Handlers**:
+ - `worklenz-backend/src/socket.io/commands/on-update-task-progress.ts` - Handles manual progress updates
+ - `worklenz-backend/src/socket.io/commands/on-update-task-weight.ts` - Handles task weight updates
+
+2. **Database Functions**:
+ - `worklenz-backend/database/migrations/20250423000000-subtask-manual-progress.sql` - Contains the `get_task_complete_ratio` function that calculates progress based on the selected method
+ - Functions that support project creation/updates with progress mode settings:
+ - `create_project`
+ - `update_project`
+
+3. **Controllers**:
+ - `worklenz-backend/src/controllers/project-workload/workload-gannt-base.ts` - Contains the `calculateTaskCompleteRatio` method
+ - `worklenz-backend/src/controllers/projects-controller.ts` - Handles project-level progress calculations
+
+### Frontend Files
+
+1. **Project Configuration**:
+ - `worklenz-frontend/src/components/projects/project-drawer/project-drawer.tsx` - Contains UI for selecting progress method when creating/editing projects
+
+2. **Progress Visualization Components**:
+ - `worklenz-frontend/src/components/project-list/project-list-table/project-list-progress/progress-list-progress.tsx` - Displays project progress
+ - `worklenz-frontend/src/pages/projects/project-view-1/taskList/taskListTable/taskListTableCells/TaskProgress.tsx` - Displays task progress
+ - `worklenz-frontend/src/pages/projects/projectView/taskList/task-list-table/task-list-table-cells/task-list-progress-cell/task-list-progress-cell.tsx` - Alternative task progress cell
+
+3. **Progress Input Components**:
+ - `worklenz-frontend/src/components/task-drawer/shared/info-tab/details/task-drawer-progress/task-drawer-progress.tsx` - Component for inputting task progress/weight
+
+## Choosing the Right Progress Method
+
+Each progress method is suitable for different types of projects:
+
+- **Manual Progress**: Best for creative work where progress is subjective
+- **Weighted Progress**: Ideal for projects where some tasks are more significant than others
+- **Time-based Progress**: Perfect for projects where time estimates are reliable and important
+
+Project managers can choose the appropriate method when creating or editing a project in the project drawer, based on their team's workflow and project requirements.
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..57245686
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,6 @@
+{
+ "name": "worklenz",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {}
+}
diff --git a/task-progress-methods.md b/task-progress-methods.md
new file mode 100644
index 00000000..11b18ef5
--- /dev/null
+++ b/task-progress-methods.md
@@ -0,0 +1,244 @@
+# Task Progress Tracking Methods in WorkLenz
+
+## Overview
+WorkLenz supports three different methods for tracking task progress, each suitable for different project management approaches:
+
+1. **Manual Progress** - Direct input of progress percentages
+2. **Weighted Progress** - Tasks have weights that affect overall progress calculation
+3. **Time-based Progress** - Progress calculated based on estimated time vs. time spent
+
+These modes can be selected when creating or editing a project in the project drawer.
+
+## 1. Manual Progress Mode
+
+This mode allows direct input of progress percentages for individual tasks without subtasks.
+
+**Implementation:**
+- Enabled by setting `use_manual_progress` to true in the project settings
+- Progress is updated through the `on-update-task-progress.ts` socket event handler
+- The UI shows a manual progress input slider in the task drawer for tasks without subtasks
+- Updates the database with `progress_value` and sets `manual_progress` flag to true
+
+**Calculation Logic:**
+- For tasks without subtasks: Uses the manually set progress value
+- For parent tasks: Calculates the average of all subtask progress values
+- Subtask progress comes from either manual values or completion status (0% or 100%)
+
+**Code Example:**
+```typescript
+// Manual progress update via socket.io
+socket?.emit(SocketEvents.UPDATE_TASK_PROGRESS.toString(), JSON.stringify({
+ task_id: task.id,
+ progress_value: value,
+ parent_task_id: task.parent_task_id
+}));
+```
+
+### Showing Progress in Subtask Rows
+
+When manual progress is enabled in a project, progress is shown in the following ways:
+
+1. **In Task List Views**:
+ - Subtasks display their individual progress values in the progress column
+ - Parent tasks display the calculated average progress of all subtasks
+
+2. **Implementation Details**:
+ - The progress values are stored in the `progress_value` column in the database
+ - For subtasks with manual progress set, the value is shown directly
+ - For subtasks without manual progress, the completion status determines the value (0% or 100%)
+ - The task view model includes both `progress` and `complete_ratio` properties
+
+**Relevant Components:**
+```typescript
+// From task-list-progress-cell.tsx
+const TaskListProgressCell = ({ task }: TaskListProgressCellProps) => {
+ return task.is_sub_task ? null : (
+
+
+
+ );
+};
+```
+
+**Task Progress Calculation in Backend:**
+```typescript
+// From tasks-controller-base.ts
+// For tasks without subtasks, respect manual progress if set
+if (task.manual_progress === true && task.progress_value !== null) {
+ // For manually set progress, use that value directly
+ task.progress = parseInt(task.progress_value);
+ task.complete_ratio = parseInt(task.progress_value);
+}
+```
+
+## 2. Weighted Progress Mode
+
+This mode allows assigning different weights to subtasks to reflect their relative importance in the overall task or project progress.
+
+**Implementation:**
+- Enabled by setting `use_weighted_progress` to true in the project settings
+- Weights are updated through the `on-update-task-weight.ts` socket event handler
+- The UI shows a weight input for subtasks in the task drawer
+- Default weight is 100 if not specified
+
+**Calculation Logic:**
+- Progress is calculated using a weighted average: `SUM(progress_value * weight) / SUM(weight)`
+- This gives more influence to tasks with higher weights
+- A parent task's progress is the weighted average of its subtasks' progress
+
+**Code Example:**
+```typescript
+// Weight update via socket.io
+socket?.emit(SocketEvents.UPDATE_TASK_WEIGHT.toString(), JSON.stringify({
+ task_id: task.id,
+ weight: value,
+ parent_task_id: task.parent_task_id
+}));
+```
+
+## 3. Time-based Progress Mode
+
+This mode calculates progress based on estimated time vs. actual time spent.
+
+**Implementation:**
+- Enabled by setting `use_time_progress` to true in the project settings
+- Uses task time estimates (hours and minutes) for calculation
+- No separate socket handler needed as it's calculated automatically
+
+**Calculation Logic:**
+- Progress is calculated using time as the weight: `SUM(progress_value * estimated_minutes) / SUM(estimated_minutes)`
+- For tasks with time tracking, estimated vs. actual time can be factored in
+- Parent task progress is weighted by the estimated time of each subtask
+
+**SQL Example:**
+```sql
+WITH subtask_progress AS (
+ SELECT
+ CASE
+ WHEN manual_progress IS TRUE AND progress_value IS NOT NULL THEN
+ progress_value
+ ELSE
+ CASE
+ WHEN EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) THEN 100
+ ELSE 0
+ END
+ END AS progress_value,
+ COALESCE(total_hours * 60 + total_minutes, 0) AS estimated_minutes
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+)
+SELECT COALESCE(
+ SUM(progress_value * estimated_minutes) / NULLIF(SUM(estimated_minutes), 0),
+ 0
+)
+FROM subtask_progress
+INTO _ratio;
+```
+
+## Default Progress Tracking (when no special mode is selected)
+
+If no specific progress mode is enabled, the system falls back to a traditional completion-based calculation:
+
+**Implementation:**
+- Default mode when all three special modes are disabled
+- Based on task completion status only
+
+**Calculation Logic:**
+- For tasks without subtasks: 0% if not done, 100% if done
+- For parent tasks: `(completed_tasks / total_tasks) * 100`
+- Counts both the parent and all subtasks in the calculation
+
+**SQL Example:**
+```sql
+-- Traditional calculation based on completion status
+SELECT (CASE
+ WHEN EXISTS(SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = _task_id
+ AND is_done IS TRUE) THEN 1
+ ELSE 0 END)
+INTO _parent_task_done;
+
+SELECT COUNT(*)
+FROM tasks_with_status_view
+WHERE parent_task_id = _task_id
+ AND is_done IS TRUE
+INTO _sub_tasks_done;
+
+_total_completed = _parent_task_done + _sub_tasks_done;
+_total_tasks = _sub_tasks_count + 1; -- +1 for the parent task
+
+IF _total_tasks = 0 THEN
+ _ratio = 0;
+ELSE
+ _ratio = (_total_completed / _total_tasks) * 100;
+END IF;
+```
+
+## Technical Implementation Details
+
+The progress calculation logic is implemented in PostgreSQL functions, primarily in the `get_task_complete_ratio` function. Progress updates flow through the system as follows:
+
+1. **User Action**: User updates task progress or weight in the UI
+2. **Socket Event**: Client emits socket event (UPDATE_TASK_PROGRESS or UPDATE_TASK_WEIGHT)
+3. **Server Handler**: Server processes the event in the respective handler function
+4. **Database Update**: Progress/weight value is updated in the database
+5. **Recalculation**: If needed, parent task progress is recalculated
+6. **Broadcast**: Changes are broadcast to all clients in the project room
+7. **UI Update**: Client UI updates to reflect the new progress values
+
+This architecture allows for real-time updates and consistent progress calculation across all clients.
+
+## Associated Files and Components
+
+### Backend Files
+
+1. **Socket Event Handlers**:
+ - `worklenz-backend/src/socket.io/commands/on-update-task-progress.ts` - Handles manual progress updates
+ - `worklenz-backend/src/socket.io/commands/on-update-task-weight.ts` - Handles task weight updates
+
+2. **Database Functions**:
+ - `worklenz-backend/database/migrations/20250423000000-subtask-manual-progress.sql` - Contains the `get_task_complete_ratio` function that calculates progress based on the selected method
+ - Functions that support project creation/updates with progress mode settings:
+ - `create_project`
+ - `update_project`
+
+3. **Controllers**:
+ - `worklenz-backend/src/controllers/project-workload/workload-gannt-base.ts` - Contains the `calculateTaskCompleteRatio` method
+ - `worklenz-backend/src/controllers/projects-controller.ts` - Handles project-level progress calculations
+ - `worklenz-backend/src/controllers/tasks-controller-base.ts` - Handles task progress calculation and updates task view models
+
+### Frontend Files
+
+1. **Project Configuration**:
+ - `worklenz-frontend/src/components/projects/project-drawer/project-drawer.tsx` - Contains UI for selecting progress method when creating/editing projects
+
+2. **Progress Visualization Components**:
+ - `worklenz-frontend/src/components/project-list/project-list-table/project-list-progress/progress-list-progress.tsx` - Displays project progress
+ - `worklenz-frontend/src/pages/projects/project-view-1/taskList/taskListTable/taskListTableCells/TaskProgress.tsx` - Displays task progress
+ - `worklenz-frontend/src/pages/projects/projectView/taskList/task-list-table/task-list-table-cells/task-list-progress-cell/task-list-progress-cell.tsx` - Alternative task progress cell
+ - `worklenz-frontend/src/components/task-list-common/task-row/task-row-progress/task-row-progress.tsx` - Displays progress in task rows
+
+3. **Progress Input Components**:
+ - `worklenz-frontend/src/components/task-drawer/shared/info-tab/details/task-drawer-progress/task-drawer-progress.tsx` - Component for inputting task progress/weight
+
+## Choosing the Right Progress Method
+
+Each progress method is suitable for different types of projects:
+
+- **Manual Progress**: Best for creative work where progress is subjective
+- **Weighted Progress**: Ideal for projects where some tasks are more significant than others
+- **Time-based Progress**: Perfect for projects where time estimates are reliable and important
+
+Project managers can choose the appropriate method when creating or editing a project in the project drawer, based on their team's workflow and project requirements.
\ No newline at end of file
diff --git a/worklenz-backend/.env.template b/worklenz-backend/.env.template
index 145f2411..fdd8fe44 100644
--- a/worklenz-backend/.env.template
+++ b/worklenz-backend/.env.template
@@ -47,12 +47,17 @@ FRONTEND_URL=http://localhost:5000
# STORAGE
STORAGE_PROVIDER=s3 # values s3 or azure
-# AWS
+# AWS - SES
AWS_REGION="your_aws_region"
AWS_ACCESS_KEY_ID="your_aws_access_key_id"
AWS_SECRET_ACCESS_KEY="your_aws_secret_access_key"
-AWS_BUCKET="your_s3_bucket"
+
+# S3
+S3_REGION="S3_REGION"
+S3_BUCKET="your_s3_bucket"
S3_URL="your_s3_url"
+S3_ACCESS_KEY_ID="S3_ACCESS_KEY_ID"
+S3_SECRET_ACCESS_KEY="S3_SECRET_ACCESS_KEY"
# Azure Storage
AZURE_STORAGE_ACCOUNT_NAME="your_storage_account_name"
@@ -73,4 +78,8 @@ GOOGLE_CAPTCHA_SECRET_KEY=your_captcha_secret_key
GOOGLE_CAPTCHA_PASS_SCORE=0.8
# Email Cronjobs
-ENABLE_EMAIL_CRONJOBS=true
\ No newline at end of file
+ENABLE_EMAIL_CRONJOBS=true
+
+# RECURRING_JOBS
+ENABLE_RECURRING_JOBS=true
+RECURRING_JOBS_INTERVAL="0 11 */1 * 1-5"
\ No newline at end of file
diff --git a/worklenz-backend/.gitignore b/worklenz-backend/.gitignore
index d9d5a80a..cb13f868 100644
--- a/worklenz-backend/.gitignore
+++ b/worklenz-backend/.gitignore
@@ -20,9 +20,6 @@ coverage
# nyc test coverage
.nyc_output
-# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
# Bower dependency directory (https://bower.io/)
bower_components
diff --git a/worklenz-backend/Gruntfile.js b/worklenz-backend/Gruntfile.js
deleted file mode 100644
index b621cbc0..00000000
--- a/worklenz-backend/Gruntfile.js
+++ /dev/null
@@ -1,131 +0,0 @@
-module.exports = function (grunt) {
-
- // Project configuration.
- grunt.initConfig({
- pkg: grunt.file.readJSON("package.json"),
- clean: {
- dist: "build"
- },
- compress: require("./grunt/grunt-compress"),
- copy: {
- main: {
- files: [
- {expand: true, cwd: "src", src: ["public/**"], dest: "build"},
- {expand: true, cwd: "src", src: ["views/**"], dest: "build"},
- {expand: true, cwd: "landing-page-assets", src: ["**"], dest: "build/public/assets"},
- {expand: true, cwd: "src", src: ["shared/sample-data.json"], dest: "build", filter: "isFile"},
- {expand: true, cwd: "src", src: ["shared/templates/**"], dest: "build", filter: "isFile"},
- {expand: true, cwd: "src", src: ["shared/postgresql-error-codes.json"], dest: "build", filter: "isFile"},
- ]
- },
- packages: {
- files: [
- {expand: true, cwd: "", src: [".env"], dest: "build", filter: "isFile"},
- {expand: true, cwd: "", src: [".gitignore"], dest: "build", filter: "isFile"},
- {expand: true, cwd: "", src: ["release"], dest: "build", filter: "isFile"},
- {expand: true, cwd: "", src: ["jest.config.js"], dest: "build", filter: "isFile"},
- {expand: true, cwd: "", src: ["package.json"], dest: "build", filter: "isFile"},
- {expand: true, cwd: "", src: ["package-lock.json"], dest: "build", filter: "isFile"},
- {expand: true, cwd: "", src: ["common_modules/**"], dest: "build"}
- ]
- }
- },
- sync: {
- main: {
- files: [
- {cwd: "src", src: ["views/**", "public/**"], dest: "build/"}, // makes all src relative to cwd
- ],
- verbose: true,
- failOnError: true,
- compareUsing: "md5"
- }
- },
- uglify: {
- all: {
- files: [{
- expand: true,
- cwd: "build",
- src: "**/*.js",
- dest: "build"
- }]
- },
- controllers: {
- files: [{
- expand: true,
- cwd: "build",
- src: "controllers/*.js",
- dest: "build"
- }]
- },
- routes: {
- files: [{
- expand: true,
- cwd: "build",
- src: "routes/**/*.js",
- dest: "build"
- }]
- },
- assets: {
- files: [{
- expand: true,
- cwd: "build",
- src: "public/assets/**/*.js",
- dest: "build"
- }]
- }
- },
- shell: {
- tsc: {
- command: "tsc --build tsconfig.prod.json"
- },
- esbuild: {
- // command: "esbuild `find src -type f -name '*.ts'` --platform=node --minify=false --target=esnext --format=cjs --tsconfig=tsconfig.prod.json --outdir=build"
- command: "node esbuild && node cli/esbuild-patch"
- },
- tsc_dev: {
- command: "tsc --build tsconfig.json"
- },
- swagger: {
- command: "node ./cli/swagger"
- },
- inline_queries: {
- command: "node ./cli/inline-queries"
- }
- },
- watch: {
- scripts: {
- files: ["src/**/*.ts"],
- tasks: ["shell:tsc_dev"],
- options: {
- debounceDelay: 250,
- spawn: false,
- }
- },
- other: {
- files: ["src/**/*.pug", "landing-page-assets/**"],
- tasks: ["sync"]
- }
- }
- });
-
- grunt.registerTask("clean", ["clean"]);
- grunt.registerTask("copy", ["copy:main"]);
- grunt.registerTask("swagger", ["shell:swagger"]);
- grunt.registerTask("build:tsc", ["shell:tsc"]);
- grunt.registerTask("build", ["clean", "shell:tsc", "copy:main", "compress"]);
- grunt.registerTask("build:es", ["clean", "shell:esbuild", "copy:main", "uglify:assets", "compress"]);
- grunt.registerTask("build:strict", ["clean", "shell:tsc", "copy:packages", "uglify:all", "copy:main", "compress"]);
- grunt.registerTask("dev", ["clean", "copy:main", "shell:tsc_dev", "shell:inline_queries", "watch"]);
-
- // Load the plugin that provides the "uglify" task.
- grunt.loadNpmTasks("grunt-contrib-watch");
- grunt.loadNpmTasks("grunt-contrib-clean");
- grunt.loadNpmTasks("grunt-contrib-copy");
- grunt.loadNpmTasks("grunt-contrib-uglify");
- grunt.loadNpmTasks("grunt-contrib-compress");
- grunt.loadNpmTasks("grunt-shell");
- grunt.loadNpmTasks("grunt-sync");
-
- // Default task(s).
- grunt.registerTask("default", []);
-};
diff --git a/worklenz-backend/database/00-init-db.sh b/worklenz-backend/database/00-init-db.sh
deleted file mode 100644
index 9743d435..00000000
--- a/worklenz-backend/database/00-init-db.sh
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/bash
-set -e
-
-# This script controls the order of SQL file execution during database initialization
-echo "Starting database initialization..."
-
-# Check if we have SQL files in expected locations
-if [ -f "/docker-entrypoint-initdb.d/sql/0_extensions.sql" ]; then
- SQL_DIR="/docker-entrypoint-initdb.d/sql"
- echo "Using SQL files from sql/ subdirectory"
-elif [ -f "/docker-entrypoint-initdb.d/0_extensions.sql" ]; then
- # First time setup - move files to subdirectory
- echo "Moving SQL files to sql/ subdirectory..."
- mkdir -p /docker-entrypoint-initdb.d/sql
-
- # Move all SQL files (except this script) to the subdirectory
- for f in /docker-entrypoint-initdb.d/*.sql; do
- if [ -f "$f" ]; then
- cp "$f" /docker-entrypoint-initdb.d/sql/
- echo "Copied $f to sql/ subdirectory"
- fi
- done
-
- SQL_DIR="/docker-entrypoint-initdb.d/sql"
-else
- echo "SQL files not found in expected locations!"
- exit 1
-fi
-
-# Execute SQL files in the correct order
-echo "Executing 0_extensions.sql..."
-psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/0_extensions.sql"
-
-echo "Executing 1_tables.sql..."
-psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/1_tables.sql"
-
-echo "Executing indexes.sql..."
-psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/indexes.sql"
-
-echo "Executing 4_functions.sql..."
-psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/4_functions.sql"
-
-echo "Executing triggers.sql..."
-psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/triggers.sql"
-
-echo "Executing 3_views.sql..."
-psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/3_views.sql"
-
-echo "Executing 2_dml.sql..."
-psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/2_dml.sql"
-
-echo "Executing 5_database_user.sql..."
-psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -f "$SQL_DIR/5_database_user.sql"
-
-echo "Database initialization completed successfully"
\ No newline at end of file
diff --git a/worklenz-backend/database/00_init.sh b/worklenz-backend/database/00_init.sh
new file mode 100644
index 00000000..afd8562a
--- /dev/null
+++ b/worklenz-backend/database/00_init.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+set -e
+
+echo "Starting database initialization..."
+
+SQL_DIR="/docker-entrypoint-initdb.d/sql"
+MIGRATIONS_DIR="/docker-entrypoint-initdb.d/migrations"
+BACKUP_DIR="/docker-entrypoint-initdb.d/pg_backups"
+
+# --------------------------------------------
+# ๐๏ธ STEP 1: Attempt to restore latest backup
+# --------------------------------------------
+
+if [ -d "$BACKUP_DIR" ]; then
+ LATEST_BACKUP=$(ls -t "$BACKUP_DIR"/*.sql 2>/dev/null | head -n 1)
+else
+ LATEST_BACKUP=""
+fi
+
+if [ -f "$LATEST_BACKUP" ]; then
+ echo "๐๏ธ Found latest backup: $LATEST_BACKUP"
+ echo "โณ Restoring from backup..."
+ psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" < "$LATEST_BACKUP"
+ echo "โ Backup restoration complete. Skipping schema and migrations."
+ exit 0
+else
+ echo "โน๏ธ No valid backup found. Proceeding with base schema and migrations."
+fi
+
+# --------------------------------------------
+# ๐๏ธ STEP 2: Continue with base schema setup
+# --------------------------------------------
+
+# Create migrations table if it doesn't exist
+psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "
+ CREATE TABLE IF NOT EXISTS schema_migrations (
+ version TEXT PRIMARY KEY,
+ applied_at TIMESTAMP DEFAULT now()
+ );
+"
+
+# List of base schema files to execute in order
+BASE_SQL_FILES=(
+ "0_extensions.sql"
+ "1_tables.sql"
+ "indexes.sql"
+ "4_functions.sql"
+ "triggers.sql"
+ "3_views.sql"
+ "2_dml.sql"
+ "5_database_user.sql"
+)
+
+echo "Running base schema SQL files in order..."
+
+for file in "${BASE_SQL_FILES[@]}"; do
+ full_path="$SQL_DIR/$file"
+ if [ -f "$full_path" ]; then
+ echo "Executing $file..."
+ psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$POSTGRES_DB" -f "$full_path"
+ else
+ echo "WARNING: $file not found, skipping."
+ fi
+done
+
+echo "โ Base schema SQL execution complete."
+
+# --------------------------------------------
+# ๐ STEP 3: Apply SQL migrations
+# --------------------------------------------
+
+if [ -d "$MIGRATIONS_DIR" ] && compgen -G "$MIGRATIONS_DIR/*.sql" > /dev/null; then
+ echo "Applying migrations..."
+ for f in "$MIGRATIONS_DIR"/*.sql; do
+ version=$(basename "$f")
+ if ! psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -tAc "SELECT 1 FROM schema_migrations WHERE version = '$version'" | grep -q 1; then
+ echo "Applying migration: $version"
+ psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -f "$f"
+ psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "INSERT INTO schema_migrations (version) VALUES ('$version');"
+ else
+ echo "Skipping already applied migration: $version"
+ fi
+ done
+else
+ echo "No migration files found or directory is empty, skipping migrations."
+fi
+
+echo "๐ Database initialization completed successfully."
diff --git a/worklenz-backend/database/migrations/20250115000000-performance-indexes.sql b/worklenz-backend/database/migrations/20250115000000-performance-indexes.sql
new file mode 100644
index 00000000..791c6f02
--- /dev/null
+++ b/worklenz-backend/database/migrations/20250115000000-performance-indexes.sql
@@ -0,0 +1,135 @@
+-- Performance indexes for optimized tasks queries
+-- Migration: 20250115000000-performance-indexes.sql
+
+-- Composite index for main task filtering
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tasks_project_archived_parent
+ON tasks(project_id, archived, parent_task_id)
+WHERE archived = FALSE;
+
+-- Index for status joins
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tasks_status_project
+ON tasks(status_id, project_id)
+WHERE archived = FALSE;
+
+-- Index for assignees lookup
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tasks_assignees_task_member
+ON tasks_assignees(task_id, team_member_id);
+
+-- Index for phase lookup
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_task_phase_task_phase
+ON task_phase(task_id, phase_id);
+
+-- Index for subtask counting
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tasks_parent_archived
+ON tasks(parent_task_id, archived)
+WHERE parent_task_id IS NOT NULL AND archived = FALSE;
+
+-- Index for labels
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_task_labels_task_label
+ON task_labels(task_id, label_id);
+
+-- Index for comments count
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_task_comments_task
+ON task_comments(task_id);
+
+-- Index for attachments count
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_task_attachments_task
+ON task_attachments(task_id);
+
+-- Index for work log aggregation
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_task_work_log_task
+ON task_work_log(task_id);
+
+-- Index for subscribers check
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_task_subscribers_task
+ON task_subscribers(task_id);
+
+-- Index for dependencies check
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_task_dependencies_task
+ON task_dependencies(task_id);
+
+-- Index for timers lookup
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_task_timers_task_user
+ON task_timers(task_id, user_id);
+
+-- Index for custom columns
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_cc_column_values_task
+ON cc_column_values(task_id);
+
+-- Index for team member info view optimization
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_team_members_team_user
+ON team_members(team_id, user_id)
+WHERE active = TRUE;
+
+-- Index for notification settings
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_notification_settings_user_team
+ON notification_settings(user_id, team_id);
+
+-- Index for task status categories
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_task_statuses_category
+ON task_statuses(category_id, project_id);
+
+-- Index for project phases
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_project_phases_project_sort
+ON project_phases(project_id, sort_index);
+
+-- Index for task priorities
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_task_priorities_value
+ON task_priorities(value);
+
+-- Index for team labels
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_team_labels_team
+ON team_labels(team_id);
+
+-- NEW INDEXES FOR PERFORMANCE OPTIMIZATION --
+
+-- Composite index for task main query optimization (covers most WHERE conditions)
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tasks_performance_main
+ON tasks(project_id, archived, parent_task_id, status_id, priority_id)
+WHERE archived = FALSE;
+
+-- Index for sorting by sort_order with project filter
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tasks_project_sort_order
+ON tasks(project_id, sort_order)
+WHERE archived = FALSE;
+
+-- Index for email_invitations to optimize team_member_info_view
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_email_invitations_team_member
+ON email_invitations(team_member_id);
+
+-- Covering index for task status with category information
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_task_statuses_covering
+ON task_statuses(id, category_id, project_id);
+
+-- Index for task aggregation queries (parent task progress calculation)
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tasks_parent_status_archived
+ON tasks(parent_task_id, status_id, archived)
+WHERE archived = FALSE;
+
+-- Index for project team member filtering
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_team_members_project_lookup
+ON team_members(team_id, active, user_id)
+WHERE active = TRUE;
+
+-- Covering index for tasks with frequently accessed columns
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tasks_covering_main
+ON tasks(id, project_id, archived, parent_task_id, status_id, priority_id, sort_order, name)
+WHERE archived = FALSE;
+
+-- Index for task search functionality
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tasks_name_search
+ON tasks USING gin(to_tsvector('english', name))
+WHERE archived = FALSE;
+
+-- Index for date-based filtering (if used)
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tasks_dates
+ON tasks(project_id, start_date, end_date)
+WHERE archived = FALSE;
+
+-- Index for task timers with user filtering
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_task_timers_user_task
+ON task_timers(user_id, task_id);
+
+-- Index for sys_task_status_categories lookups
+CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_sys_task_status_categories_covering
+ON sys_task_status_categories(id, color_code, color_code_dark, is_done, is_doing, is_todo);
\ No newline at end of file
diff --git a/worklenz-backend/database/migrations/20250128000000-fix-window-function-error.sql b/worklenz-backend/database/migrations/20250128000000-fix-window-function-error.sql
new file mode 100644
index 00000000..9a20e173
--- /dev/null
+++ b/worklenz-backend/database/migrations/20250128000000-fix-window-function-error.sql
@@ -0,0 +1,143 @@
+-- Fix window function error in task sort optimized functions
+-- Error: window functions are not allowed in UPDATE
+
+-- Replace the optimized sort functions to avoid CTE usage in UPDATE statements
+CREATE OR REPLACE FUNCTION handle_task_list_sort_between_groups_optimized(_from_index integer, _to_index integer, _task_id uuid, _project_id uuid, _batch_size integer DEFAULT 100) RETURNS void
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _offset INT := 0;
+ _affected_rows INT;
+BEGIN
+ -- PERFORMANCE OPTIMIZATION: Use direct updates without CTE in UPDATE
+ IF (_to_index = -1)
+ THEN
+ _to_index = COALESCE((SELECT MAX(sort_order) + 1 FROM tasks WHERE project_id = _project_id), 0);
+ END IF;
+
+ -- PERFORMANCE OPTIMIZATION: Batch updates for large datasets
+ IF _to_index > _from_index
+ THEN
+ LOOP
+ UPDATE tasks
+ SET sort_order = sort_order - 1
+ WHERE project_id = _project_id
+ AND sort_order > _from_index
+ AND sort_order < _to_index
+ AND sort_order > _offset
+ AND sort_order <= _offset + _batch_size;
+
+ GET DIAGNOSTICS _affected_rows = ROW_COUNT;
+ EXIT WHEN _affected_rows = 0;
+ _offset := _offset + _batch_size;
+ END LOOP;
+
+ UPDATE tasks SET sort_order = _to_index - 1 WHERE id = _task_id AND project_id = _project_id;
+ END IF;
+
+ IF _to_index < _from_index
+ THEN
+ _offset := 0;
+ LOOP
+ UPDATE tasks
+ SET sort_order = sort_order + 1
+ WHERE project_id = _project_id
+ AND sort_order > _to_index
+ AND sort_order < _from_index
+ AND sort_order > _offset
+ AND sort_order <= _offset + _batch_size;
+
+ GET DIAGNOSTICS _affected_rows = ROW_COUNT;
+ EXIT WHEN _affected_rows = 0;
+ _offset := _offset + _batch_size;
+ END LOOP;
+
+ UPDATE tasks SET sort_order = _to_index + 1 WHERE id = _task_id AND project_id = _project_id;
+ END IF;
+END
+$$;
+
+-- Replace the second optimized sort function
+CREATE OR REPLACE FUNCTION handle_task_list_sort_inside_group_optimized(_from_index integer, _to_index integer, _task_id uuid, _project_id uuid, _batch_size integer DEFAULT 100) RETURNS void
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _offset INT := 0;
+ _affected_rows INT;
+BEGIN
+ -- PERFORMANCE OPTIMIZATION: Batch updates for large datasets without CTE in UPDATE
+ IF _to_index > _from_index
+ THEN
+ LOOP
+ UPDATE tasks
+ SET sort_order = sort_order - 1
+ WHERE project_id = _project_id
+ AND sort_order > _from_index
+ AND sort_order <= _to_index
+ AND sort_order > _offset
+ AND sort_order <= _offset + _batch_size;
+
+ GET DIAGNOSTICS _affected_rows = ROW_COUNT;
+ EXIT WHEN _affected_rows = 0;
+ _offset := _offset + _batch_size;
+ END LOOP;
+ END IF;
+
+ IF _to_index < _from_index
+ THEN
+ _offset := 0;
+ LOOP
+ UPDATE tasks
+ SET sort_order = sort_order + 1
+ WHERE project_id = _project_id
+ AND sort_order >= _to_index
+ AND sort_order < _from_index
+ AND sort_order > _offset
+ AND sort_order <= _offset + _batch_size;
+
+ GET DIAGNOSTICS _affected_rows = ROW_COUNT;
+ EXIT WHEN _affected_rows = 0;
+ _offset := _offset + _batch_size;
+ END LOOP;
+ END IF;
+
+ UPDATE tasks SET sort_order = _to_index WHERE id = _task_id AND project_id = _project_id;
+END
+$$;
+
+-- Add simple bulk update function as alternative
+CREATE OR REPLACE FUNCTION update_task_sort_orders_bulk(_updates json) RETURNS void
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _update_record RECORD;
+BEGIN
+ -- Simple approach: update each task's sort_order from the provided array
+ FOR _update_record IN
+ SELECT
+ (item->>'task_id')::uuid as task_id,
+ (item->>'sort_order')::int as sort_order,
+ (item->>'status_id')::uuid as status_id,
+ (item->>'priority_id')::uuid as priority_id,
+ (item->>'phase_id')::uuid as phase_id
+ FROM json_array_elements(_updates) as item
+ LOOP
+ UPDATE tasks
+ SET
+ sort_order = _update_record.sort_order,
+ status_id = COALESCE(_update_record.status_id, status_id),
+ priority_id = COALESCE(_update_record.priority_id, priority_id)
+ WHERE id = _update_record.task_id;
+
+ -- Handle phase updates separately since it's in a different table
+ IF _update_record.phase_id IS NOT NULL THEN
+ INSERT INTO task_phase (task_id, phase_id)
+ VALUES (_update_record.task_id, _update_record.phase_id)
+ ON CONFLICT (task_id) DO UPDATE SET phase_id = _update_record.phase_id;
+ END IF;
+ END LOOP;
+END
+$$;
\ No newline at end of file
diff --git a/worklenz-backend/database/migrations/20250422132400-manual-task-progress.sql b/worklenz-backend/database/migrations/20250422132400-manual-task-progress.sql
new file mode 100644
index 00000000..c45d34af
--- /dev/null
+++ b/worklenz-backend/database/migrations/20250422132400-manual-task-progress.sql
@@ -0,0 +1,78 @@
+-- Migration: Add manual task progress
+-- Date: 2025-04-22
+-- Version: 1.0.0
+
+BEGIN;
+
+-- Add manual progress fields to tasks table
+ALTER TABLE tasks
+ADD COLUMN IF NOT EXISTS manual_progress BOOLEAN DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS progress_value INTEGER DEFAULT NULL,
+ADD COLUMN IF NOT EXISTS weight INTEGER DEFAULT NULL;
+
+-- Update function to consider manual progress
+CREATE OR REPLACE FUNCTION get_task_complete_ratio(_task_id uuid) RETURNS json
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _parent_task_done FLOAT = 0;
+ _sub_tasks_done FLOAT = 0;
+ _sub_tasks_count FLOAT = 0;
+ _total_completed FLOAT = 0;
+ _total_tasks FLOAT = 0;
+ _ratio FLOAT = 0;
+ _is_manual BOOLEAN = FALSE;
+ _manual_value INTEGER = NULL;
+BEGIN
+ -- Check if manual progress is set
+ SELECT manual_progress, progress_value
+ FROM tasks
+ WHERE id = _task_id
+ INTO _is_manual, _manual_value;
+
+ -- If manual progress is enabled and has a value, use it directly
+ IF _is_manual IS TRUE AND _manual_value IS NOT NULL THEN
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', _manual_value,
+ 'total_completed', 0,
+ 'total_tasks', 0,
+ 'is_manual', TRUE
+ );
+ END IF;
+
+ -- Otherwise calculate automatically as before
+ SELECT (CASE
+ WHEN EXISTS(SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = _task_id
+ AND is_done IS TRUE) THEN 1
+ ELSE 0 END)
+ INTO _parent_task_done;
+ SELECT COUNT(*) FROM tasks WHERE parent_task_id = _task_id AND archived IS FALSE INTO _sub_tasks_count;
+
+ SELECT COUNT(*)
+ FROM tasks_with_status_view
+ WHERE parent_task_id = _task_id
+ AND is_done IS TRUE
+ INTO _sub_tasks_done;
+
+ _total_completed = _parent_task_done + _sub_tasks_done;
+ _total_tasks = _sub_tasks_count; -- +1 for the parent task
+
+ IF _total_tasks > 0 THEN
+ _ratio = (_total_completed / _total_tasks) * 100;
+ ELSE
+ _ratio = _parent_task_done * 100;
+ END IF;
+
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', _ratio,
+ 'total_completed', _total_completed,
+ 'total_tasks', _total_tasks,
+ 'is_manual', FALSE
+ );
+END
+$$;
+
+COMMIT;
\ No newline at end of file
diff --git a/worklenz-backend/database/migrations/20250423000000-subtask-manual-progress.sql b/worklenz-backend/database/migrations/20250423000000-subtask-manual-progress.sql
new file mode 100644
index 00000000..b4650dc7
--- /dev/null
+++ b/worklenz-backend/database/migrations/20250423000000-subtask-manual-progress.sql
@@ -0,0 +1,687 @@
+-- Migration: Enhance manual task progress with subtask support
+-- Date: 2025-04-23
+-- Version: 1.0.0
+
+BEGIN;
+
+-- Update function to consider subtask manual progress when calculating parent task progress
+CREATE OR REPLACE FUNCTION get_task_complete_ratio(_task_id uuid) RETURNS json
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _parent_task_done FLOAT = 0;
+ _sub_tasks_done FLOAT = 0;
+ _sub_tasks_count FLOAT = 0;
+ _total_completed FLOAT = 0;
+ _total_tasks FLOAT = 0;
+ _ratio FLOAT = 0;
+ _is_manual BOOLEAN = FALSE;
+ _manual_value INTEGER = NULL;
+ _project_id UUID;
+ _use_manual_progress BOOLEAN = FALSE;
+ _use_weighted_progress BOOLEAN = FALSE;
+ _use_time_progress BOOLEAN = FALSE;
+BEGIN
+ -- Check if manual progress is set for this task
+ SELECT manual_progress, progress_value, project_id
+ FROM tasks
+ WHERE id = _task_id
+ INTO _is_manual, _manual_value, _project_id;
+
+ -- Check if the project uses manual progress
+ IF _project_id IS NOT NULL THEN
+ SELECT COALESCE(use_manual_progress, FALSE),
+ COALESCE(use_weighted_progress, FALSE),
+ COALESCE(use_time_progress, FALSE)
+ FROM projects
+ WHERE id = _project_id
+ INTO _use_manual_progress, _use_weighted_progress, _use_time_progress;
+ END IF;
+
+ -- Get all subtasks
+ SELECT COUNT(*)
+ FROM tasks
+ WHERE parent_task_id = _task_id AND archived IS FALSE
+ INTO _sub_tasks_count;
+
+ -- If manual progress is enabled and has a value AND there are no subtasks, use it directly
+ IF _is_manual IS TRUE AND _manual_value IS NOT NULL AND _sub_tasks_count = 0 THEN
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', _manual_value,
+ 'total_completed', 0,
+ 'total_tasks', 0,
+ 'is_manual', TRUE
+ );
+ END IF;
+
+ -- If there are no subtasks, just use the parent task's status
+ IF _sub_tasks_count = 0 THEN
+ SELECT (CASE
+ WHEN EXISTS(SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = _task_id
+ AND is_done IS TRUE) THEN 1
+ ELSE 0 END)
+ INTO _parent_task_done;
+
+ _ratio = _parent_task_done * 100;
+ ELSE
+ -- If project uses manual progress, calculate based on subtask manual progress values
+ IF _use_manual_progress IS TRUE THEN
+ WITH subtask_progress AS (
+ SELECT
+ CASE
+ -- If subtask has manual progress, use that value
+ WHEN manual_progress IS TRUE AND progress_value IS NOT NULL THEN
+ progress_value
+ -- Otherwise use completion status (0 or 100)
+ ELSE
+ CASE
+ WHEN EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) THEN 100
+ ELSE 0
+ END
+ END AS progress_value
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ )
+ SELECT COALESCE(AVG(progress_value), 0)
+ FROM subtask_progress
+ INTO _ratio;
+ -- If project uses weighted progress, calculate based on subtask weights
+ ELSIF _use_weighted_progress IS TRUE THEN
+ WITH subtask_progress AS (
+ SELECT
+ CASE
+ -- If subtask has manual progress, use that value
+ WHEN manual_progress IS TRUE AND progress_value IS NOT NULL THEN
+ progress_value
+ -- Otherwise use completion status (0 or 100)
+ ELSE
+ CASE
+ WHEN EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) THEN 100
+ ELSE 0
+ END
+ END AS progress_value,
+ COALESCE(weight, 100) AS weight
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ )
+ SELECT COALESCE(
+ SUM(progress_value * weight) / NULLIF(SUM(weight), 0),
+ 0
+ )
+ FROM subtask_progress
+ INTO _ratio;
+ -- If project uses time-based progress, calculate based on estimated time
+ ELSIF _use_time_progress IS TRUE THEN
+ WITH subtask_progress AS (
+ SELECT
+ CASE
+ -- If subtask has manual progress, use that value
+ WHEN manual_progress IS TRUE AND progress_value IS NOT NULL THEN
+ progress_value
+ -- Otherwise use completion status (0 or 100)
+ ELSE
+ CASE
+ WHEN EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) THEN 100
+ ELSE 0
+ END
+ END AS progress_value,
+ COALESCE(total_minutes, 0) AS estimated_minutes
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ )
+ SELECT COALESCE(
+ SUM(progress_value * estimated_minutes) / NULLIF(SUM(estimated_minutes), 0),
+ 0
+ )
+ FROM subtask_progress
+ INTO _ratio;
+ ELSE
+ -- Traditional calculation based on completion status
+ SELECT (CASE
+ WHEN EXISTS(SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = _task_id
+ AND is_done IS TRUE) THEN 1
+ ELSE 0 END)
+ INTO _parent_task_done;
+
+ SELECT COUNT(*)
+ FROM tasks_with_status_view
+ WHERE parent_task_id = _task_id
+ AND is_done IS TRUE
+ INTO _sub_tasks_done;
+
+ _total_completed = _parent_task_done + _sub_tasks_done;
+ _total_tasks = _sub_tasks_count + 1; -- +1 for the parent task
+
+ IF _total_tasks = 0 THEN
+ _ratio = 0;
+ ELSE
+ _ratio = (_total_completed / _total_tasks) * 100;
+ END IF;
+ END IF;
+ END IF;
+
+ -- Ensure ratio is between 0 and 100
+ IF _ratio < 0 THEN
+ _ratio = 0;
+ ELSIF _ratio > 100 THEN
+ _ratio = 100;
+ END IF;
+
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', _ratio,
+ 'total_completed', _total_completed,
+ 'total_tasks', _total_tasks,
+ 'is_manual', _is_manual
+ );
+END
+$$;
+
+CREATE OR REPLACE FUNCTION update_project(_body json) RETURNS json
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _user_id UUID;
+ _team_id UUID;
+ _client_id UUID;
+ _project_id UUID;
+ _project_manager_team_member_id UUID;
+ _client_name TEXT;
+ _project_name TEXT;
+BEGIN
+ -- need a test, can be throw errors
+ _client_name = TRIM((_body ->> 'client_name')::TEXT);
+ _project_name = TRIM((_body ->> 'name')::TEXT);
+
+ -- add inside the controller
+ _user_id = (_body ->> 'user_id')::UUID;
+ _team_id = (_body ->> 'team_id')::UUID;
+ _project_manager_team_member_id = (_body ->> 'team_member_id')::UUID;
+
+ -- cache exists client if exists
+ SELECT id FROM clients WHERE LOWER(name) = LOWER(_client_name) AND team_id = _team_id INTO _client_id;
+
+ -- insert client if not exists
+ IF is_null_or_empty(_client_id) IS TRUE AND is_null_or_empty(_client_name) IS FALSE
+ THEN
+ INSERT INTO clients (name, team_id) VALUES (_client_name, _team_id) RETURNING id INTO _client_id;
+ END IF;
+
+ -- check whether the project name is already in
+ IF EXISTS(
+ SELECT name FROM projects WHERE LOWER(name) = LOWER(_project_name)
+ AND team_id = _team_id AND id != (_body ->> 'id')::UUID
+ )
+ THEN
+ RAISE 'PROJECT_EXISTS_ERROR:%', _project_name;
+ END IF;
+
+ -- update the project
+ UPDATE projects
+ SET name = _project_name,
+ notes = (_body ->> 'notes')::TEXT,
+ color_code = (_body ->> 'color_code')::TEXT,
+ status_id = (_body ->> 'status_id')::UUID,
+ health_id = (_body ->> 'health_id')::UUID,
+ key = (_body ->> 'key')::TEXT,
+ start_date = (_body ->> 'start_date')::TIMESTAMPTZ,
+ end_date = (_body ->> 'end_date')::TIMESTAMPTZ,
+ client_id = _client_id,
+ folder_id = (_body ->> 'folder_id')::UUID,
+ category_id = (_body ->> 'category_id')::UUID,
+ updated_at = CURRENT_TIMESTAMP,
+ estimated_working_days = (_body ->> 'working_days')::INTEGER,
+ estimated_man_days = (_body ->> 'man_days')::INTEGER,
+ hours_per_day = (_body ->> 'hours_per_day')::INTEGER,
+ use_manual_progress = COALESCE((_body ->> 'use_manual_progress')::BOOLEAN, FALSE),
+ use_weighted_progress = COALESCE((_body ->> 'use_weighted_progress')::BOOLEAN, FALSE),
+ use_time_progress = COALESCE((_body ->> 'use_time_progress')::BOOLEAN, FALSE)
+ WHERE id = (_body ->> 'id')::UUID
+ AND team_id = _team_id
+ RETURNING id INTO _project_id;
+
+ UPDATE project_members SET project_access_level_id = (SELECT id FROM project_access_levels WHERE key = 'MEMBER') WHERE project_id = _project_id;
+
+ IF NOT (_project_manager_team_member_id IS NULL)
+ THEN
+ PERFORM update_project_manager(_project_manager_team_member_id, _project_id::UUID);
+ END IF;
+
+ RETURN JSON_BUILD_OBJECT(
+ 'id', _project_id,
+ 'name', (_body ->> 'name')::TEXT,
+ 'project_manager_id', _project_manager_team_member_id::UUID
+ );
+END;
+$$;
+
+-- 3. Also modify the create_project function to handle the new fields during project creation
+CREATE OR REPLACE FUNCTION create_project(_body json) RETURNS json
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _project_id UUID;
+ _user_id UUID;
+ _team_id UUID;
+ _team_member_id UUID;
+ _client_id UUID;
+ _client_name TEXT;
+ _project_name TEXT;
+ _project_created_log TEXT;
+ _project_member_added_log TEXT;
+ _project_created_log_id UUID;
+ _project_manager_team_member_id UUID;
+ _project_key TEXT;
+BEGIN
+ _client_name = TRIM((_body ->> 'client_name')::TEXT);
+ _project_name = TRIM((_body ->> 'name')::TEXT);
+ _project_key = TRIM((_body ->> 'key')::TEXT);
+ _project_created_log = (_body ->> 'project_created_log')::TEXT;
+ _project_member_added_log = (_body ->> 'project_member_added_log')::TEXT;
+ _user_id = (_body ->> 'user_id')::UUID;
+ _team_id = (_body ->> 'team_id')::UUID;
+ _project_manager_team_member_id = (_body ->> 'project_manager_id')::UUID;
+
+ SELECT id FROM team_members WHERE user_id = _user_id AND team_id = _team_id INTO _team_member_id;
+
+ -- cache exists client if exists
+ SELECT id FROM clients WHERE LOWER(name) = LOWER(_client_name) AND team_id = _team_id INTO _client_id;
+
+ -- insert client if not exists
+ IF is_null_or_empty(_client_id) IS TRUE AND is_null_or_empty(_client_name) IS FALSE
+ THEN
+ INSERT INTO clients (name, team_id) VALUES (_client_name, _team_id) RETURNING id INTO _client_id;
+ END IF;
+
+ -- check whether the project name is already in
+ IF EXISTS(SELECT name FROM projects WHERE LOWER(name) = LOWER(_project_name) AND team_id = _team_id)
+ THEN
+ RAISE 'PROJECT_EXISTS_ERROR:%', _project_name;
+ END IF;
+
+ -- create the project
+ INSERT
+ INTO projects (name, key, color_code, start_date, end_date, team_id, notes, owner_id, status_id, health_id, folder_id,
+ category_id, estimated_working_days, estimated_man_days, hours_per_day,
+ use_manual_progress, use_weighted_progress, use_time_progress, client_id)
+ VALUES (_project_name,
+ UPPER(_project_key),
+ (_body ->> 'color_code')::TEXT,
+ (_body ->> 'start_date')::TIMESTAMPTZ,
+ (_body ->> 'end_date')::TIMESTAMPTZ,
+ _team_id,
+ (_body ->> 'notes')::TEXT,
+ _user_id,
+ (_body ->> 'status_id')::UUID,
+ (_body ->> 'health_id')::UUID,
+ (_body ->> 'folder_id')::UUID,
+ (_body ->> 'category_id')::UUID,
+ (_body ->> 'working_days')::INTEGER,
+ (_body ->> 'man_days')::INTEGER,
+ (_body ->> 'hours_per_day')::INTEGER,
+ COALESCE((_body ->> 'use_manual_progress')::BOOLEAN, FALSE),
+ COALESCE((_body ->> 'use_weighted_progress')::BOOLEAN, FALSE),
+ COALESCE((_body ->> 'use_time_progress')::BOOLEAN, FALSE),
+ _client_id)
+ RETURNING id INTO _project_id;
+
+ -- register the project log
+ INSERT INTO project_logs (project_id, team_id, description)
+ VALUES (_project_id, _team_id, _project_created_log)
+ RETURNING id INTO _project_created_log_id;
+
+ -- insert the project creator as a project member
+ INSERT INTO project_members (team_member_id, project_access_level_id, project_id, role_id)
+ VALUES (_team_member_id, (SELECT id FROM project_access_levels WHERE key = 'ADMIN'),
+ _project_id,
+ (SELECT id FROM roles WHERE team_id = _team_id AND default_role IS TRUE));
+
+ -- insert statuses
+ INSERT INTO task_statuses (name, project_id, team_id, category_id, sort_order)
+ VALUES ('To Do', _project_id, _team_id, (SELECT id FROM sys_task_status_categories WHERE is_todo IS TRUE), 0);
+ INSERT INTO task_statuses (name, project_id, team_id, category_id, sort_order)
+ VALUES ('Doing', _project_id, _team_id, (SELECT id FROM sys_task_status_categories WHERE is_doing IS TRUE), 1);
+ INSERT INTO task_statuses (name, project_id, team_id, category_id, sort_order)
+ VALUES ('Done', _project_id, _team_id, (SELECT id FROM sys_task_status_categories WHERE is_done IS TRUE), 2);
+
+ -- insert default project columns
+ PERFORM insert_task_list_columns(_project_id);
+
+ -- add project manager role if exists
+ IF NOT is_null_or_empty(_project_manager_team_member_id) THEN
+ PERFORM update_project_manager(_project_manager_team_member_id, _project_id);
+ END IF;
+
+ RETURN JSON_BUILD_OBJECT(
+ 'id', _project_id,
+ 'name', _project_name,
+ 'project_created_log_id', _project_created_log_id
+ );
+END;
+$$;
+
+-- 4. Update the getById function to include the new fields in the response
+CREATE OR REPLACE FUNCTION getProjectById(_project_id UUID, _team_id UUID) RETURNS JSON
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _result JSON;
+BEGIN
+ SELECT ROW_TO_JSON(rec) INTO _result
+ FROM (SELECT p.id,
+ p.name,
+ p.key,
+ p.color_code,
+ p.start_date,
+ p.end_date,
+ c.name AS client_name,
+ c.id AS client_id,
+ p.notes,
+ p.created_at,
+ p.updated_at,
+ ts.name AS status,
+ ts.color_code AS status_color,
+ ts.icon AS status_icon,
+ ts.id AS status_id,
+ h.name AS health,
+ h.color_code AS health_color,
+ h.icon AS health_icon,
+ h.id AS health_id,
+ pc.name AS category_name,
+ pc.color_code AS category_color,
+ pc.id AS category_id,
+ p.phase_label,
+ p.estimated_man_days AS man_days,
+ p.estimated_working_days AS working_days,
+ p.hours_per_day,
+ p.use_manual_progress,
+ p.use_weighted_progress,
+ -- Additional fields
+ COALESCE((SELECT ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(t)))
+ FROM (SELECT pm.id,
+ pm.project_id,
+ tm.id AS team_member_id,
+ tm.user_id,
+ u.name,
+ u.email,
+ u.avatar_url,
+ u.phone_number,
+ pal.name AS access_level,
+ pal.key AS access_level_key,
+ pal.id AS access_level_id,
+ EXISTS(SELECT 1
+ FROM project_members
+ INNER JOIN project_access_levels ON
+ project_members.project_access_level_id = project_access_levels.id
+ WHERE project_id = p.id
+ AND project_access_levels.key = 'PROJECT_MANAGER'
+ AND team_member_id = tm.id) AS is_project_manager
+ FROM project_members pm
+ INNER JOIN team_members tm ON pm.team_member_id = tm.id
+ INNER JOIN users u ON tm.user_id = u.id
+ INNER JOIN project_access_levels pal ON pm.project_access_level_id = pal.id
+ WHERE pm.project_id = p.id) t), '[]'::JSON) AS members,
+ (SELECT COUNT(DISTINCT (id))
+ FROM tasks
+ WHERE archived IS FALSE
+ AND project_id = p.id) AS task_count,
+ (SELECT ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(t)))
+ FROM (SELECT project_members.id,
+ project_members.project_id,
+ team_members.id AS team_member_id,
+ team_members.user_id,
+ users.name,
+ users.email,
+ users.avatar_url,
+ project_access_levels.name AS access_level,
+ project_access_levels.key AS access_level_key,
+ project_access_levels.id AS access_level_id
+ FROM project_members
+ INNER JOIN team_members ON project_members.team_member_id = team_members.id
+ INNER JOIN users ON team_members.user_id = users.id
+ INNER JOIN project_access_levels
+ ON project_members.project_access_level_id = project_access_levels.id
+ WHERE project_id = p.id
+ AND project_access_levels.key = 'PROJECT_MANAGER'
+ LIMIT 1) t) AS project_manager,
+
+ (SELECT EXISTS(SELECT 1
+ FROM project_subscribers
+ WHERE project_id = p.id
+ AND user_id = (SELECT user_id
+ FROM project_members
+ WHERE team_member_id = (SELECT id
+ FROM team_members
+ WHERE user_id IN
+ (SELECT user_id FROM is_member_of_project_cte))
+ AND project_id = p.id))) AS subscribed,
+ (SELECT name
+ FROM users
+ WHERE id =
+ (SELECT owner_id FROM projects WHERE id = p.id)) AS project_owner,
+ (SELECT default_view
+ FROM project_members
+ WHERE project_id = p.id
+ AND team_member_id IN (SELECT id FROM is_member_of_project_cte)) AS team_member_default_view,
+ (SELECT EXISTS(SELECT user_id
+ FROM archived_projects
+ WHERE user_id IN (SELECT user_id FROM is_member_of_project_cte)
+ AND project_id = p.id)) AS archived,
+
+ (SELECT EXISTS(SELECT user_id
+ FROM favorite_projects
+ WHERE user_id IN (SELECT user_id FROM is_member_of_project_cte)
+ AND project_id = p.id)) AS favorite
+
+ FROM projects p
+ LEFT JOIN sys_project_statuses ts ON p.status_id = ts.id
+ LEFT JOIN sys_project_healths h ON p.health_id = h.id
+ LEFT JOIN project_categories pc ON p.category_id = pc.id
+ LEFT JOIN clients c ON p.client_id = c.id,
+ LATERAL (SELECT id, user_id
+ FROM team_members
+ WHERE id = (SELECT team_member_id
+ FROM project_members
+ WHERE project_id = p.id
+ AND team_member_id IN (SELECT id
+ FROM team_members
+ WHERE team_id = _team_id)
+ LIMIT 1)) is_member_of_project_cte
+
+ WHERE p.id = _project_id
+ AND p.team_id = _team_id) rec;
+
+ RETURN _result;
+END
+$$;
+
+CREATE OR REPLACE FUNCTION public.get_task_form_view_model(_user_id UUID, _team_id UUID, _task_id UUID, _project_id UUID) RETURNS JSON
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _task JSON;
+ _priorities JSON;
+ _projects JSON;
+ _statuses JSON;
+ _team_members JSON;
+ _assignees JSON;
+ _phases JSON;
+BEGIN
+
+ -- Select task info
+ SELECT COALESCE(ROW_TO_JSON(rec), '{}'::JSON)
+ INTO _task
+ FROM (WITH RECURSIVE task_hierarchy AS (
+ -- Base case: Start with the given task
+ SELECT id,
+ parent_task_id,
+ 0 AS level
+ FROM tasks
+ WHERE id = _task_id
+
+ UNION ALL
+
+ -- Recursive case: Traverse up to parent tasks
+ SELECT t.id,
+ t.parent_task_id,
+ th.level + 1 AS level
+ FROM tasks t
+ INNER JOIN task_hierarchy th ON t.id = th.parent_task_id
+ WHERE th.parent_task_id IS NOT NULL)
+ SELECT id,
+ name,
+ description,
+ start_date,
+ end_date,
+ done,
+ total_minutes,
+ priority_id,
+ project_id,
+ created_at,
+ updated_at,
+ status_id,
+ parent_task_id,
+ sort_order,
+ (SELECT phase_id FROM task_phase WHERE task_id = tasks.id) AS phase_id,
+ CONCAT((SELECT key FROM projects WHERE id = tasks.project_id), '-', task_no) AS task_key,
+ (SELECT start_time
+ FROM task_timers
+ WHERE task_id = tasks.id
+ AND user_id = _user_id) AS timer_start_time,
+ parent_task_id IS NOT NULL AS is_sub_task,
+ (SELECT COUNT('*')
+ FROM tasks
+ WHERE parent_task_id = tasks.id
+ AND archived IS FALSE) AS sub_tasks_count,
+ (SELECT COUNT(*)
+ FROM tasks_with_status_view tt
+ WHERE (tt.parent_task_id = tasks.id OR tt.task_id = tasks.id)
+ AND tt.is_done IS TRUE)
+ AS completed_count,
+ (SELECT COUNT(*) FROM task_attachments WHERE task_id = tasks.id) AS attachments_count,
+ (SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(r))), '[]'::JSON)
+ FROM (SELECT task_labels.label_id AS id,
+ (SELECT name FROM team_labels WHERE id = task_labels.label_id),
+ (SELECT color_code FROM team_labels WHERE id = task_labels.label_id)
+ FROM task_labels
+ WHERE task_id = tasks.id
+ ORDER BY name) r) AS labels,
+ (SELECT color_code
+ FROM sys_task_status_categories
+ WHERE id = (SELECT category_id FROM task_statuses WHERE id = tasks.status_id)) AS status_color,
+ (SELECT COUNT(*) FROM tasks WHERE parent_task_id = _task_id) AS sub_tasks_count,
+ (SELECT name FROM users WHERE id = tasks.reporter_id) AS reporter,
+ (SELECT get_task_assignees(tasks.id)) AS assignees,
+ (SELECT id FROM team_members WHERE user_id = _user_id AND team_id = _team_id) AS team_member_id,
+ billable,
+ schedule_id,
+ progress_value,
+ weight,
+ (SELECT MAX(level) FROM task_hierarchy) AS task_level
+ FROM tasks
+ WHERE id = _task_id) rec;
+
+ SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
+ INTO _priorities
+ FROM (SELECT id, name FROM task_priorities ORDER BY value) rec;
+
+ SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
+ INTO _phases
+ FROM (SELECT id, name FROM project_phases WHERE project_id = _project_id ORDER BY name) rec;
+
+ SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
+ INTO _projects
+ FROM (SELECT id, name
+ FROM projects
+ WHERE team_id = _team_id
+ AND (CASE
+ WHEN (is_owner(_user_id, _team_id) OR is_admin(_user_id, _team_id) IS TRUE) THEN TRUE
+ ELSE is_member_of_project(projects.id, _user_id, _team_id) END)
+ ORDER BY name) rec;
+
+ SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
+ INTO _statuses
+ FROM (SELECT id, name FROM task_statuses WHERE project_id = _project_id) rec;
+
+ SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
+ INTO _team_members
+ FROM (SELECT team_members.id,
+ (SELECT name FROM team_member_info_view WHERE team_member_info_view.team_member_id = team_members.id),
+ (SELECT email FROM team_member_info_view WHERE team_member_info_view.team_member_id = team_members.id),
+ (SELECT avatar_url
+ FROM team_member_info_view
+ WHERE team_member_info_view.team_member_id = team_members.id)
+ FROM team_members
+ LEFT JOIN users u ON team_members.user_id = u.id
+ WHERE team_id = _team_id
+ AND team_members.active IS TRUE) rec;
+
+ SELECT get_task_assignees(_task_id) INTO _assignees;
+
+ RETURN JSON_BUILD_OBJECT(
+ 'task', _task,
+ 'priorities', _priorities,
+ 'projects', _projects,
+ 'statuses', _statuses,
+ 'team_members', _team_members,
+ 'assignees', _assignees,
+ 'phases', _phases
+ );
+END;
+$$;
+
+-- Add use_manual_progress, use_weighted_progress, and use_time_progress to projects table if they don't exist
+ALTER TABLE projects
+ADD COLUMN IF NOT EXISTS use_manual_progress BOOLEAN DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS use_weighted_progress BOOLEAN DEFAULT FALSE,
+ADD COLUMN IF NOT EXISTS use_time_progress BOOLEAN DEFAULT FALSE;
+
+-- Add a trigger to reset manual progress when a task gets a new subtask
+CREATE OR REPLACE FUNCTION reset_parent_task_manual_progress() RETURNS TRIGGER AS
+$$
+BEGIN
+ -- When a task gets a new subtask (parent_task_id is set), reset the parent's manual_progress flag
+ IF NEW.parent_task_id IS NOT NULL THEN
+ UPDATE tasks
+ SET manual_progress = false
+ WHERE id = NEW.parent_task_id
+ AND manual_progress = true;
+ END IF;
+ RETURN NEW;
+END;
+$$ LANGUAGE plpgsql;
+
+-- Create the trigger on the tasks table
+DROP TRIGGER IF EXISTS reset_parent_manual_progress_trigger ON tasks;
+CREATE TRIGGER reset_parent_manual_progress_trigger
+AFTER INSERT OR UPDATE OF parent_task_id ON tasks
+FOR EACH ROW
+EXECUTE FUNCTION reset_parent_task_manual_progress();
+
+COMMIT;
\ No newline at end of file
diff --git a/worklenz-backend/database/migrations/20250424000000-add-progress-and-weight-activity-types.sql b/worklenz-backend/database/migrations/20250424000000-add-progress-and-weight-activity-types.sql
new file mode 100644
index 00000000..53eafe20
--- /dev/null
+++ b/worklenz-backend/database/migrations/20250424000000-add-progress-and-weight-activity-types.sql
@@ -0,0 +1,157 @@
+-- Migration: Add progress and weight activity types support
+-- Date: 2025-04-24
+-- Version: 1.0.0
+
+BEGIN;
+
+-- Update the get_activity_logs_by_task function to handle progress and weight attribute types
+CREATE OR REPLACE FUNCTION get_activity_logs_by_task(_task_id uuid) RETURNS json
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _result JSON;
+BEGIN
+ SELECT ROW_TO_JSON(rec)
+ INTO _result
+ FROM (SELECT (SELECT tasks.created_at FROM tasks WHERE tasks.id = _task_id),
+ (SELECT name
+ FROM users
+ WHERE id = (SELECT reporter_id FROM tasks WHERE id = _task_id)),
+ (SELECT avatar_url
+ FROM users
+ WHERE id = (SELECT reporter_id FROM tasks WHERE id = _task_id)),
+ (SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec2))), '[]'::JSON)
+ FROM (SELECT task_id,
+ created_at,
+ attribute_type,
+ log_type,
+
+ -- Case for previous value
+ (CASE
+ WHEN (attribute_type = 'status')
+ THEN (SELECT name FROM task_statuses WHERE id = old_value::UUID)
+ WHEN (attribute_type = 'priority')
+ THEN (SELECT name FROM task_priorities WHERE id = old_value::UUID)
+ WHEN (attribute_type = 'phase' AND old_value <> 'Unmapped')
+ THEN (SELECT name FROM project_phases WHERE id = old_value::UUID)
+ WHEN (attribute_type = 'progress' OR attribute_type = 'weight')
+ THEN old_value
+ ELSE (old_value) END) AS previous,
+
+ -- Case for current value
+ (CASE
+ WHEN (attribute_type = 'assignee')
+ THEN (SELECT name FROM users WHERE id = new_value::UUID)
+ WHEN (attribute_type = 'label')
+ THEN (SELECT name FROM team_labels WHERE id = new_value::UUID)
+ WHEN (attribute_type = 'status')
+ THEN (SELECT name FROM task_statuses WHERE id = new_value::UUID)
+ WHEN (attribute_type = 'priority')
+ THEN (SELECT name FROM task_priorities WHERE id = new_value::UUID)
+ WHEN (attribute_type = 'phase' AND new_value <> 'Unmapped')
+ THEN (SELECT name FROM project_phases WHERE id = new_value::UUID)
+ WHEN (attribute_type = 'progress' OR attribute_type = 'weight')
+ THEN new_value
+ ELSE (new_value) END) AS current,
+
+ -- Case for assigned user
+ (CASE
+ WHEN (attribute_type = 'assignee')
+ THEN (SELECT ROW_TO_JSON(rec)
+ FROM (SELECT (CASE
+ WHEN (new_value IS NOT NULL)
+ THEN (SELECT name FROM users WHERE users.id = new_value::UUID)
+ ELSE (next_string) END) AS name,
+ (SELECT avatar_url FROM users WHERE users.id = new_value::UUID)) rec)
+ ELSE (NULL) END) AS assigned_user,
+
+ -- Case for label data
+ (CASE
+ WHEN (attribute_type = 'label')
+ THEN (SELECT ROW_TO_JSON(rec)
+ FROM (SELECT (SELECT name FROM team_labels WHERE id = new_value::UUID),
+ (SELECT color_code FROM team_labels WHERE id = new_value::UUID)) rec)
+ ELSE (NULL) END) AS label_data,
+
+ -- Case for previous status
+ (CASE
+ WHEN (attribute_type = 'status')
+ THEN (SELECT ROW_TO_JSON(rec)
+ FROM (SELECT (SELECT name FROM task_statuses WHERE id = old_value::UUID),
+ (SELECT color_code
+ FROM sys_task_status_categories
+ WHERE id = (SELECT category_id FROM task_statuses WHERE id = old_value::UUID)),
+ (SELECT color_code_dark
+ FROM sys_task_status_categories
+ WHERE id = (SELECT category_id FROM task_statuses WHERE id = old_value::UUID))) rec)
+ ELSE (NULL) END) AS previous_status,
+
+ -- Case for next status
+ (CASE
+ WHEN (attribute_type = 'status')
+ THEN (SELECT ROW_TO_JSON(rec)
+ FROM (SELECT (SELECT name FROM task_statuses WHERE id = new_value::UUID),
+ (SELECT color_code
+ FROM sys_task_status_categories
+ WHERE id = (SELECT category_id FROM task_statuses WHERE id = new_value::UUID)),
+ (SELECT color_code_dark
+ FROM sys_task_status_categories
+ WHERE id = (SELECT category_id FROM task_statuses WHERE id = new_value::UUID))) rec)
+ ELSE (NULL) END) AS next_status,
+
+ -- Case for previous priority
+ (CASE
+ WHEN (attribute_type = 'priority')
+ THEN (SELECT ROW_TO_JSON(rec)
+ FROM (SELECT (SELECT name FROM task_priorities WHERE id = old_value::UUID),
+ (SELECT color_code FROM task_priorities WHERE id = old_value::UUID)) rec)
+ ELSE (NULL) END) AS previous_priority,
+
+ -- Case for next priority
+ (CASE
+ WHEN (attribute_type = 'priority')
+ THEN (SELECT ROW_TO_JSON(rec)
+ FROM (SELECT (SELECT name FROM task_priorities WHERE id = new_value::UUID),
+ (SELECT color_code FROM task_priorities WHERE id = new_value::UUID)) rec)
+ ELSE (NULL) END) AS next_priority,
+
+ -- Case for previous phase
+ (CASE
+ WHEN (attribute_type = 'phase' AND old_value <> 'Unmapped')
+ THEN (SELECT ROW_TO_JSON(rec)
+ FROM (SELECT (SELECT name FROM project_phases WHERE id = old_value::UUID),
+ (SELECT color_code FROM project_phases WHERE id = old_value::UUID)) rec)
+ ELSE (NULL) END) AS previous_phase,
+
+ -- Case for next phase
+ (CASE
+ WHEN (attribute_type = 'phase' AND new_value <> 'Unmapped')
+ THEN (SELECT ROW_TO_JSON(rec)
+ FROM (SELECT (SELECT name FROM project_phases WHERE id = new_value::UUID),
+ (SELECT color_code FROM project_phases WHERE id = new_value::UUID)) rec)
+ ELSE (NULL) END) AS next_phase,
+
+ -- Case for done by
+ (SELECT ROW_TO_JSON(rec)
+ FROM (SELECT (SELECT name FROM users WHERE users.id = tal.user_id),
+ (SELECT avatar_url FROM users WHERE users.id = tal.user_id)) rec) AS done_by,
+
+ -- Add log text for progress and weight
+ (CASE
+ WHEN (attribute_type = 'progress')
+ THEN 'updated the progress of'
+ WHEN (attribute_type = 'weight')
+ THEN 'updated the weight of'
+ ELSE ''
+ END) AS log_text
+
+
+ FROM task_activity_logs tal
+ WHERE task_id = _task_id
+ ORDER BY created_at DESC) rec2) AS logs) rec;
+ RETURN _result;
+END;
+$$;
+
+COMMIT;
\ No newline at end of file
diff --git a/worklenz-backend/database/migrations/20250425000000-update-time-based-progress.sql b/worklenz-backend/database/migrations/20250425000000-update-time-based-progress.sql
new file mode 100644
index 00000000..7b02bef7
--- /dev/null
+++ b/worklenz-backend/database/migrations/20250425000000-update-time-based-progress.sql
@@ -0,0 +1,243 @@
+-- Migration: Update time-based progress mode to work for all tasks
+-- Date: 2025-04-25
+-- Version: 1.0.0
+
+BEGIN;
+
+-- Update function to use time-based progress for all tasks
+CREATE OR REPLACE FUNCTION get_task_complete_ratio(_task_id uuid) RETURNS json
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _parent_task_done FLOAT = 0;
+ _sub_tasks_done FLOAT = 0;
+ _sub_tasks_count FLOAT = 0;
+ _total_completed FLOAT = 0;
+ _total_tasks FLOAT = 0;
+ _ratio FLOAT = 0;
+ _is_manual BOOLEAN = FALSE;
+ _manual_value INTEGER = NULL;
+ _project_id UUID;
+ _use_manual_progress BOOLEAN = FALSE;
+ _use_weighted_progress BOOLEAN = FALSE;
+ _use_time_progress BOOLEAN = FALSE;
+ _task_complete BOOLEAN = FALSE;
+BEGIN
+ -- Check if manual progress is set for this task
+ SELECT manual_progress, progress_value, project_id,
+ EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = tasks.id
+ AND is_done IS TRUE
+ ) AS is_complete
+ FROM tasks
+ WHERE id = _task_id
+ INTO _is_manual, _manual_value, _project_id, _task_complete;
+
+ -- Check if the project uses manual progress
+ IF _project_id IS NOT NULL THEN
+ SELECT COALESCE(use_manual_progress, FALSE),
+ COALESCE(use_weighted_progress, FALSE),
+ COALESCE(use_time_progress, FALSE)
+ FROM projects
+ WHERE id = _project_id
+ INTO _use_manual_progress, _use_weighted_progress, _use_time_progress;
+ END IF;
+
+ -- Get all subtasks
+ SELECT COUNT(*)
+ FROM tasks
+ WHERE parent_task_id = _task_id AND archived IS FALSE
+ INTO _sub_tasks_count;
+
+ -- If task is complete, always return 100%
+ IF _task_complete IS TRUE THEN
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', 100,
+ 'total_completed', 1,
+ 'total_tasks', 1,
+ 'is_manual', FALSE
+ );
+ END IF;
+
+ -- Use manual progress value in two cases:
+ -- 1. When task has manual_progress = TRUE and progress_value is set
+ -- 2. When project has use_manual_progress = TRUE and progress_value is set
+ IF (_is_manual IS TRUE AND _manual_value IS NOT NULL) OR
+ (_use_manual_progress IS TRUE AND _manual_value IS NOT NULL) THEN
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', _manual_value,
+ 'total_completed', 0,
+ 'total_tasks', 0,
+ 'is_manual', TRUE
+ );
+ END IF;
+
+ -- If there are no subtasks, just use the parent task's status (unless in time-based mode)
+ IF _sub_tasks_count = 0 THEN
+ -- Use time-based estimation for tasks without subtasks if enabled
+ IF _use_time_progress IS TRUE THEN
+ -- For time-based tasks without subtasks, we still need some progress calculation
+ -- If the task is completed, return 100%
+ -- Otherwise, use the progress value if set manually, or 0
+ SELECT
+ CASE
+ WHEN _task_complete IS TRUE THEN 100
+ ELSE COALESCE(_manual_value, 0)
+ END
+ INTO _ratio;
+ ELSE
+ -- Traditional calculation for non-time-based tasks
+ SELECT (CASE WHEN _task_complete IS TRUE THEN 1 ELSE 0 END)
+ INTO _parent_task_done;
+
+ _ratio = _parent_task_done * 100;
+ END IF;
+ ELSE
+ -- If project uses manual progress, calculate based on subtask manual progress values
+ IF _use_manual_progress IS TRUE THEN
+ WITH subtask_progress AS (
+ SELECT
+ t.id,
+ t.manual_progress,
+ t.progress_value,
+ EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) AS is_complete
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ ),
+ subtask_with_values AS (
+ SELECT
+ CASE
+ -- For completed tasks, always use 100%
+ WHEN is_complete IS TRUE THEN 100
+ -- For tasks with progress value set, use it regardless of manual_progress flag
+ WHEN progress_value IS NOT NULL THEN progress_value
+ -- Default to 0 for incomplete tasks with no progress value
+ ELSE 0
+ END AS progress_value
+ FROM subtask_progress
+ )
+ SELECT COALESCE(AVG(progress_value), 0)
+ FROM subtask_with_values
+ INTO _ratio;
+ -- If project uses weighted progress, calculate based on subtask weights
+ ELSIF _use_weighted_progress IS TRUE THEN
+ WITH subtask_progress AS (
+ SELECT
+ t.id,
+ t.manual_progress,
+ t.progress_value,
+ EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) AS is_complete,
+ COALESCE(t.weight, 100) AS weight
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ ),
+ subtask_with_values AS (
+ SELECT
+ CASE
+ -- For completed tasks, always use 100%
+ WHEN is_complete IS TRUE THEN 100
+ -- For tasks with progress value set, use it regardless of manual_progress flag
+ WHEN progress_value IS NOT NULL THEN progress_value
+ -- Default to 0 for incomplete tasks with no progress value
+ ELSE 0
+ END AS progress_value,
+ weight
+ FROM subtask_progress
+ )
+ SELECT COALESCE(
+ SUM(progress_value * weight) / NULLIF(SUM(weight), 0),
+ 0
+ )
+ FROM subtask_with_values
+ INTO _ratio;
+ -- If project uses time-based progress, calculate based on estimated time
+ ELSIF _use_time_progress IS TRUE THEN
+ WITH subtask_progress AS (
+ SELECT
+ t.id,
+ t.manual_progress,
+ t.progress_value,
+ EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) AS is_complete,
+ COALESCE(t.total_minutes, 0) AS estimated_minutes
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ ),
+ subtask_with_values AS (
+ SELECT
+ CASE
+ -- For completed tasks, always use 100%
+ WHEN is_complete IS TRUE THEN 100
+ -- For tasks with progress value set, use it regardless of manual_progress flag
+ WHEN progress_value IS NOT NULL THEN progress_value
+ -- Default to 0 for incomplete tasks with no progress value
+ ELSE 0
+ END AS progress_value,
+ estimated_minutes
+ FROM subtask_progress
+ )
+ SELECT COALESCE(
+ SUM(progress_value * estimated_minutes) / NULLIF(SUM(estimated_minutes), 0),
+ 0
+ )
+ FROM subtask_with_values
+ INTO _ratio;
+ ELSE
+ -- Traditional calculation based on completion status
+ SELECT (CASE WHEN _task_complete IS TRUE THEN 1 ELSE 0 END)
+ INTO _parent_task_done;
+
+ SELECT COUNT(*)
+ FROM tasks_with_status_view
+ WHERE parent_task_id = _task_id
+ AND is_done IS TRUE
+ INTO _sub_tasks_done;
+
+ _total_completed = _parent_task_done + _sub_tasks_done;
+ _total_tasks = _sub_tasks_count + 1; -- +1 for the parent task
+
+ IF _total_tasks = 0 THEN
+ _ratio = 0;
+ ELSE
+ _ratio = (_total_completed / _total_tasks) * 100;
+ END IF;
+ END IF;
+ END IF;
+
+ -- Ensure ratio is between 0 and 100
+ IF _ratio < 0 THEN
+ _ratio = 0;
+ ELSIF _ratio > 100 THEN
+ _ratio = 100;
+ END IF;
+
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', _ratio,
+ 'total_completed', _total_completed,
+ 'total_tasks', _total_tasks,
+ 'is_manual', _is_manual
+ );
+END
+$$;
+
+COMMIT;
\ No newline at end of file
diff --git a/worklenz-backend/database/migrations/20250426000000-improve-parent-task-progress-calculation.sql b/worklenz-backend/database/migrations/20250426000000-improve-parent-task-progress-calculation.sql
new file mode 100644
index 00000000..e1d5d1f2
--- /dev/null
+++ b/worklenz-backend/database/migrations/20250426000000-improve-parent-task-progress-calculation.sql
@@ -0,0 +1,289 @@
+-- Migration: Improve parent task progress calculation using weights and time estimation
+-- Date: 2025-04-26
+-- Version: 1.0.0
+
+BEGIN;
+
+-- Update function to better calculate parent task progress based on subtask weights or time estimations
+CREATE OR REPLACE FUNCTION get_task_complete_ratio(_task_id uuid) RETURNS json
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _parent_task_done FLOAT = 0;
+ _sub_tasks_done FLOAT = 0;
+ _sub_tasks_count FLOAT = 0;
+ _total_completed FLOAT = 0;
+ _total_tasks FLOAT = 0;
+ _ratio FLOAT = 0;
+ _is_manual BOOLEAN = FALSE;
+ _manual_value INTEGER = NULL;
+ _project_id UUID;
+ _use_manual_progress BOOLEAN = FALSE;
+ _use_weighted_progress BOOLEAN = FALSE;
+ _use_time_progress BOOLEAN = FALSE;
+BEGIN
+ -- Check if manual progress is set for this task
+ SELECT manual_progress, progress_value, project_id
+ FROM tasks
+ WHERE id = _task_id
+ INTO _is_manual, _manual_value, _project_id;
+
+ -- Check if the project uses manual progress
+ IF _project_id IS NOT NULL THEN
+ SELECT COALESCE(use_manual_progress, FALSE),
+ COALESCE(use_weighted_progress, FALSE),
+ COALESCE(use_time_progress, FALSE)
+ FROM projects
+ WHERE id = _project_id
+ INTO _use_manual_progress, _use_weighted_progress, _use_time_progress;
+ END IF;
+
+ -- Get all subtasks
+ SELECT COUNT(*)
+ FROM tasks
+ WHERE parent_task_id = _task_id AND archived IS FALSE
+ INTO _sub_tasks_count;
+
+ -- Only respect manual progress for tasks without subtasks
+ IF _is_manual IS TRUE AND _manual_value IS NOT NULL AND _sub_tasks_count = 0 THEN
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', _manual_value,
+ 'total_completed', 0,
+ 'total_tasks', 0,
+ 'is_manual', TRUE
+ );
+ END IF;
+
+ -- If there are no subtasks, just use the parent task's status
+ IF _sub_tasks_count = 0 THEN
+ -- For tasks without subtasks in time-based mode
+ IF _use_time_progress IS TRUE THEN
+ SELECT
+ CASE
+ WHEN EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = _task_id
+ AND is_done IS TRUE
+ ) THEN 100
+ ELSE COALESCE(_manual_value, 0)
+ END
+ INTO _ratio;
+ ELSE
+ -- Traditional calculation for non-time-based tasks
+ SELECT (CASE
+ WHEN EXISTS(SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = _task_id
+ AND is_done IS TRUE) THEN 1
+ ELSE 0 END)
+ INTO _parent_task_done;
+
+ _ratio = _parent_task_done * 100;
+ END IF;
+ ELSE
+ -- For parent tasks with subtasks, always use the appropriate calculation based on project mode
+ -- If project uses manual progress, calculate based on subtask manual progress values
+ IF _use_manual_progress IS TRUE THEN
+ WITH subtask_progress AS (
+ SELECT
+ CASE
+ -- If subtask has manual progress, use that value
+ WHEN manual_progress IS TRUE AND progress_value IS NOT NULL THEN
+ progress_value
+ -- Otherwise use completion status (0 or 100)
+ ELSE
+ CASE
+ WHEN EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) THEN 100
+ ELSE 0
+ END
+ END AS progress_value
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ )
+ SELECT COALESCE(AVG(progress_value), 0)
+ FROM subtask_progress
+ INTO _ratio;
+ -- If project uses weighted progress, calculate based on subtask weights
+ ELSIF _use_weighted_progress IS TRUE THEN
+ WITH subtask_progress AS (
+ SELECT
+ CASE
+ -- If subtask has manual progress, use that value
+ WHEN manual_progress IS TRUE AND progress_value IS NOT NULL THEN
+ progress_value
+ -- Otherwise use completion status (0 or 100)
+ ELSE
+ CASE
+ WHEN EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) THEN 100
+ ELSE 0
+ END
+ END AS progress_value,
+ COALESCE(weight, 100) AS weight -- Default weight is 100 if not specified
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ )
+ SELECT COALESCE(
+ SUM(progress_value * weight) / NULLIF(SUM(weight), 0),
+ 0
+ )
+ FROM subtask_progress
+ INTO _ratio;
+ -- If project uses time-based progress, calculate based on estimated time (total_minutes)
+ ELSIF _use_time_progress IS TRUE THEN
+ WITH subtask_progress AS (
+ SELECT
+ CASE
+ -- If subtask has manual progress, use that value
+ WHEN manual_progress IS TRUE AND progress_value IS NOT NULL THEN
+ progress_value
+ -- Otherwise use completion status (0 or 100)
+ ELSE
+ CASE
+ WHEN EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) THEN 100
+ ELSE 0
+ END
+ END AS progress_value,
+ COALESCE(total_minutes, 0) AS estimated_minutes -- Use time estimation for weighting
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ )
+ SELECT COALESCE(
+ SUM(progress_value * estimated_minutes) / NULLIF(SUM(estimated_minutes), 0),
+ 0
+ )
+ FROM subtask_progress
+ INTO _ratio;
+ ELSE
+ -- Traditional calculation based on completion status when no special mode is enabled
+ SELECT (CASE
+ WHEN EXISTS(SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = _task_id
+ AND is_done IS TRUE) THEN 1
+ ELSE 0 END)
+ INTO _parent_task_done;
+
+ SELECT COUNT(*)
+ FROM tasks_with_status_view
+ WHERE parent_task_id = _task_id
+ AND is_done IS TRUE
+ INTO _sub_tasks_done;
+
+ _total_completed = _parent_task_done + _sub_tasks_done;
+ _total_tasks = _sub_tasks_count + 1; -- +1 for the parent task
+
+ IF _total_tasks = 0 THEN
+ _ratio = 0;
+ ELSE
+ _ratio = (_total_completed / _total_tasks) * 100;
+ END IF;
+ END IF;
+ END IF;
+
+ -- Ensure ratio is between 0 and 100
+ IF _ratio < 0 THEN
+ _ratio = 0;
+ ELSIF _ratio > 100 THEN
+ _ratio = 100;
+ END IF;
+
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', _ratio,
+ 'total_completed', _total_completed,
+ 'total_tasks', _total_tasks,
+ 'is_manual', _is_manual
+ );
+END
+$$;
+
+-- Make sure we recalculate parent task progress when subtask progress changes
+CREATE OR REPLACE FUNCTION update_parent_task_progress() RETURNS TRIGGER AS
+$$
+DECLARE
+ _parent_task_id UUID;
+ _project_id UUID;
+ _ratio FLOAT;
+BEGIN
+ -- Check if this is a subtask
+ IF NEW.parent_task_id IS NOT NULL THEN
+ _parent_task_id := NEW.parent_task_id;
+
+ -- Force any parent task with subtasks to NOT use manual progress
+ UPDATE tasks
+ SET manual_progress = FALSE
+ WHERE id = _parent_task_id;
+ END IF;
+
+ -- If this task has progress value of 100 and doesn't have subtasks, we might want to prompt the user
+ -- to mark it as done. We'll annotate this in a way that the socket handler can detect.
+ IF NEW.progress_value = 100 OR NEW.weight = 100 OR NEW.total_minutes > 0 THEN
+ -- Check if task has status in "done" category
+ SELECT project_id FROM tasks WHERE id = NEW.id INTO _project_id;
+
+ -- Get the progress ratio for this task
+ SELECT get_task_complete_ratio(NEW.id)->>'ratio' INTO _ratio;
+
+ IF _ratio::FLOAT >= 100 THEN
+ -- Log that this task is at 100% progress
+ RAISE NOTICE 'Task % progress is at 100%%, may need status update', NEW.id;
+ END IF;
+ END IF;
+
+ RETURN NEW;
+END;
+$$ LANGUAGE plpgsql;
+
+-- Create trigger for updates to task progress
+DROP TRIGGER IF EXISTS update_parent_task_progress_trigger ON tasks;
+CREATE TRIGGER update_parent_task_progress_trigger
+AFTER UPDATE OF progress_value, weight, total_minutes ON tasks
+FOR EACH ROW
+EXECUTE FUNCTION update_parent_task_progress();
+
+-- Create a function to ensure parent tasks never have manual progress when they have subtasks
+CREATE OR REPLACE FUNCTION ensure_parent_task_without_manual_progress() RETURNS TRIGGER AS
+$$
+BEGIN
+ -- If this is a new subtask being created or a task is being converted to a subtask
+ IF NEW.parent_task_id IS NOT NULL THEN
+ -- Force the parent task to NOT use manual progress
+ UPDATE tasks
+ SET manual_progress = FALSE
+ WHERE id = NEW.parent_task_id;
+
+ -- Log that we've reset manual progress for a parent task
+ RAISE NOTICE 'Reset manual progress for parent task % because it has subtasks', NEW.parent_task_id;
+ END IF;
+
+ RETURN NEW;
+END;
+$$ LANGUAGE plpgsql;
+
+-- Create trigger for when tasks are created or updated with a parent_task_id
+DROP TRIGGER IF EXISTS ensure_parent_task_without_manual_progress_trigger ON tasks;
+CREATE TRIGGER ensure_parent_task_without_manual_progress_trigger
+AFTER INSERT OR UPDATE OF parent_task_id ON tasks
+FOR EACH ROW
+EXECUTE FUNCTION ensure_parent_task_without_manual_progress();
+
+COMMIT;
\ No newline at end of file
diff --git a/worklenz-backend/database/migrations/20250426000000-update-progress-mode-handlers.sql b/worklenz-backend/database/migrations/20250426000000-update-progress-mode-handlers.sql
new file mode 100644
index 00000000..7f16670b
--- /dev/null
+++ b/worklenz-backend/database/migrations/20250426000000-update-progress-mode-handlers.sql
@@ -0,0 +1,150 @@
+-- Migration: Update socket event handlers to set progress-mode handlers
+-- Date: 2025-04-26
+-- Version: 1.0.0
+
+BEGIN;
+
+-- Create ENUM type for progress modes
+CREATE TYPE progress_mode_type AS ENUM ('manual', 'weighted', 'time', 'default');
+
+-- Alter tasks table to use ENUM type
+ALTER TABLE tasks
+ALTER COLUMN progress_mode TYPE progress_mode_type
+USING progress_mode::text::progress_mode_type;
+
+-- Update the on_update_task_progress function to set progress_mode
+CREATE OR REPLACE FUNCTION on_update_task_progress(_body json) RETURNS json
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _task_id UUID;
+ _progress_value INTEGER;
+ _parent_task_id UUID;
+ _project_id UUID;
+ _current_mode progress_mode_type;
+BEGIN
+ _task_id = (_body ->> 'task_id')::UUID;
+ _progress_value = (_body ->> 'progress_value')::INTEGER;
+ _parent_task_id = (_body ->> 'parent_task_id')::UUID;
+
+ -- Get the project ID and determine the current progress mode
+ SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
+
+ IF _project_id IS NOT NULL THEN
+ SELECT
+ CASE
+ WHEN use_manual_progress IS TRUE THEN 'manual'
+ WHEN use_weighted_progress IS TRUE THEN 'weighted'
+ WHEN use_time_progress IS TRUE THEN 'time'
+ ELSE 'default'
+ END
+ INTO _current_mode
+ FROM projects
+ WHERE id = _project_id;
+ ELSE
+ _current_mode := 'default';
+ END IF;
+
+ -- Update the task with progress value and set the progress mode
+ UPDATE tasks
+ SET progress_value = _progress_value,
+ manual_progress = TRUE,
+ progress_mode = _current_mode,
+ updated_at = CURRENT_TIMESTAMP
+ WHERE id = _task_id;
+
+ -- Return the updated task info
+ RETURN JSON_BUILD_OBJECT(
+ 'task_id', _task_id,
+ 'progress_value', _progress_value,
+ 'progress_mode', _current_mode
+ );
+END;
+$$;
+
+-- Update the on_update_task_weight function to set progress_mode when weight is updated
+CREATE OR REPLACE FUNCTION on_update_task_weight(_body json) RETURNS json
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _task_id UUID;
+ _weight INTEGER;
+ _parent_task_id UUID;
+ _project_id UUID;
+BEGIN
+ _task_id = (_body ->> 'task_id')::UUID;
+ _weight = (_body ->> 'weight')::INTEGER;
+ _parent_task_id = (_body ->> 'parent_task_id')::UUID;
+
+ -- Get the project ID
+ SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
+
+ -- Update the task with weight value and set progress_mode to 'weighted'
+ UPDATE tasks
+ SET weight = _weight,
+ progress_mode = 'weighted',
+ updated_at = CURRENT_TIMESTAMP
+ WHERE id = _task_id;
+
+ -- Return the updated task info
+ RETURN JSON_BUILD_OBJECT(
+ 'task_id', _task_id,
+ 'weight', _weight
+ );
+END;
+$$;
+
+-- Create a function to reset progress values when switching project progress modes
+CREATE OR REPLACE FUNCTION reset_project_progress_values() RETURNS TRIGGER
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _old_mode progress_mode_type;
+ _new_mode progress_mode_type;
+ _project_id UUID;
+BEGIN
+ _project_id := NEW.id;
+
+ -- Determine old and new modes
+ _old_mode :=
+ CASE
+ WHEN OLD.use_manual_progress IS TRUE THEN 'manual'
+ WHEN OLD.use_weighted_progress IS TRUE THEN 'weighted'
+ WHEN OLD.use_time_progress IS TRUE THEN 'time'
+ ELSE 'default'
+ END;
+
+ _new_mode :=
+ CASE
+ WHEN NEW.use_manual_progress IS TRUE THEN 'manual'
+ WHEN NEW.use_weighted_progress IS TRUE THEN 'weighted'
+ WHEN NEW.use_time_progress IS TRUE THEN 'time'
+ ELSE 'default'
+ END;
+
+ -- If mode has changed, reset progress values for tasks with the old mode
+ IF _old_mode <> _new_mode THEN
+ -- Reset progress values for tasks that were set in the old mode
+ UPDATE tasks
+ SET progress_value = NULL,
+ progress_mode = NULL
+ WHERE project_id = _project_id
+ AND progress_mode = _old_mode;
+ END IF;
+
+ RETURN NEW;
+END;
+$$;
+
+-- Create trigger to reset progress values when project progress mode changes
+DROP TRIGGER IF EXISTS reset_progress_on_mode_change ON projects;
+CREATE TRIGGER reset_progress_on_mode_change
+ AFTER UPDATE OF use_manual_progress, use_weighted_progress, use_time_progress
+ ON projects
+ FOR EACH ROW
+ EXECUTE FUNCTION reset_project_progress_values();
+
+COMMIT;
\ No newline at end of file
diff --git a/worklenz-backend/database/migrations/20250427000000-fix-progress-mode-type.sql b/worklenz-backend/database/migrations/20250427000000-fix-progress-mode-type.sql
new file mode 100644
index 00000000..6e5efc9d
--- /dev/null
+++ b/worklenz-backend/database/migrations/20250427000000-fix-progress-mode-type.sql
@@ -0,0 +1,160 @@
+-- Migration: Fix progress_mode_type ENUM and casting issues
+-- Date: 2025-04-27
+-- Version: 1.0.0
+
+BEGIN;
+
+-- First, let's ensure the ENUM type exists with the correct values
+DO $$
+BEGIN
+ -- Check if the type exists
+ IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'progress_mode_type') THEN
+ CREATE TYPE progress_mode_type AS ENUM ('manual', 'weighted', 'time', 'default');
+ ELSE
+ -- Add any missing values to the existing ENUM
+ BEGIN
+ ALTER TYPE progress_mode_type ADD VALUE IF NOT EXISTS 'manual';
+ ALTER TYPE progress_mode_type ADD VALUE IF NOT EXISTS 'weighted';
+ ALTER TYPE progress_mode_type ADD VALUE IF NOT EXISTS 'time';
+ ALTER TYPE progress_mode_type ADD VALUE IF NOT EXISTS 'default';
+ EXCEPTION
+ WHEN duplicate_object THEN
+ -- Ignore if values already exist
+ NULL;
+ END;
+ END IF;
+END $$;
+
+-- Update functions to use proper type casting
+CREATE OR REPLACE FUNCTION on_update_task_progress(_body json) RETURNS json
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _task_id UUID;
+ _progress_value INTEGER;
+ _parent_task_id UUID;
+ _project_id UUID;
+ _current_mode progress_mode_type;
+BEGIN
+ _task_id = (_body ->> 'task_id')::UUID;
+ _progress_value = (_body ->> 'progress_value')::INTEGER;
+ _parent_task_id = (_body ->> 'parent_task_id')::UUID;
+
+ -- Get the project ID and determine the current progress mode
+ SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
+
+ IF _project_id IS NOT NULL THEN
+ SELECT
+ CASE
+ WHEN use_manual_progress IS TRUE THEN 'manual'::progress_mode_type
+ WHEN use_weighted_progress IS TRUE THEN 'weighted'::progress_mode_type
+ WHEN use_time_progress IS TRUE THEN 'time'::progress_mode_type
+ ELSE 'default'::progress_mode_type
+ END
+ INTO _current_mode
+ FROM projects
+ WHERE id = _project_id;
+ ELSE
+ _current_mode := 'default'::progress_mode_type;
+ END IF;
+
+ -- Update the task with progress value and set the progress mode
+ UPDATE tasks
+ SET progress_value = _progress_value,
+ manual_progress = TRUE,
+ progress_mode = _current_mode,
+ updated_at = CURRENT_TIMESTAMP
+ WHERE id = _task_id;
+
+ -- Return the updated task info
+ RETURN JSON_BUILD_OBJECT(
+ 'task_id', _task_id,
+ 'progress_value', _progress_value,
+ 'progress_mode', _current_mode
+ );
+END;
+$$;
+
+-- Update the on_update_task_weight function to use proper type casting
+CREATE OR REPLACE FUNCTION on_update_task_weight(_body json) RETURNS json
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _task_id UUID;
+ _weight INTEGER;
+ _parent_task_id UUID;
+ _project_id UUID;
+BEGIN
+ _task_id = (_body ->> 'task_id')::UUID;
+ _weight = (_body ->> 'weight')::INTEGER;
+ _parent_task_id = (_body ->> 'parent_task_id')::UUID;
+
+ -- Get the project ID
+ SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
+
+ -- Update the task with weight value and set progress_mode to 'weighted'
+ UPDATE tasks
+ SET weight = _weight,
+ progress_mode = 'weighted'::progress_mode_type,
+ updated_at = CURRENT_TIMESTAMP
+ WHERE id = _task_id;
+
+ -- Return the updated task info
+ RETURN JSON_BUILD_OBJECT(
+ 'task_id', _task_id,
+ 'weight', _weight
+ );
+END;
+$$;
+
+-- Update the reset_project_progress_values function to use proper type casting
+CREATE OR REPLACE FUNCTION reset_project_progress_values() RETURNS TRIGGER
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _old_mode progress_mode_type;
+ _new_mode progress_mode_type;
+ _project_id UUID;
+BEGIN
+ _project_id := NEW.id;
+
+ -- Determine old and new modes with proper type casting
+ _old_mode :=
+ CASE
+ WHEN OLD.use_manual_progress IS TRUE THEN 'manual'::progress_mode_type
+ WHEN OLD.use_weighted_progress IS TRUE THEN 'weighted'::progress_mode_type
+ WHEN OLD.use_time_progress IS TRUE THEN 'time'::progress_mode_type
+ ELSE 'default'::progress_mode_type
+ END;
+
+ _new_mode :=
+ CASE
+ WHEN NEW.use_manual_progress IS TRUE THEN 'manual'::progress_mode_type
+ WHEN NEW.use_weighted_progress IS TRUE THEN 'weighted'::progress_mode_type
+ WHEN NEW.use_time_progress IS TRUE THEN 'time'::progress_mode_type
+ ELSE 'default'::progress_mode_type
+ END;
+
+ -- If mode has changed, reset progress values for tasks with the old mode
+ IF _old_mode <> _new_mode THEN
+ -- Reset progress values for tasks that were set in the old mode
+ UPDATE tasks
+ SET progress_value = NULL,
+ progress_mode = NULL
+ WHERE project_id = _project_id
+ AND progress_mode::text::progress_mode_type = _old_mode;
+ END IF;
+
+ RETURN NEW;
+END;
+$$;
+
+-- Update the tasks table to ensure proper type casting for existing values
+UPDATE tasks
+SET progress_mode = progress_mode::text::progress_mode_type
+WHERE progress_mode IS NOT NULL;
+
+COMMIT;
\ No newline at end of file
diff --git a/worklenz-backend/database/migrations/20250506000000-fix-multilevel-subtask-progress-calculation.sql b/worklenz-backend/database/migrations/20250506000000-fix-multilevel-subtask-progress-calculation.sql
new file mode 100644
index 00000000..1a8d4cba
--- /dev/null
+++ b/worklenz-backend/database/migrations/20250506000000-fix-multilevel-subtask-progress-calculation.sql
@@ -0,0 +1,166 @@
+-- Migration: Fix multilevel subtask progress calculation for weighted and manual progress
+-- Date: 2025-05-06
+-- Version: 1.0.0
+
+BEGIN;
+
+-- Update the trigger function to recursively recalculate parent task progress up the entire hierarchy
+CREATE OR REPLACE FUNCTION update_parent_task_progress() RETURNS TRIGGER AS
+$$
+DECLARE
+ _parent_task_id UUID;
+ _project_id UUID;
+ _ratio FLOAT;
+BEGIN
+ -- Check if this is a subtask
+ IF NEW.parent_task_id IS NOT NULL THEN
+ _parent_task_id := NEW.parent_task_id;
+
+ -- Force any parent task with subtasks to NOT use manual progress
+ UPDATE tasks
+ SET manual_progress = FALSE
+ WHERE id = _parent_task_id;
+
+ -- Calculate and update the parent's progress value
+ SELECT (get_task_complete_ratio(_parent_task_id)->>'ratio')::FLOAT INTO _ratio;
+
+ -- Update the parent's progress value
+ UPDATE tasks
+ SET progress_value = _ratio
+ WHERE id = _parent_task_id;
+
+ -- Recursively propagate changes up the hierarchy by using a recursive CTE
+ WITH RECURSIVE task_hierarchy AS (
+ -- Base case: Start with the parent task
+ SELECT
+ id,
+ parent_task_id
+ FROM tasks
+ WHERE id = _parent_task_id
+
+ UNION ALL
+
+ -- Recursive case: Go up to each ancestor
+ SELECT
+ t.id,
+ t.parent_task_id
+ FROM tasks t
+ JOIN task_hierarchy th ON t.id = th.parent_task_id
+ WHERE t.id IS NOT NULL
+ )
+ -- For each ancestor, recalculate its progress
+ UPDATE tasks
+ SET
+ manual_progress = FALSE,
+ progress_value = (SELECT (get_task_complete_ratio(task_hierarchy.id)->>'ratio')::FLOAT)
+ FROM task_hierarchy
+ WHERE tasks.id = task_hierarchy.id
+ AND task_hierarchy.parent_task_id IS NOT NULL;
+
+ -- Log the recalculation for debugging
+ RAISE NOTICE 'Updated progress for task % to %', _parent_task_id, _ratio;
+ END IF;
+
+ -- If this task has progress value of 100 and doesn't have subtasks, we might want to prompt the user
+ -- to mark it as done. We'll annotate this in a way that the socket handler can detect.
+ IF NEW.progress_value = 100 OR NEW.weight = 100 OR NEW.total_minutes > 0 THEN
+ -- Check if task has status in "done" category
+ SELECT project_id FROM tasks WHERE id = NEW.id INTO _project_id;
+
+ -- Get the progress ratio for this task
+ SELECT (get_task_complete_ratio(NEW.id)->>'ratio')::FLOAT INTO _ratio;
+
+ IF _ratio >= 100 THEN
+ -- Log that this task is at 100% progress
+ RAISE NOTICE 'Task % progress is at 100%%, may need status update', NEW.id;
+ END IF;
+ END IF;
+
+ RETURN NEW;
+END;
+$$ LANGUAGE plpgsql;
+
+-- Update existing trigger or create a new one to handle more changes
+DROP TRIGGER IF EXISTS update_parent_task_progress_trigger ON tasks;
+CREATE TRIGGER update_parent_task_progress_trigger
+AFTER UPDATE OF progress_value, weight, total_minutes, parent_task_id, manual_progress ON tasks
+FOR EACH ROW
+EXECUTE FUNCTION update_parent_task_progress();
+
+-- Also add a trigger for when a new task is inserted
+DROP TRIGGER IF EXISTS update_parent_task_progress_on_insert_trigger ON tasks;
+CREATE TRIGGER update_parent_task_progress_on_insert_trigger
+AFTER INSERT ON tasks
+FOR EACH ROW
+WHEN (NEW.parent_task_id IS NOT NULL)
+EXECUTE FUNCTION update_parent_task_progress();
+
+-- Add a comment to explain the fix
+COMMENT ON FUNCTION update_parent_task_progress() IS
+'This function recursively updates progress values for all ancestors when a task''s progress changes.
+The previous version only updated the immediate parent, which led to incorrect progress values for
+higher-level parent tasks when using weighted or manual progress calculations with multi-level subtasks.';
+
+-- Add a function to immediately recalculate all task progress values in the correct order
+-- This will fix existing data where parent tasks don't have proper progress values
+CREATE OR REPLACE FUNCTION recalculate_all_task_progress() RETURNS void AS
+$$
+BEGIN
+ -- First, reset manual_progress flag for all tasks that have subtasks
+ UPDATE tasks AS t
+ SET manual_progress = FALSE
+ WHERE EXISTS (
+ SELECT 1
+ FROM tasks
+ WHERE parent_task_id = t.id
+ AND archived IS FALSE
+ );
+
+ -- Start recalculation from leaf tasks (no subtasks) and propagate upward
+ -- This ensures calculations are done in the right order
+ WITH RECURSIVE task_hierarchy AS (
+ -- Base case: Start with all leaf tasks (no subtasks)
+ SELECT
+ id,
+ parent_task_id,
+ 0 AS level
+ FROM tasks
+ WHERE NOT EXISTS (
+ SELECT 1 FROM tasks AS sub
+ WHERE sub.parent_task_id = tasks.id
+ AND sub.archived IS FALSE
+ )
+ AND archived IS FALSE
+
+ UNION ALL
+
+ -- Recursive case: Move up to parent tasks, but only after processing all their children
+ SELECT
+ t.id,
+ t.parent_task_id,
+ th.level + 1
+ FROM tasks t
+ JOIN task_hierarchy th ON t.id = th.parent_task_id
+ WHERE t.archived IS FALSE
+ )
+ -- Sort by level to ensure we calculate in the right order (leaves first, then parents)
+ -- This ensures we're using already updated progress values
+ UPDATE tasks
+ SET progress_value = (SELECT (get_task_complete_ratio(tasks.id)->>'ratio')::FLOAT)
+ FROM (
+ SELECT id, level
+ FROM task_hierarchy
+ ORDER BY level
+ ) AS ordered_tasks
+ WHERE tasks.id = ordered_tasks.id
+ AND (manual_progress IS FALSE OR manual_progress IS NULL);
+
+ -- Log the completion of the recalculation
+ RAISE NOTICE 'Finished recalculating all task progress values';
+END;
+$$ LANGUAGE plpgsql;
+
+-- Execute the function to fix existing data
+SELECT recalculate_all_task_progress();
+
+COMMIT;
\ No newline at end of file
diff --git a/worklenz-backend/database/migrations/consolidated-progress-migrations.sql b/worklenz-backend/database/migrations/consolidated-progress-migrations.sql
new file mode 100644
index 00000000..ef89a923
--- /dev/null
+++ b/worklenz-backend/database/migrations/consolidated-progress-migrations.sql
@@ -0,0 +1,1140 @@
+BEGIN;
+
+-- Create ENUM type for progress modes
+CREATE TYPE PROGRESS_MODE_TYPE AS ENUM ('manual', 'weighted', 'time', 'default');
+
+-- Alter tasks table to use ENUM type
+ALTER TABLE tasks
+ ADD COLUMN IF NOT EXISTS manual_progress BOOLEAN DEFAULT FALSE,
+ ADD COLUMN IF NOT EXISTS progress_value INTEGER DEFAULT NULL,
+ ADD COLUMN IF NOT EXISTS progress_mode PROGRESS_MODE_TYPE DEFAULT 'default',
+ ADD COLUMN IF NOT EXISTS weight INTEGER DEFAULT NULL;
+
+-- Add manual progress fields to tasks table
+ALTER TABLE tasks
+ ADD COLUMN IF NOT EXISTS manual_progress BOOLEAN DEFAULT FALSE,
+ ADD COLUMN IF NOT EXISTS progress_value INTEGER DEFAULT NULL,
+ ADD COLUMN IF NOT EXISTS weight INTEGER DEFAULT NULL;
+
+-- Add progress-related fields to projects table
+ALTER TABLE projects
+ ADD COLUMN IF NOT EXISTS use_manual_progress BOOLEAN DEFAULT FALSE,
+ ADD COLUMN IF NOT EXISTS use_weighted_progress BOOLEAN DEFAULT FALSE,
+ ADD COLUMN IF NOT EXISTS use_time_progress BOOLEAN DEFAULT FALSE;
+
+-- Update function to consider manual progress
+CREATE OR REPLACE FUNCTION get_task_complete_ratio(_task_id uuid) RETURNS json
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _parent_task_done FLOAT = 0;
+ _sub_tasks_done FLOAT = 0;
+ _sub_tasks_count FLOAT = 0;
+ _total_completed FLOAT = 0;
+ _total_tasks FLOAT = 0;
+ _ratio FLOAT = 0;
+ _is_manual BOOLEAN = FALSE;
+ _manual_value INTEGER = NULL;
+ _project_id UUID;
+ _use_manual_progress BOOLEAN = FALSE;
+ _use_weighted_progress BOOLEAN = FALSE;
+ _use_time_progress BOOLEAN = FALSE;
+ _task_complete BOOLEAN = FALSE;
+ _progress_mode VARCHAR(20) = NULL;
+BEGIN
+ -- Check if manual progress is set for this task
+ SELECT manual_progress, progress_value, project_id, progress_mode,
+ EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = tasks.id
+ AND is_done IS TRUE
+ ) AS is_complete
+ FROM tasks
+ WHERE id = _task_id
+ INTO _is_manual, _manual_value, _project_id, _progress_mode, _task_complete;
+
+ -- Check if the project uses manual progress
+ IF _project_id IS NOT NULL THEN
+ SELECT COALESCE(use_manual_progress, FALSE),
+ COALESCE(use_weighted_progress, FALSE),
+ COALESCE(use_time_progress, FALSE)
+ FROM projects
+ WHERE id = _project_id
+ INTO _use_manual_progress, _use_weighted_progress, _use_time_progress;
+ END IF;
+
+ -- Get all subtasks
+ SELECT COUNT(*)
+ FROM tasks
+ WHERE parent_task_id = _task_id AND archived IS FALSE
+ INTO _sub_tasks_count;
+
+ -- If task is complete, always return 100%
+ IF _task_complete IS TRUE THEN
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', 100,
+ 'total_completed', 1,
+ 'total_tasks', 1,
+ 'is_manual', FALSE
+ );
+ END IF;
+
+ -- Determine current active mode
+ DECLARE
+ _current_mode VARCHAR(20) = CASE
+ WHEN _use_manual_progress IS TRUE THEN 'manual'
+ WHEN _use_weighted_progress IS TRUE THEN 'weighted'
+ WHEN _use_time_progress IS TRUE THEN 'time'
+ ELSE 'default'
+ END;
+ BEGIN
+ -- Only use manual progress value if it was set in the current active mode
+ -- and time progress is not enabled
+ IF _use_time_progress IS FALSE AND
+ ((_is_manual IS TRUE AND _manual_value IS NOT NULL AND
+ (_progress_mode IS NULL OR _progress_mode = _current_mode)) OR
+ (_use_manual_progress IS TRUE AND _manual_value IS NOT NULL AND
+ (_progress_mode IS NULL OR _progress_mode = 'manual'))) THEN
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', _manual_value,
+ 'total_completed', 0,
+ 'total_tasks', 0,
+ 'is_manual', TRUE
+ );
+ END IF;
+ END;
+
+ -- If there are no subtasks, calculate based on the task itself
+ IF _sub_tasks_count = 0 THEN
+ -- Use time-based estimation if enabled
+ IF _use_time_progress IS TRUE THEN
+ -- Calculate progress based on logged time vs estimated time
+ WITH task_time_info AS (
+ SELECT
+ COALESCE(t.total_minutes, 0) as estimated_minutes,
+ COALESCE((
+ SELECT SUM(time_spent)
+ FROM task_work_log
+ WHERE task_id = t.id
+ ), 0) as logged_minutes
+ FROM tasks t
+ WHERE t.id = _task_id
+ )
+ SELECT
+ CASE
+ WHEN _task_complete IS TRUE THEN 100
+ WHEN estimated_minutes > 0 THEN
+ LEAST((logged_minutes / estimated_minutes) * 100, 100)
+ ELSE 0
+ END
+ INTO _ratio
+ FROM task_time_info;
+ ELSE
+ -- Traditional calculation for non-time-based tasks
+ SELECT (CASE WHEN _task_complete IS TRUE THEN 1 ELSE 0 END)
+ INTO _parent_task_done;
+
+ _ratio = _parent_task_done * 100;
+ END IF;
+ ELSE
+ -- If project uses manual progress, calculate based on subtask manual progress values
+ IF _use_manual_progress IS TRUE AND _use_time_progress IS FALSE THEN
+ WITH subtask_progress AS (
+ SELECT
+ t.id,
+ t.manual_progress,
+ t.progress_value,
+ t.progress_mode,
+ EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) AS is_complete
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ ),
+ subtask_with_values AS (
+ SELECT
+ CASE
+ WHEN is_complete IS TRUE THEN 100
+ WHEN progress_value IS NOT NULL AND (progress_mode = 'manual' OR progress_mode IS NULL) THEN progress_value
+ ELSE 0
+ END AS progress_value
+ FROM subtask_progress
+ )
+ SELECT COALESCE(AVG(progress_value), 0)
+ FROM subtask_with_values
+ INTO _ratio;
+ -- If project uses weighted progress, calculate based on subtask weights
+ ELSIF _use_weighted_progress IS TRUE AND _use_time_progress IS FALSE THEN
+ WITH subtask_progress AS (
+ SELECT
+ t.id,
+ t.manual_progress,
+ t.progress_value,
+ t.progress_mode,
+ EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) AS is_complete,
+ COALESCE(t.weight, 100) AS weight
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ ),
+ subtask_with_values AS (
+ SELECT
+ CASE
+ WHEN is_complete IS TRUE THEN 100
+ WHEN progress_value IS NOT NULL AND (progress_mode = 'weighted' OR progress_mode IS NULL) THEN progress_value
+ ELSE 0
+ END AS progress_value,
+ weight
+ FROM subtask_progress
+ )
+ SELECT COALESCE(
+ SUM(progress_value * weight) / NULLIF(SUM(weight), 0),
+ 0
+ )
+ FROM subtask_with_values
+ INTO _ratio;
+ -- If project uses time-based progress, calculate based on actual logged time
+ ELSIF _use_time_progress IS TRUE THEN
+ WITH task_time_info AS (
+ SELECT
+ t.id,
+ COALESCE(t.total_minutes, 0) as estimated_minutes,
+ COALESCE((
+ SELECT SUM(time_spent)
+ FROM task_work_log
+ WHERE task_id = t.id
+ ), 0) as logged_minutes,
+ EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) AS is_complete
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ )
+ SELECT COALESCE(
+ SUM(
+ CASE
+ WHEN is_complete IS TRUE THEN estimated_minutes
+ ELSE LEAST(logged_minutes, estimated_minutes)
+ END
+ ) / NULLIF(SUM(estimated_minutes), 0) * 100,
+ 0
+ )
+ FROM task_time_info
+ INTO _ratio;
+ ELSE
+ -- Traditional calculation based on completion status
+ SELECT (CASE WHEN _task_complete IS TRUE THEN 1 ELSE 0 END)
+ INTO _parent_task_done;
+
+ SELECT COUNT(*)
+ FROM tasks_with_status_view
+ WHERE parent_task_id = _task_id
+ AND is_done IS TRUE
+ INTO _sub_tasks_done;
+
+ _total_completed = _parent_task_done + _sub_tasks_done;
+ _total_tasks = _sub_tasks_count + 1; -- +1 for the parent task
+
+ IF _total_tasks = 0 THEN
+ _ratio = 0;
+ ELSE
+ _ratio = (_total_completed / _total_tasks) * 100;
+ END IF;
+ END IF;
+ END IF;
+
+ -- Ensure ratio is between 0 and 100
+ IF _ratio < 0 THEN
+ _ratio = 0;
+ ELSIF _ratio > 100 THEN
+ _ratio = 100;
+ END IF;
+
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', _ratio,
+ 'total_completed', _total_completed,
+ 'total_tasks', _total_tasks,
+ 'is_manual', _is_manual
+ );
+END
+$$;
+
+-- Update project functions to handle progress-related fields
+CREATE OR REPLACE FUNCTION update_project(_body JSON) RETURNS JSON
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _user_id UUID;
+ _team_id UUID;
+ _client_id UUID;
+ _project_id UUID;
+ _project_manager_team_member_id UUID;
+ _client_name TEXT;
+ _project_name TEXT;
+BEGIN
+ -- need a test, can be throw errors
+ _client_name = TRIM((_body ->> 'client_name')::TEXT);
+ _project_name = TRIM((_body ->> 'name')::TEXT);
+
+ -- add inside the controller
+ _user_id = (_body ->> 'user_id')::UUID;
+ _team_id = (_body ->> 'team_id')::UUID;
+ _project_manager_team_member_id = (_body ->> 'team_member_id')::UUID;
+
+ -- cache exists client if exists
+ SELECT id FROM clients WHERE LOWER(name) = LOWER(_client_name) AND team_id = _team_id INTO _client_id;
+
+ -- insert client if not exists
+ IF is_null_or_empty(_client_id) IS TRUE AND is_null_or_empty(_client_name) IS FALSE
+ THEN
+ INSERT INTO clients (name, team_id) VALUES (_client_name, _team_id) RETURNING id INTO _client_id;
+ END IF;
+
+ -- check whether the project name is already in
+ IF EXISTS(SELECT name
+ FROM projects
+ WHERE LOWER(name) = LOWER(_project_name)
+ AND team_id = _team_id
+ AND id != (_body ->> 'id')::UUID)
+ THEN
+ RAISE 'PROJECT_EXISTS_ERROR:%', _project_name;
+ END IF;
+
+ -- update the project
+ UPDATE projects
+ SET name = _project_name,
+ notes = (_body ->> 'notes')::TEXT,
+ color_code = (_body ->> 'color_code')::TEXT,
+ status_id = (_body ->> 'status_id')::UUID,
+ health_id = (_body ->> 'health_id')::UUID,
+ key = (_body ->> 'key')::TEXT,
+ start_date = (_body ->> 'start_date')::TIMESTAMPTZ,
+ end_date = (_body ->> 'end_date')::TIMESTAMPTZ,
+ client_id = _client_id,
+ folder_id = (_body ->> 'folder_id')::UUID,
+ category_id = (_body ->> 'category_id')::UUID,
+ updated_at = CURRENT_TIMESTAMP,
+ estimated_working_days = (_body ->> 'working_days')::INTEGER,
+ estimated_man_days = (_body ->> 'man_days')::INTEGER,
+ hours_per_day = (_body ->> 'hours_per_day')::INTEGER,
+ use_manual_progress = COALESCE((_body ->> 'use_manual_progress')::BOOLEAN, FALSE),
+ use_weighted_progress = COALESCE((_body ->> 'use_weighted_progress')::BOOLEAN, FALSE),
+ use_time_progress = COALESCE((_body ->> 'use_time_progress')::BOOLEAN, FALSE)
+ WHERE id = (_body ->> 'id')::UUID
+ AND team_id = _team_id
+ RETURNING id INTO _project_id;
+
+ UPDATE project_members
+ SET project_access_level_id = (SELECT id FROM project_access_levels WHERE key = 'MEMBER')
+ WHERE project_id = _project_id;
+
+ IF NOT (_project_manager_team_member_id IS NULL)
+ THEN
+ PERFORM update_project_manager(_project_manager_team_member_id, _project_id::UUID);
+ END IF;
+
+ RETURN JSON_BUILD_OBJECT(
+ 'id', _project_id,
+ 'name', (_body ->> 'name')::TEXT,
+ 'project_manager_id', _project_manager_team_member_id::UUID
+ );
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION create_project(_body JSON) RETURNS JSON
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _project_id UUID;
+ _user_id UUID;
+ _team_id UUID;
+ _team_member_id UUID;
+ _client_id UUID;
+ _client_name TEXT;
+ _project_name TEXT;
+ _project_created_log TEXT;
+ _project_member_added_log TEXT;
+ _project_created_log_id UUID;
+ _project_manager_team_member_id UUID;
+ _project_key TEXT;
+BEGIN
+ _client_name = TRIM((_body ->> 'client_name')::TEXT);
+ _project_name = TRIM((_body ->> 'name')::TEXT);
+ _project_key = TRIM((_body ->> 'key')::TEXT);
+ _project_created_log = (_body ->> 'project_created_log')::TEXT;
+ _project_member_added_log = (_body ->> 'project_member_added_log')::TEXT;
+ _user_id = (_body ->> 'user_id')::UUID;
+ _team_id = (_body ->> 'team_id')::UUID;
+ _project_manager_team_member_id = (_body ->> 'project_manager_id')::UUID;
+
+ SELECT id FROM team_members WHERE user_id = _user_id AND team_id = _team_id INTO _team_member_id;
+
+ -- cache exists client if exists
+ SELECT id FROM clients WHERE LOWER(name) = LOWER(_client_name) AND team_id = _team_id INTO _client_id;
+
+ -- insert client if not exists
+ IF is_null_or_empty(_client_id) IS TRUE AND is_null_or_empty(_client_name) IS FALSE
+ THEN
+ INSERT INTO clients (name, team_id) VALUES (_client_name, _team_id) RETURNING id INTO _client_id;
+ END IF;
+
+ -- check whether the project name is already in
+ IF EXISTS(SELECT name FROM projects WHERE LOWER(name) = LOWER(_project_name) AND team_id = _team_id)
+ THEN
+ RAISE 'PROJECT_EXISTS_ERROR:%', _project_name;
+ END IF;
+
+ -- create the project
+ INSERT
+ INTO projects (name, key, color_code, start_date, end_date, team_id, notes, owner_id, status_id, health_id,
+ folder_id,
+ category_id, estimated_working_days, estimated_man_days, hours_per_day,
+ use_manual_progress, use_weighted_progress, use_time_progress, client_id)
+ VALUES (_project_name,
+ UPPER(_project_key),
+ (_body ->> 'color_code')::TEXT,
+ (_body ->> 'start_date')::TIMESTAMPTZ,
+ (_body ->> 'end_date')::TIMESTAMPTZ,
+ _team_id,
+ (_body ->> 'notes')::TEXT,
+ _user_id,
+ (_body ->> 'status_id')::UUID,
+ (_body ->> 'health_id')::UUID,
+ (_body ->> 'folder_id')::UUID,
+ (_body ->> 'category_id')::UUID,
+ (_body ->> 'working_days')::INTEGER,
+ (_body ->> 'man_days')::INTEGER,
+ (_body ->> 'hours_per_day')::INTEGER,
+ COALESCE((_body ->> 'use_manual_progress')::BOOLEAN, FALSE),
+ COALESCE((_body ->> 'use_weighted_progress')::BOOLEAN, FALSE),
+ COALESCE((_body ->> 'use_time_progress')::BOOLEAN, FALSE),
+ _client_id)
+ RETURNING id INTO _project_id;
+
+ -- register the project log
+ INSERT INTO project_logs (project_id, team_id, description)
+ VALUES (_project_id, _team_id, _project_created_log)
+ RETURNING id INTO _project_created_log_id;
+
+ -- insert the project creator as a project member
+ INSERT INTO project_members (team_member_id, project_access_level_id, project_id, role_id)
+ VALUES (_team_member_id, (SELECT id FROM project_access_levels WHERE key = 'ADMIN'),
+ _project_id,
+ (SELECT id FROM roles WHERE team_id = _team_id AND default_role IS TRUE));
+
+ -- insert statuses
+ INSERT INTO task_statuses (name, project_id, team_id, category_id, sort_order)
+ VALUES ('To Do', _project_id, _team_id, (SELECT id FROM sys_task_status_categories WHERE is_todo IS TRUE), 0);
+ INSERT INTO task_statuses (name, project_id, team_id, category_id, sort_order)
+ VALUES ('Doing', _project_id, _team_id, (SELECT id FROM sys_task_status_categories WHERE is_doing IS TRUE), 1);
+ INSERT INTO task_statuses (name, project_id, team_id, category_id, sort_order)
+ VALUES ('Done', _project_id, _team_id, (SELECT id FROM sys_task_status_categories WHERE is_done IS TRUE), 2);
+
+ -- insert default project columns
+ PERFORM insert_task_list_columns(_project_id);
+
+ -- add project manager role if exists
+ IF NOT is_null_or_empty(_project_manager_team_member_id)
+ THEN
+ PERFORM update_project_manager(_project_manager_team_member_id, _project_id);
+ END IF;
+
+ RETURN JSON_BUILD_OBJECT(
+ 'id', _project_id,
+ 'name', _project_name,
+ 'project_created_log_id', _project_created_log_id
+ );
+END;
+$$;
+
+COMMIT;
+
+BEGIN;
+
+-- Update the on_update_task_progress function to set progress_mode
+CREATE OR REPLACE FUNCTION on_update_task_progress(_body JSON) RETURNS JSON
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _task_id UUID;
+ _progress_value INTEGER;
+ _parent_task_id UUID;
+ _project_id UUID;
+ _current_mode VARCHAR(20);
+BEGIN
+ _task_id = (_body ->> 'task_id')::UUID;
+ _progress_value = (_body ->> 'progress_value')::INTEGER;
+ _parent_task_id = (_body ->> 'parent_task_id')::UUID;
+
+ -- Get the project ID and determine the current progress mode
+ SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
+
+ IF _project_id IS NOT NULL
+ THEN
+ SELECT CASE
+ WHEN use_manual_progress IS TRUE THEN 'manual'
+ WHEN use_weighted_progress IS TRUE THEN 'weighted'
+ WHEN use_time_progress IS TRUE THEN 'time'
+ ELSE 'default'
+ END
+ INTO _current_mode
+ FROM projects
+ WHERE id = _project_id;
+ ELSE
+ _current_mode := 'default';
+ END IF;
+
+ -- Update the task with progress value and set the progress mode
+ UPDATE tasks
+ SET progress_value = _progress_value,
+ manual_progress = TRUE,
+ progress_mode = _current_mode,
+ updated_at = CURRENT_TIMESTAMP
+ WHERE id = _task_id;
+
+ -- Return the updated task info
+ RETURN JSON_BUILD_OBJECT(
+ 'task_id', _task_id,
+ 'progress_value', _progress_value,
+ 'progress_mode', _current_mode
+ );
+END;
+$$;
+
+-- Update the on_update_task_weight function to set progress_mode when weight is updated
+CREATE OR REPLACE FUNCTION on_update_task_weight(_body JSON) RETURNS JSON
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _task_id UUID;
+ _weight INTEGER;
+ _parent_task_id UUID;
+ _project_id UUID;
+BEGIN
+ _task_id = (_body ->> 'task_id')::UUID;
+ _weight = (_body ->> 'weight')::INTEGER;
+ _parent_task_id = (_body ->> 'parent_task_id')::UUID;
+
+ -- Get the project ID
+ SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
+
+ -- Update the task with weight value and set progress_mode to 'weighted'
+ UPDATE tasks
+ SET weight = _weight,
+ progress_mode = 'weighted',
+ updated_at = CURRENT_TIMESTAMP
+ WHERE id = _task_id;
+
+ -- Return the updated task info
+ RETURN JSON_BUILD_OBJECT(
+ 'task_id', _task_id,
+ 'weight', _weight
+ );
+END;
+$$;
+
+-- Create a function to reset progress values when switching project progress modes
+CREATE OR REPLACE FUNCTION reset_project_progress_values() RETURNS TRIGGER
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _old_mode VARCHAR(20);
+ _new_mode VARCHAR(20);
+ _project_id UUID;
+BEGIN
+ _project_id := NEW.id;
+
+ -- Determine old and new modes
+ _old_mode :=
+ CASE
+ WHEN OLD.use_manual_progress IS TRUE THEN 'manual'
+ WHEN OLD.use_weighted_progress IS TRUE THEN 'weighted'
+ WHEN OLD.use_time_progress IS TRUE THEN 'time'
+ ELSE 'default'
+ END;
+
+ _new_mode :=
+ CASE
+ WHEN NEW.use_manual_progress IS TRUE THEN 'manual'
+ WHEN NEW.use_weighted_progress IS TRUE THEN 'weighted'
+ WHEN NEW.use_time_progress IS TRUE THEN 'time'
+ ELSE 'default'
+ END;
+
+ -- If mode has changed, reset progress values for tasks with the old mode
+ IF _old_mode <> _new_mode
+ THEN
+ -- Reset progress values for tasks that were set in the old mode
+ UPDATE tasks
+ SET progress_value = NULL,
+ progress_mode = NULL
+ WHERE project_id = _project_id
+ AND progress_mode = _old_mode;
+ END IF;
+
+ RETURN NEW;
+END;
+$$;
+
+-- Create trigger to reset progress values when project progress mode changes
+DROP TRIGGER IF EXISTS reset_progress_on_mode_change ON projects;
+CREATE TRIGGER reset_progress_on_mode_change
+ AFTER UPDATE OF use_manual_progress, use_weighted_progress, use_time_progress
+ ON projects
+ FOR EACH ROW
+EXECUTE FUNCTION reset_project_progress_values();
+
+COMMIT;
+
+BEGIN;
+
+-- Add progress_mode column to tasks table to track which mode the progress was set in
+ALTER TABLE tasks
+ ADD COLUMN IF NOT EXISTS progress_mode VARCHAR(20) DEFAULT NULL;
+
+-- Update function to use time-based progress for all tasks and respect mode changes
+CREATE OR REPLACE FUNCTION get_task_complete_ratio(_task_id UUID) RETURNS JSON
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _parent_task_done FLOAT = 0;
+ _sub_tasks_done FLOAT = 0;
+ _sub_tasks_count FLOAT = 0;
+ _total_completed FLOAT = 0;
+ _total_tasks FLOAT = 0;
+ _ratio FLOAT = 0;
+ _is_manual BOOLEAN = FALSE;
+ _manual_value INTEGER = NULL;
+ _project_id UUID;
+ _use_manual_progress BOOLEAN = FALSE;
+ _use_weighted_progress BOOLEAN = FALSE;
+ _use_time_progress BOOLEAN = FALSE;
+ _task_complete BOOLEAN = FALSE;
+ _progress_mode VARCHAR(20) = NULL;
+BEGIN
+ -- Check if manual progress is set for this task
+ SELECT manual_progress,
+ progress_value,
+ project_id,
+ progress_mode,
+ EXISTS(SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = tasks.id
+ AND is_done IS TRUE) AS is_complete
+ FROM tasks
+ WHERE id = _task_id
+ INTO _is_manual, _manual_value, _project_id, _progress_mode, _task_complete;
+
+ -- Check if the project uses manual progress
+ IF _project_id IS NOT NULL
+ THEN
+ SELECT COALESCE(use_manual_progress, FALSE),
+ COALESCE(use_weighted_progress, FALSE),
+ COALESCE(use_time_progress, FALSE)
+ FROM projects
+ WHERE id = _project_id
+ INTO _use_manual_progress, _use_weighted_progress, _use_time_progress;
+ END IF;
+
+ -- Get all subtasks
+ SELECT COUNT(*)
+ FROM tasks
+ WHERE parent_task_id = _task_id
+ AND archived IS FALSE
+ INTO _sub_tasks_count;
+
+ -- If task is complete, always return 100%
+ IF _task_complete IS TRUE
+ THEN
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', 100,
+ 'total_completed', 1,
+ 'total_tasks', 1,
+ 'is_manual', FALSE
+ );
+ END IF;
+
+ -- Determine current active mode
+ DECLARE
+ _current_mode VARCHAR(20) = CASE
+ WHEN _use_manual_progress IS TRUE THEN 'manual'
+ WHEN _use_weighted_progress IS TRUE THEN 'weighted'
+ WHEN _use_time_progress IS TRUE THEN 'time'
+ ELSE 'default'
+ END;
+ BEGIN
+ -- Only use manual progress value if it was set in the current active mode
+ -- or if the task is explicitly marked for manual progress
+ IF (_is_manual IS TRUE AND _manual_value IS NOT NULL AND
+ (_progress_mode IS NULL OR _progress_mode = _current_mode)) OR
+ (_use_manual_progress IS TRUE AND _manual_value IS NOT NULL AND
+ (_progress_mode IS NULL OR _progress_mode = 'manual'))
+ THEN
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', _manual_value,
+ 'total_completed', 0,
+ 'total_tasks', 0,
+ 'is_manual', TRUE
+ );
+ END IF;
+ END;
+
+ -- If there are no subtasks, just use the parent task's status (unless in time-based mode)
+ IF _sub_tasks_count = 0
+ THEN
+ -- Use time-based estimation for tasks without subtasks if enabled
+ IF _use_time_progress IS TRUE
+ THEN
+ -- For time-based tasks without subtasks, we still need some progress calculation
+ -- If the task is completed, return 100%
+ -- Otherwise, use the progress value if set manually in the correct mode, or 0
+ SELECT CASE
+ WHEN _task_complete IS TRUE THEN 100
+ WHEN _manual_value IS NOT NULL AND (_progress_mode = 'time' OR _progress_mode IS NULL)
+ THEN _manual_value
+ ELSE 0
+ END
+ INTO _ratio;
+ ELSE
+ -- Traditional calculation for non-time-based tasks
+ SELECT (CASE WHEN _task_complete IS TRUE THEN 1 ELSE 0 END)
+ INTO _parent_task_done;
+
+ _ratio = _parent_task_done * 100;
+ END IF;
+ ELSE
+ -- If project uses manual progress, calculate based on subtask manual progress values
+ IF _use_manual_progress IS TRUE
+ THEN
+ WITH subtask_progress AS (SELECT t.id,
+ t.manual_progress,
+ t.progress_value,
+ t.progress_mode,
+ EXISTS(SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE) AS is_complete
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE),
+ subtask_with_values AS (SELECT CASE
+ -- For completed tasks, always use 100%
+ WHEN is_complete IS TRUE THEN 100
+ -- For tasks with progress value set in the correct mode, use it
+ WHEN progress_value IS NOT NULL AND
+ (progress_mode = 'manual' OR progress_mode IS NULL)
+ THEN progress_value
+ -- Default to 0 for incomplete tasks with no progress value or wrong mode
+ ELSE 0
+ END AS progress_value
+ FROM subtask_progress)
+ SELECT COALESCE(AVG(progress_value), 0)
+ FROM subtask_with_values
+ INTO _ratio;
+ -- If project uses weighted progress, calculate based on subtask weights
+ ELSIF _use_weighted_progress IS TRUE
+ THEN
+ WITH subtask_progress AS (SELECT t.id,
+ t.manual_progress,
+ t.progress_value,
+ t.progress_mode,
+ EXISTS(SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE) AS is_complete,
+ COALESCE(t.weight, 100) AS weight
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE),
+ subtask_with_values AS (SELECT CASE
+ -- For completed tasks, always use 100%
+ WHEN is_complete IS TRUE THEN 100
+ -- For tasks with progress value set in the correct mode, use it
+ WHEN progress_value IS NOT NULL AND
+ (progress_mode = 'weighted' OR progress_mode IS NULL)
+ THEN progress_value
+ -- Default to 0 for incomplete tasks with no progress value or wrong mode
+ ELSE 0
+ END AS progress_value,
+ weight
+ FROM subtask_progress)
+ SELECT COALESCE(
+ SUM(progress_value * weight) / NULLIF(SUM(weight), 0),
+ 0
+ )
+ FROM subtask_with_values
+ INTO _ratio;
+ -- If project uses time-based progress, calculate based on actual logged time
+ ELSIF _use_time_progress IS TRUE
+ THEN
+ WITH task_time_info AS (
+ SELECT
+ t.id,
+ COALESCE(t.total_minutes, 0) as estimated_minutes,
+ COALESCE((
+ SELECT SUM(time_spent)
+ FROM task_work_log
+ WHERE task_id = t.id
+ ), 0) as logged_minutes,
+ EXISTS(
+ SELECT 1
+ FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = t.id
+ AND is_done IS TRUE
+ ) AS is_complete
+ FROM tasks t
+ WHERE t.parent_task_id = _task_id
+ AND t.archived IS FALSE
+ )
+ SELECT COALESCE(
+ SUM(
+ CASE
+ WHEN is_complete IS TRUE THEN estimated_minutes
+ ELSE LEAST(logged_minutes, estimated_minutes)
+ END
+ ) / NULLIF(SUM(estimated_minutes), 0) * 100,
+ 0
+ )
+ FROM task_time_info
+ INTO _ratio;
+ ELSE
+ -- Traditional calculation based on completion status
+ SELECT (CASE WHEN _task_complete IS TRUE THEN 1 ELSE 0 END)
+ INTO _parent_task_done;
+
+ SELECT COUNT(*)
+ FROM tasks_with_status_view
+ WHERE parent_task_id = _task_id
+ AND is_done IS TRUE
+ INTO _sub_tasks_done;
+
+ _total_completed = _parent_task_done + _sub_tasks_done;
+ _total_tasks = _sub_tasks_count + 1; -- +1 for the parent task
+
+ IF _total_tasks = 0
+ THEN
+ _ratio = 0;
+ ELSE
+ _ratio = (_total_completed / _total_tasks) * 100;
+ END IF;
+ END IF;
+ END IF;
+
+ -- Ensure ratio is between 0 and 100
+ IF _ratio < 0
+ THEN
+ _ratio = 0;
+ ELSIF _ratio > 100
+ THEN
+ _ratio = 100;
+ END IF;
+
+ RETURN JSON_BUILD_OBJECT(
+ 'ratio', _ratio,
+ 'total_completed', _total_completed,
+ 'total_tasks', _total_tasks,
+ 'is_manual', _is_manual
+ );
+END
+$$;
+
+CREATE OR REPLACE FUNCTION public.get_task_form_view_model(_user_id UUID, _team_id UUID, _task_id UUID, _project_id UUID) RETURNS JSON
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _task JSON;
+ _priorities JSON;
+ _projects JSON;
+ _statuses JSON;
+ _team_members JSON;
+ _assignees JSON;
+ _phases JSON;
+BEGIN
+
+ -- Select task info
+ SELECT COALESCE(ROW_TO_JSON(rec), '{}'::JSON)
+ INTO _task
+ FROM (WITH RECURSIVE task_hierarchy AS (
+ -- Base case: Start with the given task
+ SELECT id,
+ parent_task_id,
+ 0 AS level
+ FROM tasks
+ WHERE id = _task_id
+
+ UNION ALL
+
+ -- Recursive case: Traverse up to parent tasks
+ SELECT t.id,
+ t.parent_task_id,
+ th.level + 1 AS level
+ FROM tasks t
+ INNER JOIN task_hierarchy th ON t.id = th.parent_task_id
+ WHERE th.parent_task_id IS NOT NULL)
+ SELECT id,
+ name,
+ description,
+ start_date,
+ end_date,
+ done,
+ total_minutes,
+ priority_id,
+ project_id,
+ created_at,
+ updated_at,
+ status_id,
+ parent_task_id,
+ sort_order,
+ (SELECT phase_id FROM task_phase WHERE task_id = tasks.id) AS phase_id,
+ CONCAT((SELECT key FROM projects WHERE id = tasks.project_id), '-', task_no) AS task_key,
+ (SELECT start_time
+ FROM task_timers
+ WHERE task_id = tasks.id
+ AND user_id = _user_id) AS timer_start_time,
+ parent_task_id IS NOT NULL AS is_sub_task,
+ (SELECT COUNT('*')
+ FROM tasks
+ WHERE parent_task_id = tasks.id
+ AND archived IS FALSE) AS sub_tasks_count,
+ (SELECT COUNT(*)
+ FROM tasks_with_status_view tt
+ WHERE (tt.parent_task_id = tasks.id OR tt.task_id = tasks.id)
+ AND tt.is_done IS TRUE)
+ AS completed_count,
+ (SELECT COUNT(*) FROM task_attachments WHERE task_id = tasks.id) AS attachments_count,
+ (SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(r))), '[]'::JSON)
+ FROM (SELECT task_labels.label_id AS id,
+ (SELECT name FROM team_labels WHERE id = task_labels.label_id),
+ (SELECT color_code FROM team_labels WHERE id = task_labels.label_id)
+ FROM task_labels
+ WHERE task_id = tasks.id
+ ORDER BY name) r) AS labels,
+ (SELECT color_code
+ FROM sys_task_status_categories
+ WHERE id = (SELECT category_id FROM task_statuses WHERE id = tasks.status_id)) AS status_color,
+ (SELECT COUNT(*) FROM tasks WHERE parent_task_id = _task_id) AS sub_tasks_count,
+ (SELECT name FROM users WHERE id = tasks.reporter_id) AS reporter,
+ (SELECT get_task_assignees(tasks.id)) AS assignees,
+ (SELECT id FROM team_members WHERE user_id = _user_id AND team_id = _team_id) AS team_member_id,
+ billable,
+ schedule_id,
+ progress_value,
+ weight,
+ (SELECT MAX(level) FROM task_hierarchy) AS task_level
+ FROM tasks
+ WHERE id = _task_id) rec;
+
+ SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
+ INTO _priorities
+ FROM (SELECT id, name FROM task_priorities ORDER BY value) rec;
+
+ SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
+ INTO _phases
+ FROM (SELECT id, name FROM project_phases WHERE project_id = _project_id ORDER BY name) rec;
+
+ SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
+ INTO _projects
+ FROM (SELECT id, name
+ FROM projects
+ WHERE team_id = _team_id
+ AND (CASE
+ WHEN (is_owner(_user_id, _team_id) OR is_admin(_user_id, _team_id) IS TRUE) THEN TRUE
+ ELSE is_member_of_project(projects.id, _user_id, _team_id) END)
+ ORDER BY name) rec;
+
+ SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
+ INTO _statuses
+ FROM (SELECT id, name FROM task_statuses WHERE project_id = _project_id) rec;
+
+ SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
+ INTO _team_members
+ FROM (SELECT team_members.id,
+ (SELECT name FROM team_member_info_view WHERE team_member_info_view.team_member_id = team_members.id),
+ (SELECT email FROM team_member_info_view WHERE team_member_info_view.team_member_id = team_members.id),
+ (SELECT avatar_url
+ FROM team_member_info_view
+ WHERE team_member_info_view.team_member_id = team_members.id)
+ FROM team_members
+ LEFT JOIN users u ON team_members.user_id = u.id
+ WHERE team_id = _team_id
+ AND team_members.active IS TRUE) rec;
+
+ SELECT get_task_assignees(_task_id) INTO _assignees;
+
+ RETURN JSON_BUILD_OBJECT(
+ 'task', _task,
+ 'priorities', _priorities,
+ 'projects', _projects,
+ 'statuses', _statuses,
+ 'team_members', _team_members,
+ 'assignees', _assignees,
+ 'phases', _phases
+ );
+END;
+$$;
+
+COMMIT;
+
+BEGIN;
+
+-- Update the on_update_task_progress function to set progress_mode
+CREATE OR REPLACE FUNCTION on_update_task_progress(_body JSON) RETURNS JSON
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _task_id UUID;
+ _progress_value INTEGER;
+ _parent_task_id UUID;
+ _project_id UUID;
+ _current_mode VARCHAR(20);
+BEGIN
+ _task_id = (_body ->> 'task_id')::UUID;
+ _progress_value = (_body ->> 'progress_value')::INTEGER;
+ _parent_task_id = (_body ->> 'parent_task_id')::UUID;
+
+ -- Get the project ID and determine the current progress mode
+ SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
+
+ IF _project_id IS NOT NULL
+ THEN
+ SELECT CASE
+ WHEN use_manual_progress IS TRUE THEN 'manual'
+ WHEN use_weighted_progress IS TRUE THEN 'weighted'
+ WHEN use_time_progress IS TRUE THEN 'time'
+ ELSE 'default'
+ END
+ INTO _current_mode
+ FROM projects
+ WHERE id = _project_id;
+ ELSE
+ _current_mode := 'default';
+ END IF;
+
+ -- Update the task with progress value and set the progress mode
+ UPDATE tasks
+ SET progress_value = _progress_value,
+ manual_progress = TRUE,
+ progress_mode = _current_mode,
+ updated_at = CURRENT_TIMESTAMP
+ WHERE id = _task_id;
+
+ -- Return the updated task info
+ RETURN JSON_BUILD_OBJECT(
+ 'task_id', _task_id,
+ 'progress_value', _progress_value,
+ 'progress_mode', _current_mode
+ );
+END;
+$$;
+
+-- Update the on_update_task_weight function to set progress_mode when weight is updated
+CREATE OR REPLACE FUNCTION on_update_task_weight(_body JSON) RETURNS JSON
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _task_id UUID;
+ _weight INTEGER;
+ _parent_task_id UUID;
+ _project_id UUID;
+BEGIN
+ _task_id = (_body ->> 'task_id')::UUID;
+ _weight = (_body ->> 'weight')::INTEGER;
+ _parent_task_id = (_body ->> 'parent_task_id')::UUID;
+
+ -- Get the project ID
+ SELECT project_id INTO _project_id FROM tasks WHERE id = _task_id;
+
+ -- Update the task with weight value and set progress_mode to 'weighted'
+ UPDATE tasks
+ SET weight = _weight,
+ progress_mode = 'weighted',
+ updated_at = CURRENT_TIMESTAMP
+ WHERE id = _task_id;
+
+ -- Return the updated task info
+ RETURN JSON_BUILD_OBJECT(
+ 'task_id', _task_id,
+ 'weight', _weight
+ );
+END;
+$$;
+
+-- Create a function to reset progress values when switching project progress modes
+CREATE OR REPLACE FUNCTION reset_project_progress_values() RETURNS TRIGGER
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _old_mode VARCHAR(20);
+ _new_mode VARCHAR(20);
+ _project_id UUID;
+BEGIN
+ _project_id := NEW.id;
+
+ -- Determine old and new modes
+ _old_mode :=
+ CASE
+ WHEN OLD.use_manual_progress IS TRUE THEN 'manual'
+ WHEN OLD.use_weighted_progress IS TRUE THEN 'weighted'
+ WHEN OLD.use_time_progress IS TRUE THEN 'time'
+ ELSE 'default'
+ END;
+
+ _new_mode :=
+ CASE
+ WHEN NEW.use_manual_progress IS TRUE THEN 'manual'
+ WHEN NEW.use_weighted_progress IS TRUE THEN 'weighted'
+ WHEN NEW.use_time_progress IS TRUE THEN 'time'
+ ELSE 'default'
+ END;
+
+ -- If mode has changed, reset progress values for tasks with the old mode
+ IF _old_mode <> _new_mode
+ THEN
+ -- Reset progress values for tasks that were set in the old mode
+ UPDATE tasks
+ SET progress_value = NULL,
+ progress_mode = NULL
+ WHERE project_id = _project_id
+ AND progress_mode = _old_mode;
+ END IF;
+
+ RETURN NEW;
+END;
+$$;
+
+-- Create trigger to reset progress values when project progress mode changes
+DROP TRIGGER IF EXISTS reset_progress_on_mode_change ON projects;
+CREATE TRIGGER reset_progress_on_mode_change
+ AFTER UPDATE OF use_manual_progress, use_weighted_progress, use_time_progress
+ ON projects
+ FOR EACH ROW
+EXECUTE FUNCTION reset_project_progress_values();
+
+COMMIT;
+
+
diff --git a/worklenz-backend/database/sql/1_tables.sql b/worklenz-backend/database/sql/1_tables.sql
index e9fc31c4..21f498f1 100644
--- a/worklenz-backend/database/sql/1_tables.sql
+++ b/worklenz-backend/database/sql/1_tables.sql
@@ -12,7 +12,7 @@ CREATE TYPE DEPENDENCY_TYPE AS ENUM ('blocked_by');
CREATE TYPE SCHEDULE_TYPE AS ENUM ('daily', 'weekly', 'yearly', 'monthly', 'every_x_days', 'every_x_weeks', 'every_x_months');
-CREATE TYPE LANGUAGE_TYPE AS ENUM ('en', 'es', 'pt', 'alb', 'de');
+CREATE TYPE LANGUAGE_TYPE AS ENUM ('en', 'es', 'pt', 'alb', 'de', 'zh_cn');
-- START: Users
CREATE SEQUENCE IF NOT EXISTS users_user_no_seq START 1;
diff --git a/worklenz-backend/database/sql/3_views.sql b/worklenz-backend/database/sql/3_views.sql
index 15e36e23..f29291de 100644
--- a/worklenz-backend/database/sql/3_views.sql
+++ b/worklenz-backend/database/sql/3_views.sql
@@ -32,3 +32,37 @@ SELECT u.avatar_url,
FROM team_members
LEFT JOIN users u ON team_members.user_id = u.id;
+-- PERFORMANCE OPTIMIZATION: Create materialized view for team member info
+-- This pre-calculates the expensive joins and subqueries from team_member_info_view
+CREATE MATERIALIZED VIEW IF NOT EXISTS team_member_info_mv AS
+SELECT
+ u.avatar_url,
+ COALESCE(u.email, ei.email) AS email,
+ COALESCE(u.name, ei.name) AS name,
+ u.id AS user_id,
+ tm.id AS team_member_id,
+ tm.team_id,
+ tm.active,
+ u.socket_id
+FROM team_members tm
+LEFT JOIN users u ON tm.user_id = u.id
+LEFT JOIN email_invitations ei ON ei.team_member_id = tm.id
+WHERE tm.active = TRUE;
+
+-- Create unique index on the materialized view for fast lookups
+CREATE UNIQUE INDEX IF NOT EXISTS idx_team_member_info_mv_team_member_id
+ON team_member_info_mv(team_member_id);
+
+CREATE INDEX IF NOT EXISTS idx_team_member_info_mv_team_user
+ON team_member_info_mv(team_id, user_id);
+
+-- Function to refresh the materialized view
+CREATE OR REPLACE FUNCTION refresh_team_member_info_mv()
+RETURNS void
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ REFRESH MATERIALIZED VIEW CONCURRENTLY team_member_info_mv;
+END;
+$$;
+
diff --git a/worklenz-backend/database/sql/4_functions.sql b/worklenz-backend/database/sql/4_functions.sql
index 189f8ac7..2c57d3c4 100644
--- a/worklenz-backend/database/sql/4_functions.sql
+++ b/worklenz-backend/database/sql/4_functions.sql
@@ -3351,15 +3351,15 @@ BEGIN
SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
FROM (SELECT team_member_id,
project_member_id,
- (SELECT name FROM team_member_info_view WHERE team_member_info_view.team_member_id = tm.id),
- (SELECT email_notifications_enabled
+ COALESCE((SELECT name FROM team_member_info_view WHERE team_member_info_view.team_member_id = tm.id), '') as name,
+ COALESCE((SELECT email_notifications_enabled
FROM notification_settings
WHERE team_id = tm.team_id
- AND notification_settings.user_id = u.id) AS email_notifications_enabled,
- u.avatar_url,
+ AND notification_settings.user_id = u.id), false) AS email_notifications_enabled,
+ COALESCE(u.avatar_url, '') as avatar_url,
u.id AS user_id,
- u.email,
- u.socket_id AS socket_id,
+ COALESCE(u.email, '') as email,
+ COALESCE(u.socket_id, '') as socket_id,
tm.team_id AS team_id
FROM tasks_assignees
INNER JOIN team_members tm ON tm.id = tasks_assignees.team_member_id
@@ -4066,14 +4066,14 @@ DECLARE
_schedule_id JSON;
_task_completed_at TIMESTAMPTZ;
BEGIN
- SELECT name FROM tasks WHERE id = _task_id INTO _task_name;
+ SELECT COALESCE(name, '') FROM tasks WHERE id = _task_id INTO _task_name;
- SELECT name
+ SELECT COALESCE(name, '')
FROM task_statuses
WHERE id = (SELECT status_id FROM tasks WHERE id = _task_id)
INTO _previous_status_name;
- SELECT name FROM task_statuses WHERE id = _status_id INTO _new_status_name;
+ SELECT COALESCE(name, '') FROM task_statuses WHERE id = _status_id INTO _new_status_name;
IF (_previous_status_name != _new_status_name)
THEN
@@ -4081,14 +4081,22 @@ BEGIN
SELECT get_task_complete_info(_task_id, _status_id) INTO _task_info;
- SELECT name FROM users WHERE id = _user_id INTO _updater_name;
+ SELECT COALESCE(name, '') FROM users WHERE id = _user_id INTO _updater_name;
_message = CONCAT(_updater_name, ' transitioned "', _task_name, '" from ', _previous_status_name, ' โถ ',
_new_status_name);
END IF;
SELECT completed_at FROM tasks WHERE id = _task_id INTO _task_completed_at;
- SELECT schedule_id FROM tasks WHERE id = _task_id INTO _schedule_id;
+
+ -- Handle schedule_id properly for recurring tasks
+ SELECT CASE
+ WHEN schedule_id IS NULL THEN 'null'::json
+ ELSE json_build_object('id', schedule_id)
+ END
+ FROM tasks
+ WHERE id = _task_id
+ INTO _schedule_id;
SELECT COALESCE(ROW_TO_JSON(r), '{}'::JSON)
FROM (SELECT is_done, is_doing, is_todo
@@ -4097,7 +4105,7 @@ BEGIN
INTO _status_category;
RETURN JSON_BUILD_OBJECT(
- 'message', _message,
+ 'message', COALESCE(_message, ''),
'project_id', (SELECT project_id FROM tasks WHERE id = _task_id),
'parent_done', (CASE
WHEN EXISTS(SELECT 1
@@ -4105,14 +4113,14 @@ BEGIN
WHERE tasks_with_status_view.task_id = _task_id
AND is_done IS TRUE) THEN 1
ELSE 0 END),
- 'color_code', (_task_info ->> 'color_code')::TEXT,
- 'color_code_dark', (_task_info ->> 'color_code_dark')::TEXT,
- 'total_tasks', (_task_info ->> 'total_tasks')::INT,
- 'total_completed', (_task_info ->> 'total_completed')::INT,
- 'members', (_task_info ->> 'members')::JSON,
+ 'color_code', COALESCE((_task_info ->> 'color_code')::TEXT, ''),
+ 'color_code_dark', COALESCE((_task_info ->> 'color_code_dark')::TEXT, ''),
+ 'total_tasks', COALESCE((_task_info ->> 'total_tasks')::INT, 0),
+ 'total_completed', COALESCE((_task_info ->> 'total_completed')::INT, 0),
+ 'members', COALESCE((_task_info ->> 'members')::JSON, '[]'::JSON),
'completed_at', _task_completed_at,
- 'status_category', _status_category,
- 'schedule_id', _schedule_id
+ 'status_category', COALESCE(_status_category, '{}'::JSON),
+ 'schedule_id', COALESCE(_schedule_id, 'null'::JSON)
);
END
$$;
@@ -4317,6 +4325,7 @@ DECLARE
_from_group UUID;
_to_group UUID;
_group_by TEXT;
+ _batch_size INT := 100; -- PERFORMANCE OPTIMIZATION: Batch size for large updates
BEGIN
_project_id = (_body ->> 'project_id')::UUID;
_task_id = (_body ->> 'task_id')::UUID;
@@ -4329,16 +4338,26 @@ BEGIN
_group_by = (_body ->> 'group_by')::TEXT;
+ -- PERFORMANCE OPTIMIZATION: Use CTE for better query planning
IF (_from_group <> _to_group OR (_from_group <> _to_group) IS NULL)
THEN
+ -- PERFORMANCE OPTIMIZATION: Batch update group changes
IF (_group_by = 'status')
THEN
- UPDATE tasks SET status_id = _to_group WHERE id = _task_id AND status_id = _from_group;
+ UPDATE tasks
+ SET status_id = _to_group
+ WHERE id = _task_id
+ AND status_id = _from_group
+ AND project_id = _project_id;
END IF;
IF (_group_by = 'priority')
THEN
- UPDATE tasks SET priority_id = _to_group WHERE id = _task_id AND priority_id = _from_group;
+ UPDATE tasks
+ SET priority_id = _to_group
+ WHERE id = _task_id
+ AND priority_id = _from_group
+ AND project_id = _project_id;
END IF;
IF (_group_by = 'phase')
@@ -4357,14 +4376,15 @@ BEGIN
END IF;
END IF;
+ -- PERFORMANCE OPTIMIZATION: Optimized sort order handling
IF ((_body ->> 'to_last_index')::BOOLEAN IS TRUE AND _from_index < _to_index)
THEN
- PERFORM handle_task_list_sort_inside_group(_from_index, _to_index, _task_id, _project_id);
+ PERFORM handle_task_list_sort_inside_group_optimized(_from_index, _to_index, _task_id, _project_id, _batch_size);
ELSE
- PERFORM handle_task_list_sort_between_groups(_from_index, _to_index, _task_id, _project_id);
+ PERFORM handle_task_list_sort_between_groups_optimized(_from_index, _to_index, _task_id, _project_id, _batch_size);
END IF;
ELSE
- PERFORM handle_task_list_sort_inside_group(_from_index, _to_index, _task_id, _project_id);
+ PERFORM handle_task_list_sort_inside_group_optimized(_from_index, _to_index, _task_id, _project_id, _batch_size);
END IF;
END
$$;
@@ -5477,8 +5497,15 @@ $$
DECLARE
_iterator NUMERIC := 0;
_status_id TEXT;
+ _project_id UUID;
+ _base_sort_order NUMERIC;
BEGIN
+ -- Get the project_id from the first status to ensure we update all statuses in the same project
+ SELECT project_id INTO _project_id
+ FROM task_statuses
+ WHERE id = (SELECT TRIM(BOTH '"' FROM JSON_ARRAY_ELEMENTS(_status_ids)::TEXT) LIMIT 1)::UUID;
+ -- Update the sort_order for statuses in the provided order
FOR _status_id IN SELECT * FROM JSON_ARRAY_ELEMENTS((_status_ids)::JSON)
LOOP
UPDATE task_statuses
@@ -5487,6 +5514,29 @@ BEGIN
_iterator := _iterator + 1;
END LOOP;
+ -- Get the base sort order for remaining statuses (simple count approach)
+ SELECT COUNT(*) INTO _base_sort_order
+ FROM task_statuses ts2
+ WHERE ts2.project_id = _project_id
+ AND ts2.id = ANY(SELECT (TRIM(BOTH '"' FROM JSON_ARRAY_ELEMENTS(_status_ids)::TEXT))::UUID);
+
+ -- Update remaining statuses with simple sequential numbering
+ -- Reset iterator to start from base_sort_order
+ _iterator := _base_sort_order;
+
+ -- Use a cursor approach to avoid window functions
+ FOR _status_id IN
+ SELECT id::TEXT FROM task_statuses
+ WHERE project_id = _project_id
+ AND id NOT IN (SELECT (TRIM(BOTH '"' FROM JSON_ARRAY_ELEMENTS(_status_ids)::TEXT))::UUID)
+ ORDER BY sort_order
+ LOOP
+ UPDATE task_statuses
+ SET sort_order = _iterator
+ WHERE id = _status_id::UUID;
+ _iterator := _iterator + 1;
+ END LOOP;
+
RETURN;
END
$$;
@@ -6148,3 +6198,360 @@ BEGIN
RETURN v_new_id;
END;
$$;
+
+CREATE OR REPLACE FUNCTION transfer_team_ownership(_team_id UUID, _new_owner_id UUID) RETURNS json
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _old_owner_id UUID;
+ _owner_role_id UUID;
+ _admin_role_id UUID;
+ _old_org_id UUID;
+ _new_org_id UUID;
+ _has_license BOOLEAN;
+ _old_owner_role_id UUID;
+ _new_owner_role_id UUID;
+ _has_active_coupon BOOLEAN;
+ _other_teams_count INTEGER;
+ _new_owner_org_id UUID;
+ _license_type_id UUID;
+ _has_valid_license BOOLEAN;
+BEGIN
+ -- Get the current owner's ID and organization
+ SELECT t.user_id, t.organization_id
+ INTO _old_owner_id, _old_org_id
+ FROM teams t
+ WHERE t.id = _team_id;
+
+ IF _old_owner_id IS NULL THEN
+ RAISE EXCEPTION 'Team not found';
+ END IF;
+
+ -- Get the new owner's organization
+ SELECT organization_id INTO _new_owner_org_id
+ FROM organizations
+ WHERE user_id = _new_owner_id;
+
+ -- Get the old organization
+ SELECT id INTO _old_org_id
+ FROM organizations
+ WHERE id = _old_org_id;
+
+ IF _old_org_id IS NULL THEN
+ RAISE EXCEPTION 'Organization not found';
+ END IF;
+
+ -- Check if new owner has any valid license type
+ SELECT EXISTS (
+ SELECT 1
+ FROM (
+ -- Check regular subscriptions
+ SELECT lus.user_id, lus.status, lus.active
+ FROM licensing_user_subscriptions lus
+ WHERE lus.user_id = _new_owner_id
+ AND lus.active = TRUE
+ AND lus.status IN ('active', 'trialing')
+
+ UNION ALL
+
+ -- Check custom subscriptions
+ SELECT lcs.user_id, lcs.subscription_status as status, TRUE as active
+ FROM licensing_custom_subs lcs
+ WHERE lcs.user_id = _new_owner_id
+ AND lcs.end_date > CURRENT_DATE
+
+ UNION ALL
+
+ -- Check trial status in organizations
+ SELECT o.user_id, o.subscription_status as status, TRUE as active
+ FROM organizations o
+ WHERE o.user_id = _new_owner_id
+ AND o.trial_in_progress = TRUE
+ AND o.trial_expire_date > CURRENT_DATE
+ ) valid_licenses
+ ) INTO _has_valid_license;
+
+ IF NOT _has_valid_license THEN
+ RAISE EXCEPTION 'New owner does not have a valid license (subscription, custom subscription, or trial)';
+ END IF;
+
+ -- Check if new owner has any active coupon codes
+ SELECT EXISTS (
+ SELECT 1
+ FROM licensing_coupon_codes lcc
+ WHERE lcc.redeemed_by = _new_owner_id
+ AND lcc.is_redeemed = TRUE
+ AND lcc.is_refunded = FALSE
+ ) INTO _has_active_coupon;
+
+ IF _has_active_coupon THEN
+ RAISE EXCEPTION 'New owner has active coupon codes that need to be handled before transfer';
+ END IF;
+
+ -- Count other teams in the organization for information purposes
+ SELECT COUNT(*) INTO _other_teams_count
+ FROM teams
+ WHERE organization_id = _old_org_id
+ AND id != _team_id;
+
+ -- If new owner has their own organization, move the team to their organization
+ IF _new_owner_org_id IS NOT NULL THEN
+ -- Update the team to use the new owner's organization
+ UPDATE teams
+ SET user_id = _new_owner_id,
+ organization_id = _new_owner_org_id
+ WHERE id = _team_id;
+
+ -- Create notification about organization change
+ PERFORM create_notification(
+ _old_owner_id,
+ _team_id,
+ NULL,
+ NULL,
+ CONCAT('Team ', (SELECT name FROM teams WHERE id = _team_id), ' has been moved to a different organization')
+ );
+
+ PERFORM create_notification(
+ _new_owner_id,
+ _team_id,
+ NULL,
+ NULL,
+ CONCAT('Team ', (SELECT name FROM teams WHERE id = _team_id), ' has been moved to your organization')
+ );
+ ELSE
+ -- If new owner doesn't have an organization, transfer the old organization to them
+ UPDATE organizations
+ SET user_id = _new_owner_id
+ WHERE id = _old_org_id;
+
+ -- Update the team to use the same organization
+ UPDATE teams
+ SET user_id = _new_owner_id,
+ organization_id = _old_org_id
+ WHERE id = _team_id;
+
+ -- Notify both users about organization ownership transfer
+ PERFORM create_notification(
+ _old_owner_id,
+ NULL,
+ NULL,
+ NULL,
+ CONCAT('You are no longer the owner of organization ', (SELECT organization_name FROM organizations WHERE id = _old_org_id), '')
+ );
+
+ PERFORM create_notification(
+ _new_owner_id,
+ NULL,
+ NULL,
+ NULL,
+ CONCAT('You are now the owner of organization ', (SELECT organization_name FROM organizations WHERE id = _old_org_id), '')
+ );
+ END IF;
+
+ -- Get the owner and admin role IDs
+ SELECT id INTO _owner_role_id FROM roles WHERE team_id = _team_id AND owner = TRUE;
+ SELECT id INTO _admin_role_id FROM roles WHERE team_id = _team_id AND admin_role = TRUE;
+
+ -- Get current role IDs for both users
+ SELECT role_id INTO _old_owner_role_id
+ FROM team_members
+ WHERE team_id = _team_id AND user_id = _old_owner_id;
+
+ SELECT role_id INTO _new_owner_role_id
+ FROM team_members
+ WHERE team_id = _team_id AND user_id = _new_owner_id;
+
+ -- Update the old owner's role to admin if they want to stay in the team
+ IF _old_owner_role_id IS NOT NULL THEN
+ UPDATE team_members
+ SET role_id = _admin_role_id
+ WHERE team_id = _team_id AND user_id = _old_owner_id;
+ END IF;
+
+ -- Update the new owner's role to owner
+ IF _new_owner_role_id IS NOT NULL THEN
+ UPDATE team_members
+ SET role_id = _owner_role_id
+ WHERE team_id = _team_id AND user_id = _new_owner_id;
+ ELSE
+ -- If new owner is not a team member yet, add them
+ INSERT INTO team_members (user_id, team_id, role_id)
+ VALUES (_new_owner_id, _team_id, _owner_role_id);
+ END IF;
+
+ -- Create notification for both users about team ownership
+ PERFORM create_notification(
+ _old_owner_id,
+ _team_id,
+ NULL,
+ NULL,
+ CONCAT('You are no longer the owner of team ', (SELECT name FROM teams WHERE id = _team_id), '')
+ );
+
+ PERFORM create_notification(
+ _new_owner_id,
+ _team_id,
+ NULL,
+ NULL,
+ CONCAT('You are now the owner of team ', (SELECT name FROM teams WHERE id = _team_id), '')
+ );
+
+ RETURN json_build_object(
+ 'success', TRUE,
+ 'old_owner_id', _old_owner_id,
+ 'new_owner_id', _new_owner_id,
+ 'team_id', _team_id,
+ 'old_org_id', _old_org_id,
+ 'new_org_id', COALESCE(_new_owner_org_id, _old_org_id),
+ 'old_role_id', _old_owner_role_id,
+ 'new_role_id', _new_owner_role_id,
+ 'has_valid_license', _has_valid_license,
+ 'has_active_coupon', _has_active_coupon,
+ 'other_teams_count', _other_teams_count,
+ 'org_ownership_transferred', _new_owner_org_id IS NULL,
+ 'team_moved_to_new_org', _new_owner_org_id IS NOT NULL
+ );
+END;
+$$;
+
+-- PERFORMANCE OPTIMIZATION: Optimized version with batching for large datasets
+CREATE OR REPLACE FUNCTION handle_task_list_sort_between_groups_optimized(_from_index integer, _to_index integer, _task_id uuid, _project_id uuid, _batch_size integer DEFAULT 100) RETURNS void
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _offset INT := 0;
+ _affected_rows INT;
+BEGIN
+ -- PERFORMANCE OPTIMIZATION: Use direct updates without CTE in UPDATE
+ IF (_to_index = -1)
+ THEN
+ _to_index = COALESCE((SELECT MAX(sort_order) + 1 FROM tasks WHERE project_id = _project_id), 0);
+ END IF;
+
+ -- PERFORMANCE OPTIMIZATION: Batch updates for large datasets
+ IF _to_index > _from_index
+ THEN
+ LOOP
+ UPDATE tasks
+ SET sort_order = sort_order - 1
+ WHERE project_id = _project_id
+ AND sort_order > _from_index
+ AND sort_order < _to_index
+ AND sort_order > _offset
+ AND sort_order <= _offset + _batch_size;
+
+ GET DIAGNOSTICS _affected_rows = ROW_COUNT;
+ EXIT WHEN _affected_rows = 0;
+ _offset := _offset + _batch_size;
+ END LOOP;
+
+ UPDATE tasks SET sort_order = _to_index - 1 WHERE id = _task_id AND project_id = _project_id;
+ END IF;
+
+ IF _to_index < _from_index
+ THEN
+ _offset := 0;
+ LOOP
+ UPDATE tasks
+ SET sort_order = sort_order + 1
+ WHERE project_id = _project_id
+ AND sort_order > _to_index
+ AND sort_order < _from_index
+ AND sort_order > _offset
+ AND sort_order <= _offset + _batch_size;
+
+ GET DIAGNOSTICS _affected_rows = ROW_COUNT;
+ EXIT WHEN _affected_rows = 0;
+ _offset := _offset + _batch_size;
+ END LOOP;
+
+ UPDATE tasks SET sort_order = _to_index + 1 WHERE id = _task_id AND project_id = _project_id;
+ END IF;
+END
+$$;
+
+-- PERFORMANCE OPTIMIZATION: Optimized version with batching for large datasets
+CREATE OR REPLACE FUNCTION handle_task_list_sort_inside_group_optimized(_from_index integer, _to_index integer, _task_id uuid, _project_id uuid, _batch_size integer DEFAULT 100) RETURNS void
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _offset INT := 0;
+ _affected_rows INT;
+BEGIN
+ -- PERFORMANCE OPTIMIZATION: Batch updates for large datasets without CTE in UPDATE
+ IF _to_index > _from_index
+ THEN
+ LOOP
+ UPDATE tasks
+ SET sort_order = sort_order - 1
+ WHERE project_id = _project_id
+ AND sort_order > _from_index
+ AND sort_order <= _to_index
+ AND sort_order > _offset
+ AND sort_order <= _offset + _batch_size;
+
+ GET DIAGNOSTICS _affected_rows = ROW_COUNT;
+ EXIT WHEN _affected_rows = 0;
+ _offset := _offset + _batch_size;
+ END LOOP;
+ END IF;
+
+ IF _to_index < _from_index
+ THEN
+ _offset := 0;
+ LOOP
+ UPDATE tasks
+ SET sort_order = sort_order + 1
+ WHERE project_id = _project_id
+ AND sort_order >= _to_index
+ AND sort_order < _from_index
+ AND sort_order > _offset
+ AND sort_order <= _offset + _batch_size;
+
+ GET DIAGNOSTICS _affected_rows = ROW_COUNT;
+ EXIT WHEN _affected_rows = 0;
+ _offset := _offset + _batch_size;
+ END LOOP;
+ END IF;
+
+ UPDATE tasks SET sort_order = _to_index WHERE id = _task_id AND project_id = _project_id;
+END
+$$;
+
+-- Simple function to update task sort orders in bulk
+CREATE OR REPLACE FUNCTION update_task_sort_orders_bulk(_updates json) RETURNS void
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+ _update_record RECORD;
+BEGIN
+ -- Simple approach: update each task's sort_order from the provided array
+ FOR _update_record IN
+ SELECT
+ (item->>'task_id')::uuid as task_id,
+ (item->>'sort_order')::int as sort_order,
+ (item->>'status_id')::uuid as status_id,
+ (item->>'priority_id')::uuid as priority_id,
+ (item->>'phase_id')::uuid as phase_id
+ FROM json_array_elements(_updates) as item
+ LOOP
+ UPDATE tasks
+ SET
+ sort_order = _update_record.sort_order,
+ status_id = COALESCE(_update_record.status_id, status_id),
+ priority_id = COALESCE(_update_record.priority_id, priority_id)
+ WHERE id = _update_record.task_id;
+
+ -- Handle phase updates separately since it's in a different table
+ IF _update_record.phase_id IS NOT NULL THEN
+ INSERT INTO task_phase (task_id, phase_id)
+ VALUES (_update_record.task_id, _update_record.phase_id)
+ ON CONFLICT (task_id) DO UPDATE SET phase_id = _update_record.phase_id;
+ END IF;
+ END LOOP;
+END
+$$;
diff --git a/worklenz-backend/grunt/grunt-compress.js b/worklenz-backend/grunt/grunt-compress.js
deleted file mode 100644
index b903edf6..00000000
--- a/worklenz-backend/grunt/grunt-compress.js
+++ /dev/null
@@ -1,28 +0,0 @@
-module.exports = {
- brotli_js: {
- options: {
- mode: "brotli",
- brotli: {
- mode: 1
- }
- },
- expand: true,
- cwd: "build/public",
- src: ["**/*.js"],
- dest: "build/public",
- extDot: "last",
- ext: ".js.br"
- },
- gzip_js: {
- options: {
- mode: "gzip"
- },
- files: [{
- expand: true,
- cwd: "build/public",
- src: ["**/*.js"],
- dest: "build/public",
- ext: ".js.gz"
- }]
- }
-};
diff --git a/worklenz-backend/package-lock.json b/worklenz-backend/package-lock.json
index 2953defa..1a0f78d3 100644
--- a/worklenz-backend/package-lock.json
+++ b/worklenz-backend/package-lock.json
@@ -24,6 +24,7 @@
"cors": "^2.8.5",
"cron": "^2.4.0",
"crypto-js": "^4.1.1",
+ "csrf-sync": "^4.2.1",
"csurf": "^1.11.0",
"debug": "^4.3.4",
"dotenv": "^16.3.1",
@@ -32,6 +33,7 @@
"express-rate-limit": "^6.8.0",
"express-session": "^1.17.3",
"express-validator": "^6.15.0",
+ "grunt-cli": "^1.5.0",
"helmet": "^6.2.0",
"hpp": "^0.2.3",
"http-errors": "^2.0.0",
@@ -49,7 +51,6 @@
"passport-local": "^1.0.0",
"path": "^0.12.7",
"pg": "^8.14.1",
- "pg-native": "^3.3.0",
"pug": "^3.0.2",
"redis": "^4.6.7",
"sanitize-html": "^2.11.0",
@@ -57,8 +58,10 @@
"sharp": "^0.32.6",
"slugify": "^1.6.6",
"socket.io": "^4.7.1",
+ "tinymce": "^7.8.0",
"uglify-js": "^3.17.4",
"winston": "^3.10.0",
+ "worklenz-backend": "file:",
"xss-filters": "^1.2.7"
},
"devDependencies": {
@@ -66,15 +69,17 @@
"@babel/preset-typescript": "^7.22.5",
"@types/bcrypt": "^5.0.0",
"@types/bluebird": "^3.5.38",
+ "@types/body-parser": "^1.19.2",
"@types/compression": "^1.7.2",
"@types/connect-flash": "^0.0.37",
"@types/cookie-parser": "^1.4.3",
"@types/cron": "^2.0.1",
"@types/crypto-js": "^4.2.2",
"@types/csurf": "^1.11.2",
- "@types/express": "^4.17.17",
+ "@types/express": "^4.17.21",
"@types/express-brute": "^1.0.2",
"@types/express-brute-redis": "^0.0.4",
+ "@types/express-serve-static-core": "^4.17.34",
"@types/express-session": "^1.17.7",
"@types/fs-extra": "^9.0.13",
"@types/hpp": "^0.2.2",
@@ -99,26 +104,22 @@
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"chokidar": "^3.5.3",
+ "concurrently": "^9.1.2",
+ "cpx2": "^8.0.0",
"esbuild": "^0.17.19",
"esbuild-envfile-plugin": "^1.0.5",
"esbuild-node-externals": "^1.8.0",
"eslint": "^8.45.0",
"eslint-plugin-security": "^1.7.1",
"fs-extra": "^10.1.0",
- "grunt": "^1.6.1",
- "grunt-contrib-clean": "^2.0.1",
- "grunt-contrib-compress": "^2.0.0",
- "grunt-contrib-copy": "^1.0.0",
- "grunt-contrib-uglify": "^5.2.2",
- "grunt-contrib-watch": "^1.1.0",
- "grunt-shell": "^4.0.0",
- "grunt-sync": "^0.8.2",
"highcharts": "^11.1.0",
"jest": "^28.1.3",
"jest-sonar-reporter": "^2.0.0",
"ncp": "^2.0.0",
"nodeman": "^1.1.2",
+ "rimraf": "^6.0.1",
"swagger-jsdoc": "^6.2.8",
+ "terser": "^5.40.0",
"ts-jest": "^28.0.8",
"ts-node": "^10.9.1",
"tslint": "^6.1.3",
@@ -130,23 +131,15 @@
"yarn": "WARNING: Please use npm package manager instead of yarn"
}
},
- "node_modules/@aashutoshrathi/word-wrap": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
- "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/@ampproject/remapping": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
- "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+ "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.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
@@ -157,6 +150,7 @@
"resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz",
"integrity": "sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jsdevtools/ono": "^7.1.3",
"@types/json-schema": "^7.0.6",
@@ -169,6 +163,7 @@
"resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz",
"integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
}
@@ -177,13 +172,15 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz",
"integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@apidevtools/swagger-parser": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz",
"integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@apidevtools/json-schema-ref-parser": "^9.0.6",
"@apidevtools/openapi-schemas": "^2.0.4",
@@ -197,792 +194,924 @@
}
},
"node_modules/@aws-crypto/crc32": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz",
- "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz",
+ "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/util": "^3.0.0",
+ "@aws-crypto/util": "^5.2.0",
"@aws-sdk/types": "^3.222.0",
- "tslib": "^1.11.1"
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
}
},
- "node_modules/@aws-crypto/crc32/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
"node_modules/@aws-crypto/crc32c": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-3.0.0.tgz",
- "integrity": "sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz",
+ "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/util": "^3.0.0",
+ "@aws-crypto/util": "^5.2.0",
"@aws-sdk/types": "^3.222.0",
- "tslib": "^1.11.1"
+ "tslib": "^2.6.2"
}
},
- "node_modules/@aws-crypto/crc32c/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
- "node_modules/@aws-crypto/ie11-detection": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz",
- "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==",
- "dependencies": {
- "tslib": "^1.11.1"
- }
- },
- "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
"node_modules/@aws-crypto/sha1-browser": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-3.0.0.tgz",
- "integrity": "sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz",
+ "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/ie11-detection": "^3.0.0",
- "@aws-crypto/supports-web-crypto": "^3.0.0",
- "@aws-crypto/util": "^3.0.0",
+ "@aws-crypto/supports-web-crypto": "^5.2.0",
+ "@aws-crypto/util": "^5.2.0",
"@aws-sdk/types": "^3.222.0",
"@aws-sdk/util-locate-window": "^3.0.0",
- "@aws-sdk/util-utf8-browser": "^3.0.0",
- "tslib": "^1.11.1"
- }
- },
- "node_modules/@aws-crypto/sha1-browser/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
- "node_modules/@aws-crypto/sha256-browser": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz",
- "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==",
- "dependencies": {
- "@aws-crypto/ie11-detection": "^3.0.0",
- "@aws-crypto/sha256-js": "^3.0.0",
- "@aws-crypto/supports-web-crypto": "^3.0.0",
- "@aws-crypto/util": "^3.0.0",
- "@aws-sdk/types": "^3.222.0",
- "@aws-sdk/util-locate-window": "^3.0.0",
- "@aws-sdk/util-utf8-browser": "^3.0.0",
- "tslib": "^1.11.1"
- }
- },
- "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
- "node_modules/@aws-crypto/sha256-js": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz",
- "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==",
- "dependencies": {
- "@aws-crypto/util": "^3.0.0",
- "@aws-sdk/types": "^3.222.0",
- "tslib": "^1.11.1"
- }
- },
- "node_modules/@aws-crypto/sha256-js/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
- "node_modules/@aws-crypto/supports-web-crypto": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz",
- "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==",
- "dependencies": {
- "tslib": "^1.11.1"
- }
- },
- "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
- "node_modules/@aws-crypto/util": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz",
- "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==",
- "dependencies": {
- "@aws-sdk/types": "^3.222.0",
- "@aws-sdk/util-utf8-browser": "^3.0.0",
- "tslib": "^1.11.1"
- }
- },
- "node_modules/@aws-crypto/util/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
- "node_modules/@aws-sdk/client-s3": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.378.0.tgz",
- "integrity": "sha512-FW1CFT6Kt2Y+IiFPCd70VapcZBkS1ZhpPZttpJeugE8T2Hye1fwQDDvAwd3Slo4zMkTL+cWQkfFJSNB1Dez/pQ==",
- "dependencies": {
- "@aws-crypto/sha1-browser": "3.0.0",
- "@aws-crypto/sha256-browser": "3.0.0",
- "@aws-crypto/sha256-js": "3.0.0",
- "@aws-sdk/client-sts": "3.378.0",
- "@aws-sdk/credential-provider-node": "3.378.0",
- "@aws-sdk/middleware-bucket-endpoint": "3.378.0",
- "@aws-sdk/middleware-expect-continue": "3.378.0",
- "@aws-sdk/middleware-flexible-checksums": "3.378.0",
- "@aws-sdk/middleware-host-header": "3.378.0",
- "@aws-sdk/middleware-location-constraint": "3.378.0",
- "@aws-sdk/middleware-logger": "3.378.0",
- "@aws-sdk/middleware-recursion-detection": "3.378.0",
- "@aws-sdk/middleware-sdk-s3": "3.378.0",
- "@aws-sdk/middleware-signing": "3.378.0",
- "@aws-sdk/middleware-ssec": "3.378.0",
- "@aws-sdk/middleware-user-agent": "3.378.0",
- "@aws-sdk/signature-v4-multi-region": "3.378.0",
- "@aws-sdk/types": "3.378.0",
- "@aws-sdk/util-endpoints": "3.378.0",
- "@aws-sdk/util-user-agent-browser": "3.378.0",
- "@aws-sdk/util-user-agent-node": "3.378.0",
- "@aws-sdk/xml-builder": "3.310.0",
- "@smithy/config-resolver": "^2.0.1",
- "@smithy/eventstream-serde-browser": "^2.0.1",
- "@smithy/eventstream-serde-config-resolver": "^2.0.1",
- "@smithy/eventstream-serde-node": "^2.0.1",
- "@smithy/fetch-http-handler": "^2.0.1",
- "@smithy/hash-blob-browser": "^2.0.1",
- "@smithy/hash-node": "^2.0.1",
- "@smithy/hash-stream-node": "^2.0.1",
- "@smithy/invalid-dependency": "^2.0.1",
- "@smithy/md5-js": "^2.0.1",
- "@smithy/middleware-content-length": "^2.0.1",
- "@smithy/middleware-endpoint": "^2.0.1",
- "@smithy/middleware-retry": "^2.0.1",
- "@smithy/middleware-serde": "^2.0.1",
- "@smithy/middleware-stack": "^2.0.0",
- "@smithy/node-config-provider": "^2.0.1",
- "@smithy/node-http-handler": "^2.0.1",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/smithy-client": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "@smithy/url-parser": "^2.0.1",
- "@smithy/util-base64": "^2.0.0",
- "@smithy/util-body-length-browser": "^2.0.0",
- "@smithy/util-body-length-node": "^2.0.0",
- "@smithy/util-defaults-mode-browser": "^2.0.1",
- "@smithy/util-defaults-mode-node": "^2.0.1",
- "@smithy/util-retry": "^2.0.0",
- "@smithy/util-stream": "^2.0.1",
"@smithy/util-utf8": "^2.0.0",
- "@smithy/util-waiter": "^2.0.1",
- "fast-xml-parser": "4.2.5",
- "tslib": "^2.5.0"
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
+ "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
},
"engines": {
"node": ">=14.0.0"
}
},
+ "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
+ "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/is-array-buffer": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
+ "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/util-buffer-from": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-browser": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz",
+ "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/sha256-js": "^5.2.0",
+ "@aws-crypto/supports-web-crypto": "^5.2.0",
+ "@aws-crypto/util": "^5.2.0",
+ "@aws-sdk/types": "^3.222.0",
+ "@aws-sdk/util-locate-window": "^3.0.0",
+ "@smithy/util-utf8": "^2.0.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
+ "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
+ "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/is-array-buffer": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
+ "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/util-buffer-from": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/sha256-js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz",
+ "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/util": "^5.2.0",
+ "@aws-sdk/types": "^3.222.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/supports-web-crypto": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz",
+ "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@aws-crypto/util": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz",
+ "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "^3.222.0",
+ "@smithy/util-utf8": "^2.0.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
+ "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
+ "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/is-array-buffer": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
+ "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/util-buffer-from": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/client-s3": {
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.840.0.tgz",
+ "integrity": "sha512-dRuo03EqGBbl9+PTogpwY9bYmGWIjn8nB82HN5Qj20otgjUvhLOdEkkip9mroYsrvqNoKbMedWdCudIcB/YY1w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/sha1-browser": "5.2.0",
+ "@aws-crypto/sha256-browser": "5.2.0",
+ "@aws-crypto/sha256-js": "5.2.0",
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/credential-provider-node": "3.840.0",
+ "@aws-sdk/middleware-bucket-endpoint": "3.840.0",
+ "@aws-sdk/middleware-expect-continue": "3.840.0",
+ "@aws-sdk/middleware-flexible-checksums": "3.840.0",
+ "@aws-sdk/middleware-host-header": "3.840.0",
+ "@aws-sdk/middleware-location-constraint": "3.840.0",
+ "@aws-sdk/middleware-logger": "3.840.0",
+ "@aws-sdk/middleware-recursion-detection": "3.840.0",
+ "@aws-sdk/middleware-sdk-s3": "3.840.0",
+ "@aws-sdk/middleware-ssec": "3.840.0",
+ "@aws-sdk/middleware-user-agent": "3.840.0",
+ "@aws-sdk/region-config-resolver": "3.840.0",
+ "@aws-sdk/signature-v4-multi-region": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@aws-sdk/util-endpoints": "3.840.0",
+ "@aws-sdk/util-user-agent-browser": "3.840.0",
+ "@aws-sdk/util-user-agent-node": "3.840.0",
+ "@aws-sdk/xml-builder": "3.821.0",
+ "@smithy/config-resolver": "^4.1.4",
+ "@smithy/core": "^3.6.0",
+ "@smithy/eventstream-serde-browser": "^4.0.4",
+ "@smithy/eventstream-serde-config-resolver": "^4.1.2",
+ "@smithy/eventstream-serde-node": "^4.0.4",
+ "@smithy/fetch-http-handler": "^5.0.4",
+ "@smithy/hash-blob-browser": "^4.0.4",
+ "@smithy/hash-node": "^4.0.4",
+ "@smithy/hash-stream-node": "^4.0.4",
+ "@smithy/invalid-dependency": "^4.0.4",
+ "@smithy/md5-js": "^4.0.4",
+ "@smithy/middleware-content-length": "^4.0.4",
+ "@smithy/middleware-endpoint": "^4.1.13",
+ "@smithy/middleware-retry": "^4.1.14",
+ "@smithy/middleware-serde": "^4.0.8",
+ "@smithy/middleware-stack": "^4.0.4",
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/node-http-handler": "^4.0.6",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/smithy-client": "^4.4.5",
+ "@smithy/types": "^4.3.1",
+ "@smithy/url-parser": "^4.0.4",
+ "@smithy/util-base64": "^4.0.0",
+ "@smithy/util-body-length-browser": "^4.0.0",
+ "@smithy/util-body-length-node": "^4.0.0",
+ "@smithy/util-defaults-mode-browser": "^4.0.21",
+ "@smithy/util-defaults-mode-node": "^4.0.21",
+ "@smithy/util-endpoints": "^3.0.6",
+ "@smithy/util-middleware": "^4.0.4",
+ "@smithy/util-retry": "^4.0.6",
+ "@smithy/util-stream": "^4.2.2",
+ "@smithy/util-utf8": "^4.0.0",
+ "@smithy/util-waiter": "^4.0.6",
+ "@types/uuid": "^9.0.1",
+ "tslib": "^2.6.2",
+ "uuid": "^9.0.1"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
"node_modules/@aws-sdk/client-ses": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.378.0.tgz",
- "integrity": "sha512-9mFGS1AYOjPcIfGeOdP8YGQSLSv+pldxTUcGytST9L8Vdj7yPY2bv/gLi+UUckTU1mKP98cQFcrBpzxawmTnDA==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.840.0.tgz",
+ "integrity": "sha512-RTIVFrAGDAOJ0xWFgCf9q0y1QrfPOCn1O6fKfjqwGig0XjwQH/YbxwC6wfV24/JAPrt2qRjkSU6SvBSVcHp9+w==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "3.0.0",
- "@aws-crypto/sha256-js": "3.0.0",
- "@aws-sdk/client-sts": "3.378.0",
- "@aws-sdk/credential-provider-node": "3.378.0",
- "@aws-sdk/middleware-host-header": "3.378.0",
- "@aws-sdk/middleware-logger": "3.378.0",
- "@aws-sdk/middleware-recursion-detection": "3.378.0",
- "@aws-sdk/middleware-signing": "3.378.0",
- "@aws-sdk/middleware-user-agent": "3.378.0",
- "@aws-sdk/types": "3.378.0",
- "@aws-sdk/util-endpoints": "3.378.0",
- "@aws-sdk/util-user-agent-browser": "3.378.0",
- "@aws-sdk/util-user-agent-node": "3.378.0",
- "@smithy/config-resolver": "^2.0.1",
- "@smithy/fetch-http-handler": "^2.0.1",
- "@smithy/hash-node": "^2.0.1",
- "@smithy/invalid-dependency": "^2.0.1",
- "@smithy/middleware-content-length": "^2.0.1",
- "@smithy/middleware-endpoint": "^2.0.1",
- "@smithy/middleware-retry": "^2.0.1",
- "@smithy/middleware-serde": "^2.0.1",
- "@smithy/middleware-stack": "^2.0.0",
- "@smithy/node-config-provider": "^2.0.1",
- "@smithy/node-http-handler": "^2.0.1",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/smithy-client": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "@smithy/url-parser": "^2.0.1",
- "@smithy/util-base64": "^2.0.0",
- "@smithy/util-body-length-browser": "^2.0.0",
- "@smithy/util-body-length-node": "^2.0.0",
- "@smithy/util-defaults-mode-browser": "^2.0.1",
- "@smithy/util-defaults-mode-node": "^2.0.1",
- "@smithy/util-retry": "^2.0.0",
- "@smithy/util-utf8": "^2.0.0",
- "@smithy/util-waiter": "^2.0.1",
- "fast-xml-parser": "4.2.5",
- "tslib": "^2.5.0"
+ "@aws-crypto/sha256-browser": "5.2.0",
+ "@aws-crypto/sha256-js": "5.2.0",
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/credential-provider-node": "3.840.0",
+ "@aws-sdk/middleware-host-header": "3.840.0",
+ "@aws-sdk/middleware-logger": "3.840.0",
+ "@aws-sdk/middleware-recursion-detection": "3.840.0",
+ "@aws-sdk/middleware-user-agent": "3.840.0",
+ "@aws-sdk/region-config-resolver": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@aws-sdk/util-endpoints": "3.840.0",
+ "@aws-sdk/util-user-agent-browser": "3.840.0",
+ "@aws-sdk/util-user-agent-node": "3.840.0",
+ "@smithy/config-resolver": "^4.1.4",
+ "@smithy/core": "^3.6.0",
+ "@smithy/fetch-http-handler": "^5.0.4",
+ "@smithy/hash-node": "^4.0.4",
+ "@smithy/invalid-dependency": "^4.0.4",
+ "@smithy/middleware-content-length": "^4.0.4",
+ "@smithy/middleware-endpoint": "^4.1.13",
+ "@smithy/middleware-retry": "^4.1.14",
+ "@smithy/middleware-serde": "^4.0.8",
+ "@smithy/middleware-stack": "^4.0.4",
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/node-http-handler": "^4.0.6",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/smithy-client": "^4.4.5",
+ "@smithy/types": "^4.3.1",
+ "@smithy/url-parser": "^4.0.4",
+ "@smithy/util-base64": "^4.0.0",
+ "@smithy/util-body-length-browser": "^4.0.0",
+ "@smithy/util-body-length-node": "^4.0.0",
+ "@smithy/util-defaults-mode-browser": "^4.0.21",
+ "@smithy/util-defaults-mode-node": "^4.0.21",
+ "@smithy/util-endpoints": "^3.0.6",
+ "@smithy/util-middleware": "^4.0.4",
+ "@smithy/util-retry": "^4.0.6",
+ "@smithy/util-utf8": "^4.0.0",
+ "@smithy/util-waiter": "^4.0.6",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/client-sso": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.378.0.tgz",
- "integrity": "sha512-xQ2myljd4T0W46WQVHnT61PLiIoGqcIJA6euClvSQndKqXt8fnJP6/kn2r+APIsjey823pjkEP4mZq8gYDiOOw==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.840.0.tgz",
+ "integrity": "sha512-3Zp+FWN2hhmKdpS0Ragi5V2ZPsZNScE3jlbgoJjzjI/roHZqO+e3/+XFN4TlM0DsPKYJNp+1TAjmhxN6rOnfYA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "3.0.0",
- "@aws-crypto/sha256-js": "3.0.0",
- "@aws-sdk/middleware-host-header": "3.378.0",
- "@aws-sdk/middleware-logger": "3.378.0",
- "@aws-sdk/middleware-recursion-detection": "3.378.0",
- "@aws-sdk/middleware-user-agent": "3.378.0",
- "@aws-sdk/types": "3.378.0",
- "@aws-sdk/util-endpoints": "3.378.0",
- "@aws-sdk/util-user-agent-browser": "3.378.0",
- "@aws-sdk/util-user-agent-node": "3.378.0",
- "@smithy/config-resolver": "^2.0.1",
- "@smithy/fetch-http-handler": "^2.0.1",
- "@smithy/hash-node": "^2.0.1",
- "@smithy/invalid-dependency": "^2.0.1",
- "@smithy/middleware-content-length": "^2.0.1",
- "@smithy/middleware-endpoint": "^2.0.1",
- "@smithy/middleware-retry": "^2.0.1",
- "@smithy/middleware-serde": "^2.0.1",
- "@smithy/middleware-stack": "^2.0.0",
- "@smithy/node-config-provider": "^2.0.1",
- "@smithy/node-http-handler": "^2.0.1",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/smithy-client": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "@smithy/url-parser": "^2.0.1",
- "@smithy/util-base64": "^2.0.0",
- "@smithy/util-body-length-browser": "^2.0.0",
- "@smithy/util-body-length-node": "^2.0.0",
- "@smithy/util-defaults-mode-browser": "^2.0.1",
- "@smithy/util-defaults-mode-node": "^2.0.1",
- "@smithy/util-retry": "^2.0.0",
- "@smithy/util-utf8": "^2.0.0",
- "tslib": "^2.5.0"
+ "@aws-crypto/sha256-browser": "5.2.0",
+ "@aws-crypto/sha256-js": "5.2.0",
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/middleware-host-header": "3.840.0",
+ "@aws-sdk/middleware-logger": "3.840.0",
+ "@aws-sdk/middleware-recursion-detection": "3.840.0",
+ "@aws-sdk/middleware-user-agent": "3.840.0",
+ "@aws-sdk/region-config-resolver": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@aws-sdk/util-endpoints": "3.840.0",
+ "@aws-sdk/util-user-agent-browser": "3.840.0",
+ "@aws-sdk/util-user-agent-node": "3.840.0",
+ "@smithy/config-resolver": "^4.1.4",
+ "@smithy/core": "^3.6.0",
+ "@smithy/fetch-http-handler": "^5.0.4",
+ "@smithy/hash-node": "^4.0.4",
+ "@smithy/invalid-dependency": "^4.0.4",
+ "@smithy/middleware-content-length": "^4.0.4",
+ "@smithy/middleware-endpoint": "^4.1.13",
+ "@smithy/middleware-retry": "^4.1.14",
+ "@smithy/middleware-serde": "^4.0.8",
+ "@smithy/middleware-stack": "^4.0.4",
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/node-http-handler": "^4.0.6",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/smithy-client": "^4.4.5",
+ "@smithy/types": "^4.3.1",
+ "@smithy/url-parser": "^4.0.4",
+ "@smithy/util-base64": "^4.0.0",
+ "@smithy/util-body-length-browser": "^4.0.0",
+ "@smithy/util-body-length-node": "^4.0.0",
+ "@smithy/util-defaults-mode-browser": "^4.0.21",
+ "@smithy/util-defaults-mode-node": "^4.0.21",
+ "@smithy/util-endpoints": "^3.0.6",
+ "@smithy/util-middleware": "^4.0.4",
+ "@smithy/util-retry": "^4.0.6",
+ "@smithy/util-utf8": "^4.0.0",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
- "node_modules/@aws-sdk/client-sso-oidc": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.378.0.tgz",
- "integrity": "sha512-+IcXH/W/TVzE0lMHuACgARgM/WxVbujGJzYUmDwj4E3uXjhTrRz69aeDk5z2EUggxKON9NOzHGZpm06VoS8uPA==",
+ "node_modules/@aws-sdk/core": {
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.840.0.tgz",
+ "integrity": "sha512-x3Zgb39tF1h2XpU+yA4OAAQlW6LVEfXNlSedSYJ7HGKXqA/E9h3rWQVpYfhXXVVsLdYXdNw5KBUkoAoruoZSZA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/sha256-browser": "3.0.0",
- "@aws-crypto/sha256-js": "3.0.0",
- "@aws-sdk/middleware-host-header": "3.378.0",
- "@aws-sdk/middleware-logger": "3.378.0",
- "@aws-sdk/middleware-recursion-detection": "3.378.0",
- "@aws-sdk/middleware-user-agent": "3.378.0",
- "@aws-sdk/types": "3.378.0",
- "@aws-sdk/util-endpoints": "3.378.0",
- "@aws-sdk/util-user-agent-browser": "3.378.0",
- "@aws-sdk/util-user-agent-node": "3.378.0",
- "@smithy/config-resolver": "^2.0.1",
- "@smithy/fetch-http-handler": "^2.0.1",
- "@smithy/hash-node": "^2.0.1",
- "@smithy/invalid-dependency": "^2.0.1",
- "@smithy/middleware-content-length": "^2.0.1",
- "@smithy/middleware-endpoint": "^2.0.1",
- "@smithy/middleware-retry": "^2.0.1",
- "@smithy/middleware-serde": "^2.0.1",
- "@smithy/middleware-stack": "^2.0.0",
- "@smithy/node-config-provider": "^2.0.1",
- "@smithy/node-http-handler": "^2.0.1",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/smithy-client": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "@smithy/url-parser": "^2.0.1",
- "@smithy/util-base64": "^2.0.0",
- "@smithy/util-body-length-browser": "^2.0.0",
- "@smithy/util-body-length-node": "^2.0.0",
- "@smithy/util-defaults-mode-browser": "^2.0.1",
- "@smithy/util-defaults-mode-node": "^2.0.1",
- "@smithy/util-retry": "^2.0.0",
- "@smithy/util-utf8": "^2.0.0",
- "tslib": "^2.5.0"
+ "@aws-sdk/types": "3.840.0",
+ "@aws-sdk/xml-builder": "3.821.0",
+ "@smithy/core": "^3.6.0",
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/property-provider": "^4.0.4",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/signature-v4": "^5.1.2",
+ "@smithy/smithy-client": "^4.4.5",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-base64": "^4.0.0",
+ "@smithy/util-body-length-browser": "^4.0.0",
+ "@smithy/util-middleware": "^4.0.4",
+ "@smithy/util-utf8": "^4.0.0",
+ "fast-xml-parser": "4.4.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@aws-sdk/client-sts": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.378.0.tgz",
- "integrity": "sha512-u7y1I5BVjKEDK6ybA4c5smkbuoSFTBQqYX9qbCFYRErIA3qCICZB3duApcVRpdypKBzwYxUkLT/qKj4s9QTvrQ==",
- "dependencies": {
- "@aws-crypto/sha256-browser": "3.0.0",
- "@aws-crypto/sha256-js": "3.0.0",
- "@aws-sdk/credential-provider-node": "3.378.0",
- "@aws-sdk/middleware-host-header": "3.378.0",
- "@aws-sdk/middleware-logger": "3.378.0",
- "@aws-sdk/middleware-recursion-detection": "3.378.0",
- "@aws-sdk/middleware-sdk-sts": "3.378.0",
- "@aws-sdk/middleware-signing": "3.378.0",
- "@aws-sdk/middleware-user-agent": "3.378.0",
- "@aws-sdk/types": "3.378.0",
- "@aws-sdk/util-endpoints": "3.378.0",
- "@aws-sdk/util-user-agent-browser": "3.378.0",
- "@aws-sdk/util-user-agent-node": "3.378.0",
- "@smithy/config-resolver": "^2.0.1",
- "@smithy/fetch-http-handler": "^2.0.1",
- "@smithy/hash-node": "^2.0.1",
- "@smithy/invalid-dependency": "^2.0.1",
- "@smithy/middleware-content-length": "^2.0.1",
- "@smithy/middleware-endpoint": "^2.0.1",
- "@smithy/middleware-retry": "^2.0.1",
- "@smithy/middleware-serde": "^2.0.1",
- "@smithy/middleware-stack": "^2.0.0",
- "@smithy/node-config-provider": "^2.0.1",
- "@smithy/node-http-handler": "^2.0.1",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/smithy-client": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "@smithy/url-parser": "^2.0.1",
- "@smithy/util-base64": "^2.0.0",
- "@smithy/util-body-length-browser": "^2.0.0",
- "@smithy/util-body-length-node": "^2.0.0",
- "@smithy/util-defaults-mode-browser": "^2.0.1",
- "@smithy/util-defaults-mode-node": "^2.0.1",
- "@smithy/util-retry": "^2.0.0",
- "@smithy/util-utf8": "^2.0.0",
- "fast-xml-parser": "4.2.5",
- "tslib": "^2.5.0"
- },
- "engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-env": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.378.0.tgz",
- "integrity": "sha512-B2OVdO9kBClDwGgWTBLAQwFV8qYTYGyVujg++1FZFSFMt8ORFdZ5fNpErvJtiSjYiOOQMzyBeSNhKyYNXCiJjQ==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.840.0.tgz",
+ "integrity": "sha512-EzF6VcJK7XvQ/G15AVEfJzN2mNXU8fcVpXo4bRyr1S6t2q5zx6UPH/XjDbn18xyUmOq01t+r8gG+TmHEVo18fA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/property-provider": "^2.0.0",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/property-provider": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/credential-provider-http": {
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.840.0.tgz",
+ "integrity": "sha512-wbnUiPGLVea6mXbUh04fu+VJmGkQvmToPeTYdHE8eRZq3NRDi3t3WltT+jArLBKD/4NppRpMjf2ju4coMCz91g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/fetch-http-handler": "^5.0.4",
+ "@smithy/node-http-handler": "^4.0.6",
+ "@smithy/property-provider": "^4.0.4",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/smithy-client": "^4.4.5",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-stream": "^4.2.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-ini": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.378.0.tgz",
- "integrity": "sha512-R34ELLCBTb+QkmWCaukNkT4vGeAipcL2wFN7Q2/WVSnJnRPPZSxzDK5rr78TiOPhRBu1k+aLDRNfslTZDknIIQ==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.840.0.tgz",
+ "integrity": "sha512-7F290BsWydShHb+7InXd+IjJc3mlEIm9I0R57F/Pjl1xZB69MdkhVGCnuETWoBt4g53ktJd6NEjzm/iAhFXFmw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/credential-provider-env": "3.378.0",
- "@aws-sdk/credential-provider-process": "3.378.0",
- "@aws-sdk/credential-provider-sso": "3.378.0",
- "@aws-sdk/credential-provider-web-identity": "3.378.0",
- "@aws-sdk/types": "3.378.0",
- "@smithy/credential-provider-imds": "^2.0.0",
- "@smithy/property-provider": "^2.0.0",
- "@smithy/shared-ini-file-loader": "^2.0.0",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/credential-provider-env": "3.840.0",
+ "@aws-sdk/credential-provider-http": "3.840.0",
+ "@aws-sdk/credential-provider-process": "3.840.0",
+ "@aws-sdk/credential-provider-sso": "3.840.0",
+ "@aws-sdk/credential-provider-web-identity": "3.840.0",
+ "@aws-sdk/nested-clients": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/credential-provider-imds": "^4.0.6",
+ "@smithy/property-provider": "^4.0.4",
+ "@smithy/shared-ini-file-loader": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-node": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.378.0.tgz",
- "integrity": "sha512-vULsOsmcqSD+Prp/yl/o1gvQAKd2oHuqI8snh4G0RAkEvoyb7vx2l0ShCoXOVY/wM9PQH8nxBHmVbiAQfSndNg==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.840.0.tgz",
+ "integrity": "sha512-KufP8JnxA31wxklLm63evUPSFApGcH8X86z3mv9SRbpCm5ycgWIGVCTXpTOdgq6rPZrwT9pftzv2/b4mV/9clg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/credential-provider-env": "3.378.0",
- "@aws-sdk/credential-provider-ini": "3.378.0",
- "@aws-sdk/credential-provider-process": "3.378.0",
- "@aws-sdk/credential-provider-sso": "3.378.0",
- "@aws-sdk/credential-provider-web-identity": "3.378.0",
- "@aws-sdk/types": "3.378.0",
- "@smithy/credential-provider-imds": "^2.0.0",
- "@smithy/property-provider": "^2.0.0",
- "@smithy/shared-ini-file-loader": "^2.0.0",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/credential-provider-env": "3.840.0",
+ "@aws-sdk/credential-provider-http": "3.840.0",
+ "@aws-sdk/credential-provider-ini": "3.840.0",
+ "@aws-sdk/credential-provider-process": "3.840.0",
+ "@aws-sdk/credential-provider-sso": "3.840.0",
+ "@aws-sdk/credential-provider-web-identity": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/credential-provider-imds": "^4.0.6",
+ "@smithy/property-provider": "^4.0.4",
+ "@smithy/shared-ini-file-loader": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-process": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.378.0.tgz",
- "integrity": "sha512-KFTIy7u+wXj3eDua4rgS0tODzMnXtXhAm1RxzCW9FL5JLBBrd82ymCj1Dp72217Sw5Do6NjCnDTTNkCHZMA77w==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.840.0.tgz",
+ "integrity": "sha512-HkDQWHy8tCI4A0Ps2NVtuVYMv9cB4y/IuD/TdOsqeRIAT12h8jDb98BwQPNLAImAOwOWzZJ8Cu0xtSpX7CQhMw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/property-provider": "^2.0.0",
- "@smithy/shared-ini-file-loader": "^2.0.0",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/property-provider": "^4.0.4",
+ "@smithy/shared-ini-file-loader": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-sso": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.378.0.tgz",
- "integrity": "sha512-lDPo/audYE/oERAef/VnHMe8THPCauH3Yu3DQYzCs+EWr1sIzp8vklWdMVQQI8cUlcLyYf4Dv9t8c+eJFZvrgw==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.840.0.tgz",
+ "integrity": "sha512-2qgdtdd6R0Z1y0KL8gzzwFUGmhBHSUx4zy85L2XV1CXhpRNwV71SVWJqLDVV5RVWVf9mg50Pm3AWrUC0xb0pcA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/client-sso": "3.378.0",
- "@aws-sdk/token-providers": "3.378.0",
- "@aws-sdk/types": "3.378.0",
- "@smithy/property-provider": "^2.0.0",
- "@smithy/shared-ini-file-loader": "^2.0.0",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/client-sso": "3.840.0",
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/token-providers": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/property-provider": "^4.0.4",
+ "@smithy/shared-ini-file-loader": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/credential-provider-web-identity": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.378.0.tgz",
- "integrity": "sha512-GWjydOszhc4xDF8xuPtBvboglXQr0gwCW1oHAvmLcOT38+Hd6qnKywnMSeoXYRPgoKfF9TkWQgW1jxplzCG0UA==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.840.0.tgz",
+ "integrity": "sha512-dpEeVXG8uNZSmVXReE4WP0lwoioX2gstk4RnUgrdUE3YaPq8A+hJiVAyc3h+cjDeIqfbsQbZm9qFetKC2LF9dQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/property-provider": "^2.0.0",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/nested-clients": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/property-provider": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/middleware-bucket-endpoint": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.378.0.tgz",
- "integrity": "sha512-3o+AYU6JWUsPM49bWglCUOgNvySiHkbIma0J6F9a68e30vEDD0FUQtKzyHPZkF7iYDyesEl166gYjwVNAmASzw==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.840.0.tgz",
+ "integrity": "sha512-+gkQNtPwcSMmlwBHFd4saVVS11In6ID1HczNzpM3MXKXRBfSlbZJbCt6wN//AZ8HMklZEik4tcEOG0qa9UY8SQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@aws-sdk/util-arn-parser": "3.310.0",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "@smithy/util-config-provider": "^2.0.0",
- "tslib": "^2.5.0"
+ "@aws-sdk/types": "3.840.0",
+ "@aws-sdk/util-arn-parser": "3.804.0",
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-config-provider": "^4.0.0",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/middleware-expect-continue": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.378.0.tgz",
- "integrity": "sha512-8maaNQvza3/IGDbIyVQkUbGlo+Oc6SY1gVG50UMcTUX8nwZrD1/ko+ft+pd2EDb2n+0JritoDj4bjr6pdesNBg==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.840.0.tgz",
+ "integrity": "sha512-iJg2r6FKsKKvdiU4oCOuCf7Ro/YE0Q2BT/QyEZN3/Rt8Nr4SAZiQOlcBXOCpGvuIKOEAhvDOUnW3aDHL01PdVw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/middleware-flexible-checksums": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.378.0.tgz",
- "integrity": "sha512-pHkcVTu2T+x/1fpPHMpRDpXY5zxDsjijv3C6Nz/nm3gQrZvQ3fYDrQdV3Oj6Xeg40B3kkcp/bzgDo7MDzG088A==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.840.0.tgz",
+ "integrity": "sha512-Kg/o2G6o72sdoRH0J+avdcf668gM1bp6O4VeEXpXwUj/urQnV5qiB2q1EYT110INHUKWOLXPND3sQAqh6sTqHw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/crc32": "3.0.0",
- "@aws-crypto/crc32c": "3.0.0",
- "@aws-sdk/types": "3.378.0",
- "@smithy/is-array-buffer": "^2.0.0",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "@smithy/util-utf8": "^2.0.0",
- "tslib": "^2.5.0"
+ "@aws-crypto/crc32": "5.2.0",
+ "@aws-crypto/crc32c": "5.2.0",
+ "@aws-crypto/util": "5.2.0",
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/is-array-buffer": "^4.0.0",
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-middleware": "^4.0.4",
+ "@smithy/util-stream": "^4.2.2",
+ "@smithy/util-utf8": "^4.0.0",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/middleware-host-header": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.378.0.tgz",
- "integrity": "sha512-zzZZ8U3MxTgSW/bpr5wNbDuGUc/lPtB9c07bD/+F81KuGCOiPIl4PA4EyMI3tftPM9DbbcFX5ZwKi9vlZ4BWcw==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.840.0.tgz",
+ "integrity": "sha512-ub+hXJAbAje94+Ya6c6eL7sYujoE8D4Bumu1NUI8TXjUhVVn0HzVWQjpRLshdLsUp1AW7XyeJaxyajRaJQ8+Xg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/middleware-location-constraint": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.378.0.tgz",
- "integrity": "sha512-Nn43avmhsDnCKtD1gQ7Xl2pvuxypnN7vvLWFeHb+7CCDKx/sK+ta+1UchNNOxh8hKL+rfBYOD2+/ZvwRRkAnAA==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.840.0.tgz",
+ "integrity": "sha512-KVLD0u0YMF3aQkVF8bdyHAGWSUY6N1Du89htTLgqCcIhSxxAJ9qifrosVZ9jkAzqRW99hcufyt2LylcVU2yoKQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/middleware-logger": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.378.0.tgz",
- "integrity": "sha512-l1DyaDLm3KeBMNMuANI3scWh8Xvu248x+vw6Z7ExWOhGXFmQ1MW7YvASg/SdxWkhlF9HmkkTif1LdMB22x6QDA==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.840.0.tgz",
+ "integrity": "sha512-lSV8FvjpdllpGaRspywss4CtXV8M7NNNH+2/j86vMH+YCOZ6fu2T/TyFd/tHwZ92vDfHctWkRbQxg0bagqwovA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/middleware-recursion-detection": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.378.0.tgz",
- "integrity": "sha512-mUMfHAz0oGNIWiTZHTVJb+I515Hqs2zx1j36Le4MMiiaMkPW1SRUF1FIwGuc1wh6E8jB5q+XfEMriDjRi4TZRA==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.840.0.tgz",
+ "integrity": "sha512-Gu7lGDyfddyhIkj1Z1JtrY5NHb5+x/CRiB87GjaSrKxkDaydtX2CU977JIABtt69l9wLbcGDIQ+W0uJ5xPof7g==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/middleware-sdk-s3": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.378.0.tgz",
- "integrity": "sha512-6PeZmQTG/GURC/fpCy71znSgn9brPSzMTIW1/cBLqW9RUB2CXb0ZsbsMPwcsN3lFgd2UHeIcZjg7wBRum/Xk/Q==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.840.0.tgz",
+ "integrity": "sha512-rOUji7CayWN3O09zvvgLzDVQe0HiJdZkxoTS6vzOS3WbbdT7joGdVtAJHtn+x776QT3hHzbKU5gnfhel0o6gQA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@aws-sdk/util-arn-parser": "3.310.0",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@aws-sdk/util-arn-parser": "3.804.0",
+ "@smithy/core": "^3.6.0",
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/signature-v4": "^5.1.2",
+ "@smithy/smithy-client": "^4.4.5",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-config-provider": "^4.0.0",
+ "@smithy/util-middleware": "^4.0.4",
+ "@smithy/util-stream": "^4.2.2",
+ "@smithy/util-utf8": "^4.0.0",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@aws-sdk/middleware-sdk-sts": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.378.0.tgz",
- "integrity": "sha512-uOoE4mvlJnR7NGIbCXQA3nI4qjWHfEETX4WzamjCQBTmoXBUlSU0hCRKvG5VHSpwI3XOu7dke9fFqbldseQzgw==",
- "dependencies": {
- "@aws-sdk/middleware-signing": "3.378.0",
- "@aws-sdk/types": "3.378.0",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@aws-sdk/middleware-signing": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.378.0.tgz",
- "integrity": "sha512-XnEQUg1wkbakDMEcwpaPq4U1qn+jdGVyPLvcvcecw09yJj0+SIG5h3xWhBYVUxm9zEJUhIYc1DnNL2V5YFeCoQ==",
- "dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/property-provider": "^2.0.0",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/signature-v4": "^2.0.0",
- "@smithy/types": "^2.0.2",
- "@smithy/util-middleware": "^2.0.0",
- "tslib": "^2.5.0"
- },
- "engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/middleware-ssec": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.378.0.tgz",
- "integrity": "sha512-WDT2LOd6OxlY1zkrRG9ZtW2vFms/dsqMg9VyE88RKG2oATxSXEhkr5zLbNVh3TyuUKnV9jydate56d/ECwHOHg==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.840.0.tgz",
+ "integrity": "sha512-CBZP9t1QbjDFGOrtnUEHL1oAvmnCUUm7p0aPNbIdSzNtH42TNKjPRN3TuEIJDGjkrqpL3MXyDSmNayDcw/XW7Q==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/middleware-user-agent": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.378.0.tgz",
- "integrity": "sha512-gwMmJgfqFh0k/Tvb+agXcdbIp9pUmYRN868CfqpKiQ7UlN8DHNixuPYrdktLkUBoEvnxmZEKdt0EnkBCdBTIcw==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.840.0.tgz",
+ "integrity": "sha512-hiiMf7BP5ZkAFAvWRcK67Mw/g55ar7OCrvrynC92hunx/xhMkrgSLM0EXIZ1oTn3uql9kH/qqGF0nqsK6K555A==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@aws-sdk/util-endpoints": "3.378.0",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@aws-sdk/util-endpoints": "3.840.0",
+ "@smithy/core": "^3.6.0",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/nested-clients": {
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.840.0.tgz",
+ "integrity": "sha512-LXYYo9+n4hRqnRSIMXLBb+BLz+cEmjMtTudwK1BF6Bn2RfdDv29KuyeDRrPCS3TwKl7ZKmXUmE9n5UuHAPfBpA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-crypto/sha256-browser": "5.2.0",
+ "@aws-crypto/sha256-js": "5.2.0",
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/middleware-host-header": "3.840.0",
+ "@aws-sdk/middleware-logger": "3.840.0",
+ "@aws-sdk/middleware-recursion-detection": "3.840.0",
+ "@aws-sdk/middleware-user-agent": "3.840.0",
+ "@aws-sdk/region-config-resolver": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@aws-sdk/util-endpoints": "3.840.0",
+ "@aws-sdk/util-user-agent-browser": "3.840.0",
+ "@aws-sdk/util-user-agent-node": "3.840.0",
+ "@smithy/config-resolver": "^4.1.4",
+ "@smithy/core": "^3.6.0",
+ "@smithy/fetch-http-handler": "^5.0.4",
+ "@smithy/hash-node": "^4.0.4",
+ "@smithy/invalid-dependency": "^4.0.4",
+ "@smithy/middleware-content-length": "^4.0.4",
+ "@smithy/middleware-endpoint": "^4.1.13",
+ "@smithy/middleware-retry": "^4.1.14",
+ "@smithy/middleware-serde": "^4.0.8",
+ "@smithy/middleware-stack": "^4.0.4",
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/node-http-handler": "^4.0.6",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/smithy-client": "^4.4.5",
+ "@smithy/types": "^4.3.1",
+ "@smithy/url-parser": "^4.0.4",
+ "@smithy/util-base64": "^4.0.0",
+ "@smithy/util-body-length-browser": "^4.0.0",
+ "@smithy/util-body-length-node": "^4.0.0",
+ "@smithy/util-defaults-mode-browser": "^4.0.21",
+ "@smithy/util-defaults-mode-node": "^4.0.21",
+ "@smithy/util-endpoints": "^3.0.6",
+ "@smithy/util-middleware": "^4.0.4",
+ "@smithy/util-retry": "^4.0.6",
+ "@smithy/util-utf8": "^4.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@aws-sdk/region-config-resolver": {
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.840.0.tgz",
+ "integrity": "sha512-Qjnxd/yDv9KpIMWr90ZDPtRj0v75AqGC92Lm9+oHXZ8p1MjG5JE2CW0HL8JRgK9iKzgKBL7pPQRXI8FkvEVfrA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-config-provider": "^4.0.0",
+ "@smithy/util-middleware": "^4.0.4",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/s3-request-presigner": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.378.0.tgz",
- "integrity": "sha512-bvrfZ+pUstwyfBZuZxG/xozfxGarldjjVX9HMxj49o1vvbGOhwRKO93XRUzV5WDk4TqKi5YcErCur0ZoqSgm4w==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.840.0.tgz",
+ "integrity": "sha512-1jcrhVoSZjiAQJGNswI0RGR36/+OG6yTV42wQamHdNHk+/68dn9MGTUVr+58AEFOyEAPE/EvkiYRD6n5WkUjMg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/signature-v4-multi-region": "3.378.0",
- "@aws-sdk/types": "3.378.0",
- "@aws-sdk/util-format-url": "3.378.0",
- "@smithy/middleware-endpoint": "^2.0.1",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/smithy-client": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/signature-v4-multi-region": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@aws-sdk/util-format-url": "3.840.0",
+ "@smithy/middleware-endpoint": "^4.1.13",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/smithy-client": "^4.4.5",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/signature-v4-multi-region": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.378.0.tgz",
- "integrity": "sha512-gtuABS7EeYZQeNzTrabY3Ruv4wWmoz4u8OMSGl47gYPDWA70WYEZ0aoi4zSGuKhXiqtVvTsO9wGEMIInwV5phQ==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.840.0.tgz",
+ "integrity": "sha512-8AoVgHrkSfhvGPtwx23hIUO4MmMnux2pjnso1lrLZGqxfElM6jm2w4jTNLlNXk8uKHGyX89HaAIuT0lL6dJj9g==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/signature-v4": "^2.0.0",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/middleware-sdk-s3": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/signature-v4": "^5.1.2",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "@aws-sdk/signature-v4-crt": "^3.118.0"
- },
- "peerDependenciesMeta": {
- "@aws-sdk/signature-v4-crt": {
- "optional": true
- }
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/token-providers": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.378.0.tgz",
- "integrity": "sha512-2J3XCwYcImKGSpv4YZ7wqt/H+P56/BAFAmZx/LqwZlkgg+arTGo76WbeM0CQCsgmKuS9xZEVlfH4z+d0H9aoyw==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.840.0.tgz",
+ "integrity": "sha512-6BuTOLTXvmgwjK7ve7aTg9JaWFdM5UoMolLVPMyh3wTv9Ufalh8oklxYHUBIxsKkBGO2WiHXytveuxH6tAgTYg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/client-sso-oidc": "3.378.0",
- "@aws-sdk/types": "3.378.0",
- "@smithy/property-provider": "^2.0.0",
- "@smithy/shared-ini-file-loader": "^2.0.0",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/core": "3.840.0",
+ "@aws-sdk/nested-clients": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/property-provider": "^4.0.4",
+ "@smithy/shared-ini-file-loader": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/types": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.378.0.tgz",
- "integrity": "sha512-qP0CvR/ItgktmN8YXpGQglzzR/6s0nrsQ4zIfx3HMwpsBTwuouYahcCtF1Vr82P4NFcoDA412EJahJ2pIqEd+w==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.840.0.tgz",
+ "integrity": "sha512-xliuHaUFZxEx1NSXeLLZ9Dyu6+EJVQKEoD+yM+zqUo3YDZ7medKJWY6fIOKiPX/N7XbLdBYwajb15Q7IL8KkeA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/util-arn-parser": {
- "version": "3.310.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.310.0.tgz",
- "integrity": "sha512-jL8509owp/xB9+Or0pvn3Fe+b94qfklc2yPowZZIFAkFcCSIdkIglz18cPDWnYAcy9JGewpMS1COXKIUhZkJsA==",
+ "version": "3.804.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.804.0.tgz",
+ "integrity": "sha512-wmBJqn1DRXnZu3b4EkE6CWnoWMo1ZMvlfkqU5zPz67xx1GMaXlDCchFvKAXMjk4jn/L1O3tKnoFDNsoLV1kgNQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.5.0"
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/util-endpoints": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.378.0.tgz",
- "integrity": "sha512-NU5C2l2xAXxpyB5nT0fIhahLPlJoJdzHWw4uC53KH9b4PrjHtgvgCN8beIsD3QxyfgeoM4A5J9Auo6WurfRnLw==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.840.0.tgz",
+ "integrity": "sha512-eqE9ROdg/Kk0rj3poutyRCFauPDXIf/WSvCqFiRDDVi6QOnCv/M0g2XW8/jSvkJlOyaXkNCptapIp6BeeFFGYw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "tslib": "^2.5.0"
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-endpoints": "^3.0.6",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/util-format-url": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.378.0.tgz",
- "integrity": "sha512-CtW2HnCq08ildVD7B5OPn1zOxBAMBjkDxqzOcLw3Rk9F6OKuMM9hawulU62tMtouJPC0QSS6eLoNOrYGch5ehQ==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.840.0.tgz",
+ "integrity": "sha512-VB1PWyI1TQPiPvg4w7tgUGGQER1xxXPNUqfh3baxUSFi1Oh8wHrDnFywkxLm3NMmgDmnLnSZ5Q326qAoyqKLSg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/querystring-builder": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/querystring-builder": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/util-locate-window": {
- "version": "3.310.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz",
- "integrity": "sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==",
+ "version": "3.804.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.804.0.tgz",
+ "integrity": "sha512-zVoRfpmBVPodYlnMjgVjfGoEZagyRF5IPn3Uo6ZvOZp24chnW/FRstH7ESDHDDRga4z3V+ElUQHKpFDXWyBW5A==",
+ "license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.5.0"
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@aws-sdk/util-user-agent-browser": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.378.0.tgz",
- "integrity": "sha512-FSCpagzftK1W+m7Ar6lpX7/Gr9y5P56nhFYz8U4EYQ4PkufS6czWX9YW+/FA5OYV0vlQ/SvPqMnzoHIPUNhZrQ==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.840.0.tgz",
+ "integrity": "sha512-JdyZM3EhhL4PqwFpttZu1afDpPJCCc3eyZOLi+srpX11LsGj6sThf47TYQN75HT1CarZ7cCdQHGzP2uy3/xHfQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/types": "^2.0.2",
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/types": "^4.3.1",
"bowser": "^2.11.0",
- "tslib": "^2.5.0"
+ "tslib": "^2.6.2"
}
},
"node_modules/@aws-sdk/util-user-agent-node": {
- "version": "3.378.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.378.0.tgz",
- "integrity": "sha512-IdwVJV0E96MkJeFte4dlWqvB+oiqCiZ5lOlheY3W9NynTuuX0GGYNC8Y9yIsV8Oava1+ujpJq0ww6qXdYxmO4A==",
+ "version": "3.840.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.840.0.tgz",
+ "integrity": "sha512-Fy5JUEDQU1tPm2Yw/YqRYYc27W5+QD/J4mYvQvdWjUGZLB5q3eLFMGD35Uc28ZFoGMufPr4OCxK/bRfWROBRHQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-sdk/types": "3.378.0",
- "@smithy/node-config-provider": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@aws-sdk/middleware-user-agent": "3.840.0",
+ "@aws-sdk/types": "3.840.0",
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
},
"peerDependencies": {
"aws-crt": ">=1.0.0"
@@ -993,23 +1122,17 @@
}
}
},
- "node_modules/@aws-sdk/util-utf8-browser": {
- "version": "3.259.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz",
- "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==",
- "dependencies": {
- "tslib": "^2.3.1"
- }
- },
"node_modules/@aws-sdk/xml-builder": {
- "version": "3.310.0",
- "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.310.0.tgz",
- "integrity": "sha512-TqELu4mOuSIKQCqj63fGVs86Yh+vBx5nHRpWKNUNhB2nPTpfbziTs5c1X358be3peVWA4wPxW7Nt53KIg1tnNw==",
+ "version": "3.821.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.821.0.tgz",
+ "integrity": "sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==",
+ "license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@azure/abort-controller": {
@@ -1039,14 +1162,14 @@
}
},
"node_modules/@azure/core-client": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.3.tgz",
- "integrity": "sha512-/wGw8fJ4mdpJ1Cum7s1S+VQyXt1ihwKLzfabS1O/RDADnmzVc01dHn44qD0BvGH6KlZNzOMW95tEpKqhkCChPA==",
+ "version": "1.9.4",
+ "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.4.tgz",
+ "integrity": "sha512-f7IxTD15Qdux30s2qFARH+JxgwxWLG2Rlr4oSkPGuLWm+1p5y1+C04XGLA0vmX6EtqfutmjvpNmAfgwVIS5hpw==",
"license": "MIT",
"dependencies": {
"@azure/abort-controller": "^2.0.0",
"@azure/core-auth": "^1.4.0",
- "@azure/core-rest-pipeline": "^1.9.1",
+ "@azure/core-rest-pipeline": "^1.20.0",
"@azure/core-tracing": "^1.0.0",
"@azure/core-util": "^1.6.1",
"@azure/logger": "^1.0.0",
@@ -1057,14 +1180,14 @@
}
},
"node_modules/@azure/core-http-compat": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.2.0.tgz",
- "integrity": "sha512-1kW8ZhN0CfbNOG6C688z5uh2yrzALE7dDXHiR9dY4vt+EbhGZQSbjDa5bQd2rf3X2pdWMsXbqbArxUyeNdvtmg==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.3.0.tgz",
+ "integrity": "sha512-qLQujmUypBBG0gxHd0j6/Jdmul6ttl24c8WGiLXIk7IHXdBlfoBqW27hyz3Xn6xbfdyVSarl1Ttbk0AwnZBYCw==",
"license": "MIT",
"dependencies": {
"@azure/abort-controller": "^2.0.0",
"@azure/core-client": "^1.3.0",
- "@azure/core-rest-pipeline": "^1.19.0"
+ "@azure/core-rest-pipeline": "^1.20.0"
},
"engines": {
"node": ">=18.0.0"
@@ -1098,9 +1221,9 @@
}
},
"node_modules/@azure/core-rest-pipeline": {
- "version": "1.19.1",
- "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.19.1.tgz",
- "integrity": "sha512-zHeoI3NCs53lLBbWNzQycjnYKsA1CVKlnzSNuSFcUDwBp8HHVObePxrM7HaX+Ha5Ks639H7chNC9HOaIhNS03w==",
+ "version": "1.21.0",
+ "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.21.0.tgz",
+ "integrity": "sha512-a4MBwe/5WKbq9MIxikzgxLBbruC5qlkFYlBdI7Ev50Y7ib5Vo/Jvt5jnJo7NaWeJ908LCHL0S1Us4UMf1VoTfg==",
"license": "MIT",
"dependencies": {
"@azure/abort-controller": "^2.0.0",
@@ -1108,36 +1231,13 @@
"@azure/core-tracing": "^1.0.1",
"@azure/core-util": "^1.11.0",
"@azure/logger": "^1.0.0",
- "http-proxy-agent": "^7.0.0",
- "https-proxy-agent": "^7.0.0",
+ "@typespec/ts-http-runtime": "^0.2.3",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
}
},
- "node_modules/@azure/core-rest-pipeline/node_modules/agent-base": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
- "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/@azure/core-rest-pipeline/node_modules/https-proxy-agent": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
- "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.2",
- "debug": "4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
"node_modules/@azure/core-tracing": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz",
@@ -1151,12 +1251,13 @@
}
},
"node_modules/@azure/core-util": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.11.0.tgz",
- "integrity": "sha512-DxOSLua+NdpWoSqULhjDyAZTXFdP/LKkqtYuxxz1SCN289zk3OG8UOpnCQAz/tygyACBtWp/BoO72ptK7msY8g==",
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.12.0.tgz",
+ "integrity": "sha512-13IyjTQgABPARvG90+N2dXpC+hwp466XCdQXPCRlbWHgd3SJd5Q1VvaBGv6k1BIa4MQm6hAF1UBU1m8QUxV8sQ==",
"license": "MIT",
"dependencies": {
"@azure/abort-controller": "^2.0.0",
+ "@typespec/ts-http-runtime": "^0.2.2",
"tslib": "^2.6.2"
},
"engines": {
@@ -1177,9 +1278,9 @@
}
},
"node_modules/@azure/core-xml/node_modules/fast-xml-parser": {
- "version": "5.0.9",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.0.9.tgz",
- "integrity": "sha512-2mBwCiuW3ycKQQ6SOesSB8WeF+fIGb6I/GG5vU5/XEptwFFhp9PE8b9O7fbs2dpq9fXn4ULR3UsfydNUCntf5A==",
+ "version": "5.2.5",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.5.tgz",
+ "integrity": "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==",
"funding": [
{
"type": "github",
@@ -1188,16 +1289,16 @@
],
"license": "MIT",
"dependencies": {
- "strnum": "^2.0.5"
+ "strnum": "^2.1.0"
},
"bin": {
"fxparser": "src/cli/cli.js"
}
},
"node_modules/@azure/core-xml/node_modules/strnum": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.0.5.tgz",
- "integrity": "sha512-YAT3K/sgpCUxhxNMrrdhtod3jckkpYwH6JAuwmUdXZsmzH1wUyzTMrrK2wYCEEqlKwrWDd35NeuUkbBy/1iK+Q==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz",
+ "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==",
"funding": [
{
"type": "github",
@@ -1207,11 +1308,12 @@
"license": "MIT"
},
"node_modules/@azure/logger": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.4.tgz",
- "integrity": "sha512-4IXXzcCdLdlXuCG+8UKEwLA1T1NHqUfanhXYHiQTn+6sfWCZXduqbtXDGceg3Ce5QxTGo7EqmbV6Bi+aqKuClQ==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.2.0.tgz",
+ "integrity": "sha512-0hKEzLhpw+ZTAfNJyRrn6s+V0nDWzXk9OjBr2TiGIu0OfMr5s2V4FpKLTAK3Ca5r5OKLbf4hkOGDPyiRjie/jA==",
"license": "MIT",
"dependencies": {
+ "@typespec/ts-http-runtime": "^0.2.2",
"tslib": "^2.6.2"
},
"engines": {
@@ -1243,47 +1345,51 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.22.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
- "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/highlight": "^7.22.13",
- "chalk": "^2.4.2"
+ "@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.22.9",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz",
- "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==",
+ "version": "7.27.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.7.tgz",
+ "integrity": "sha512-xgu/ySj2mTiUFmdE9yCMfBxLp4DHd5DwmbbD05YAuICfodYT3VvRxbrh81LGQ/8UpSdtMdfKMn3KouYDX59DGQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.22.9",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz",
- "integrity": "sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==",
+ "version": "7.27.7",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.7.tgz",
+ "integrity": "sha512-BU2f9tlKQ5CAthiMIgpzAh4eDTLWo1mqi9jqE2OxMG0E/OM199VJt2q8BztTxpnSW0i1ymdwLXRJnYzvDM5r2w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.22.5",
- "@babel/generator": "^7.22.9",
- "@babel/helper-compilation-targets": "^7.22.9",
- "@babel/helper-module-transforms": "^7.22.9",
- "@babel/helpers": "^7.22.6",
- "@babel/parser": "^7.22.7",
- "@babel/template": "^7.22.5",
- "@babel/traverse": "^7.22.8",
- "@babel/types": "^7.22.5",
- "convert-source-map": "^1.7.0",
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.27.5",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-module-transforms": "^7.27.3",
+ "@babel/helpers": "^7.27.6",
+ "@babel/parser": "^7.27.7",
+ "@babel/template": "^7.27.2",
+ "@babel/traverse": "^7.27.7",
+ "@babel/types": "^7.27.7",
+ "convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
- "json5": "^2.2.2",
+ "json5": "^2.2.3",
"semver": "^6.3.1"
},
"engines": {
@@ -1295,77 +1401,65 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
- "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
+ "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/types": "^7.23.0",
- "@jridgewell/gen-mapping": "^0.3.2",
- "@jridgewell/trace-mapping": "^0.3.17",
- "jsesc": "^2.5.1"
+ "@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-annotate-as-pure": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
- "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+ "version": "7.27.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+ "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz",
- "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
+ "@babel/types": "^7.27.3"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-compilation-targets": {
- "version": "7.22.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz",
- "integrity": "sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==",
+ "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.22.9",
- "@babel/helper-validator-option": "^7.22.5",
- "browserslist": "^4.21.9",
+ "@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"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
}
},
"node_modules/@babel/helper-create-class-features-plugin": {
- "version": "7.22.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz",
- "integrity": "sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz",
+ "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-environment-visitor": "^7.22.5",
- "@babel/helper-function-name": "^7.22.5",
- "@babel/helper-member-expression-to-functions": "^7.22.5",
- "@babel/helper-optimise-call-expression": "^7.22.5",
- "@babel/helper-replace-supers": "^7.22.9",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "@babel/helper-member-expression-to-functions": "^7.27.1",
+ "@babel/helper-optimise-call-expression": "^7.27.1",
+ "@babel/helper-replace-supers": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+ "@babel/traverse": "^7.27.1",
"semver": "^6.3.1"
},
"engines": {
@@ -1376,13 +1470,14 @@
}
},
"node_modules/@babel/helper-create-regexp-features-plugin": {
- "version": "7.22.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz",
- "integrity": "sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz",
+ "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "regexpu-core": "^5.3.1",
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "regexpu-core": "^6.2.0",
"semver": "^6.3.1"
},
"engines": {
@@ -1393,90 +1488,60 @@
}
},
"node_modules/@babel/helper-define-polyfill-provider": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz",
- "integrity": "sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==",
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz",
+ "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-compilation-targets": "^7.22.6",
- "@babel/helper-plugin-utils": "^7.22.5",
- "debug": "^4.1.1",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "debug": "^4.4.1",
"lodash.debounce": "^4.0.8",
- "resolve": "^1.14.2"
+ "resolve": "^1.22.10"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
- "node_modules/@babel/helper-environment-visitor": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
- "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-function-name": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
- "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
- "dev": true,
- "dependencies": {
- "@babel/template": "^7.22.15",
- "@babel/types": "^7.23.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-hoist-variables": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
- "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-member-expression-to-functions": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz",
- "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz",
+ "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/types": "^7.22.5"
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-imports": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz",
- "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==",
+ "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/types": "^7.22.5"
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.22.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz",
- "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==",
+ "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-environment-visitor": "^7.22.5",
- "@babel/helper-module-imports": "^7.22.5",
- "@babel/helper-simple-access": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/helper-validator-identifier": "^7.22.5"
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "@babel/traverse": "^7.27.3"
},
"engines": {
"node": ">=6.9.0"
@@ -1486,35 +1551,38 @@
}
},
"node_modules/@babel/helper-optimise-call-expression": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz",
- "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz",
+ "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/types": "^7.22.5"
+ "@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
- "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
+ "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-remap-async-to-generator": {
- "version": "7.22.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz",
- "integrity": "sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz",
+ "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-environment-visitor": "^7.22.5",
- "@babel/helper-wrap-function": "^7.22.9"
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "@babel/helper-wrap-function": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1524,14 +1592,15 @@
}
},
"node_modules/@babel/helper-replace-supers": {
- "version": "7.22.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz",
- "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz",
+ "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-environment-visitor": "^7.22.5",
- "@babel/helper-member-expression-to-functions": "^7.22.5",
- "@babel/helper-optimise-call-expression": "^7.22.5"
+ "@babel/helper-member-expression-to-functions": "^7.27.1",
+ "@babel/helper-optimise-call-expression": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1540,113 +1609,85 @@
"@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/helper-simple-access": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
- "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz",
- "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz",
+ "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-split-export-declaration": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
- "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
- "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
- "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "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.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz",
- "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==",
+ "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/helper-wrap-function": {
- "version": "7.22.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.9.tgz",
- "integrity": "sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz",
+ "integrity": "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-function-name": "^7.22.5",
- "@babel/template": "^7.22.5",
- "@babel/types": "^7.22.5"
+ "@babel/template": "^7.27.1",
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helpers": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz",
- "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==",
+ "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.22.5",
- "@babel/traverse": "^7.22.6",
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
- "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
- "dev": true,
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.22.20",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0"
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.27.6"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
- "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
+ "version": "7.27.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.7.tgz",
+ "integrity": "sha512-qnzXzDXdr/po3bOTbTIQZ7+TxNKxpkN5IifVLXS+r7qwynkZfPyjZfE7hCXbo7IoO9TNcSyibgONsf2HauUd3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.27.7"
+ },
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -1654,13 +1695,47 @@
"node": ">=6.0.0"
}
},
- "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz",
- "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==",
+ "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz",
+ "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz",
+ "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz",
+ "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1670,14 +1745,15 @@
}
},
"node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz",
- "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz",
+ "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
- "@babel/plugin-transform-optional-chaining": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+ "@babel/plugin-transform-optional-chaining": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1686,11 +1762,29 @@
"@babel/core": "^7.13.0"
}
},
+ "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.27.1.tgz",
+ "integrity": "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
"node_modules/@babel/plugin-proposal-private-property-in-object": {
"version": "7.21.0-placeholder-for-preset-env.2",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
"integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
},
@@ -1698,27 +1792,12 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-proposal-unicode-property-regex": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz",
- "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==",
- "dev": true,
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.18.6",
- "@babel/helper-plugin-utils": "^7.18.6"
- },
- "engines": {
- "node": ">=4"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
"node_modules/@babel/plugin-syntax-async-generators": {
"version": "7.8.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
"integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
},
@@ -1731,6 +1810,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
"integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
},
@@ -1743,6 +1823,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
"integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.12.13"
},
@@ -1755,6 +1836,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
"integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5"
},
@@ -1765,37 +1847,14 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-dynamic-import": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
- "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-export-namespace-from": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
- "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.3"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
"node_modules/@babel/plugin-syntax-import-assertions": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz",
- "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz",
+ "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1805,12 +1864,13 @@
}
},
"node_modules/@babel/plugin-syntax-import-attributes": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz",
- "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz",
+ "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1824,6 +1884,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
"integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.10.4"
},
@@ -1836,6 +1897,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
"integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
},
@@ -1844,12 +1906,13 @@
}
},
"node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz",
- "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz",
+ "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1863,6 +1926,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
"integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.10.4"
},
@@ -1875,6 +1939,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
"integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
},
@@ -1887,6 +1952,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
"integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.10.4"
},
@@ -1899,6 +1965,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
"integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
},
@@ -1911,6 +1978,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
"integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
},
@@ -1923,6 +1991,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
"integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
},
@@ -1935,6 +2004,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
"integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5"
},
@@ -1950,6 +2020,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
"integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5"
},
@@ -1961,12 +2032,13 @@
}
},
"node_modules/@babel/plugin-syntax-typescript": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz",
- "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz",
+ "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1980,6 +2052,7 @@
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
"integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.18.6",
"@babel/helper-plugin-utils": "^7.18.6"
@@ -1992,12 +2065,13 @@
}
},
"node_modules/@babel/plugin-transform-arrow-functions": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz",
- "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz",
+ "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2007,15 +2081,15 @@
}
},
"node_modules/@babel/plugin-transform-async-generator-functions": {
- "version": "7.22.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.7.tgz",
- "integrity": "sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.27.1.tgz",
+ "integrity": "sha512-eST9RrwlpaoJBDHShc+DS2SG4ATTi2MYNb4OxYkf3n+7eb49LWpnS+HSpVfW4x927qQwgk8A2hGNVaajAEw0EA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-environment-visitor": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-remap-async-to-generator": "^7.22.5",
- "@babel/plugin-syntax-async-generators": "^7.8.4"
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-remap-async-to-generator": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2025,14 +2099,15 @@
}
},
"node_modules/@babel/plugin-transform-async-to-generator": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz",
- "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz",
+ "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-module-imports": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-remap-async-to-generator": "^7.22.5"
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-remap-async-to-generator": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2042,12 +2117,13 @@
}
},
"node_modules/@babel/plugin-transform-block-scoped-functions": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz",
- "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz",
+ "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2057,12 +2133,13 @@
}
},
"node_modules/@babel/plugin-transform-block-scoping": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz",
- "integrity": "sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==",
+ "version": "7.27.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.5.tgz",
+ "integrity": "sha512-JF6uE2s67f0y2RZcm2kpAUEbD50vH62TyWVebxwHAlbSdM49VqPz8t4a1uIjp4NIOIZ4xzLfjY5emt/RCyC7TQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2072,13 +2149,14 @@
}
},
"node_modules/@babel/plugin-transform-class-properties": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz",
- "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz",
+ "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-class-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2088,14 +2166,14 @@
}
},
"node_modules/@babel/plugin-transform-class-static-block": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz",
- "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.27.1.tgz",
+ "integrity": "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-class-static-block": "^7.14.5"
+ "@babel/helper-create-class-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2105,19 +2183,17 @@
}
},
"node_modules/@babel/plugin-transform-classes": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz",
- "integrity": "sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==",
+ "version": "7.27.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.27.7.tgz",
+ "integrity": "sha512-CuLkokN1PEZ0Fsjtq+001aog/C2drDK9nTfK/NRK0n6rBin6cBrvM+zfQjDE+UllhR6/J4a6w8Xq9i4yi3mQrw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-compilation-targets": "^7.22.6",
- "@babel/helper-environment-visitor": "^7.22.5",
- "@babel/helper-function-name": "^7.22.5",
- "@babel/helper-optimise-call-expression": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-replace-supers": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-replace-supers": "^7.27.1",
+ "@babel/traverse": "^7.27.7",
"globals": "^11.1.0"
},
"engines": {
@@ -2128,13 +2204,14 @@
}
},
"node_modules/@babel/plugin-transform-computed-properties": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz",
- "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz",
+ "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/template": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/template": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2144,12 +2221,14 @@
}
},
"node_modules/@babel/plugin-transform-destructuring": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz",
- "integrity": "sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==",
+ "version": "7.27.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.27.7.tgz",
+ "integrity": "sha512-pg3ZLdIKWCP0CrJm0O4jYjVthyBeioVfvz9nwt6o5paUxsgJ/8GucSMAIaj6M7xA4WY+SrvtGu2LijzkdyecWQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.27.7"
},
"engines": {
"node": ">=6.9.0"
@@ -2159,13 +2238,14 @@
}
},
"node_modules/@babel/plugin-transform-dotall-regex": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz",
- "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz",
+ "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2175,12 +2255,13 @@
}
},
"node_modules/@babel/plugin-transform-duplicate-keys": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz",
- "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz",
+ "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2189,14 +2270,31 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-dynamic-import": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz",
- "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==",
+ "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz",
+ "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dynamic-import": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz",
+ "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2206,13 +2304,13 @@
}
},
"node_modules/@babel/plugin-transform-exponentiation-operator": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz",
- "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz",
+ "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2222,13 +2320,13 @@
}
},
"node_modules/@babel/plugin-transform-export-namespace-from": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz",
- "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz",
+ "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2238,12 +2336,14 @@
}
},
"node_modules/@babel/plugin-transform-for-of": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz",
- "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz",
+ "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2253,14 +2353,15 @@
}
},
"node_modules/@babel/plugin-transform-function-name": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz",
- "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz",
+ "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-compilation-targets": "^7.22.5",
- "@babel/helper-function-name": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-compilation-targets": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2270,13 +2371,13 @@
}
},
"node_modules/@babel/plugin-transform-json-strings": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz",
- "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz",
+ "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-json-strings": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2286,12 +2387,13 @@
}
},
"node_modules/@babel/plugin-transform-literals": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz",
- "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz",
+ "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2301,13 +2403,13 @@
}
},
"node_modules/@babel/plugin-transform-logical-assignment-operators": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz",
- "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz",
+ "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2317,12 +2419,13 @@
}
},
"node_modules/@babel/plugin-transform-member-expression-literals": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz",
- "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz",
+ "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2332,13 +2435,14 @@
}
},
"node_modules/@babel/plugin-transform-modules-amd": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz",
- "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz",
+ "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-module-transforms": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2348,14 +2452,14 @@
}
},
"node_modules/@babel/plugin-transform-modules-commonjs": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz",
- "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz",
+ "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-simple-access": "^7.22.5"
+ "@babel/helper-module-transforms": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2365,15 +2469,16 @@
}
},
"node_modules/@babel/plugin-transform-modules-systemjs": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz",
- "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz",
+ "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-hoist-variables": "^7.22.5",
- "@babel/helper-module-transforms": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.5"
+ "@babel/helper-module-transforms": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2383,13 +2488,14 @@
}
},
"node_modules/@babel/plugin-transform-modules-umd": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz",
- "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz",
+ "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-module-transforms": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-module-transforms": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2399,13 +2505,14 @@
}
},
"node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz",
- "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz",
+ "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2415,12 +2522,13 @@
}
},
"node_modules/@babel/plugin-transform-new-target": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz",
- "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz",
+ "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2430,13 +2538,13 @@
}
},
"node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz",
- "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz",
+ "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2446,13 +2554,13 @@
}
},
"node_modules/@babel/plugin-transform-numeric-separator": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz",
- "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz",
+ "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2462,16 +2570,17 @@
}
},
"node_modules/@babel/plugin-transform-object-rest-spread": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz",
- "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==",
+ "version": "7.27.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.27.7.tgz",
+ "integrity": "sha512-201B1kFTWhckclcXpWHc8uUpYziDX/Pl4rxl0ZX0DiCZ3jknwfSUALL3QCYeeXXB37yWxJbo+g+Vfq8pAaHi3w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.22.5",
- "@babel/helper-compilation-targets": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-transform-parameters": "^7.22.5"
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/plugin-transform-destructuring": "^7.27.7",
+ "@babel/plugin-transform-parameters": "^7.27.7",
+ "@babel/traverse": "^7.27.7"
},
"engines": {
"node": ">=6.9.0"
@@ -2481,13 +2590,14 @@
}
},
"node_modules/@babel/plugin-transform-object-super": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz",
- "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz",
+ "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-replace-supers": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-replace-supers": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2497,13 +2607,13 @@
}
},
"node_modules/@babel/plugin-transform-optional-catch-binding": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz",
- "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz",
+ "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2513,14 +2623,14 @@
}
},
"node_modules/@babel/plugin-transform-optional-chaining": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.6.tgz",
- "integrity": "sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz",
+ "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2530,12 +2640,13 @@
}
},
"node_modules/@babel/plugin-transform-parameters": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz",
- "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==",
+ "version": "7.27.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz",
+ "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2545,13 +2656,14 @@
}
},
"node_modules/@babel/plugin-transform-private-methods": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz",
- "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz",
+ "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-class-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2561,15 +2673,15 @@
}
},
"node_modules/@babel/plugin-transform-private-property-in-object": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz",
- "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz",
+ "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-create-class-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "@babel/helper-create-class-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2579,12 +2691,13 @@
}
},
"node_modules/@babel/plugin-transform-property-literals": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz",
- "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz",
+ "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2594,13 +2707,13 @@
}
},
"node_modules/@babel/plugin-transform-regenerator": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz",
- "integrity": "sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==",
+ "version": "7.27.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.5.tgz",
+ "integrity": "sha512-uhB8yHerfe3MWnuLAhEbeQ4afVoqv8BQsPqrTv7e/jZ9y00kJL6l9a/f4OWaKxotmjzewfEyXE1vgDJenkQ2/Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "regenerator-transform": "^0.15.1"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2609,13 +2722,31 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-reserved-words": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz",
- "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==",
+ "node_modules/@babel/plugin-transform-regexp-modifiers": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz",
+ "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-reserved-words": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz",
+ "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2625,12 +2756,13 @@
}
},
"node_modules/@babel/plugin-transform-shorthand-properties": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz",
- "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz",
+ "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2640,13 +2772,14 @@
}
},
"node_modules/@babel/plugin-transform-spread": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz",
- "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz",
+ "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2656,12 +2789,13 @@
}
},
"node_modules/@babel/plugin-transform-sticky-regex": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz",
- "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz",
+ "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2671,12 +2805,13 @@
}
},
"node_modules/@babel/plugin-transform-template-literals": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz",
- "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz",
+ "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2686,12 +2821,13 @@
}
},
"node_modules/@babel/plugin-transform-typeof-symbol": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz",
- "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz",
+ "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2701,15 +2837,17 @@
}
},
"node_modules/@babel/plugin-transform-typescript": {
- "version": "7.22.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.9.tgz",
- "integrity": "sha512-BnVR1CpKiuD0iobHPaM1iLvcwPYN2uVFAqoLVSpEDKWuOikoCv5HbKLxclhKYUXlWkX86DoZGtqI4XhbOsyrMg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.27.1.tgz",
+ "integrity": "sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-create-class-features-plugin": "^7.22.9",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/plugin-syntax-typescript": "^7.22.5"
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "@babel/helper-create-class-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+ "@babel/plugin-syntax-typescript": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2719,12 +2857,13 @@
}
},
"node_modules/@babel/plugin-transform-unicode-escapes": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz",
- "integrity": "sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz",
+ "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2734,13 +2873,14 @@
}
},
"node_modules/@babel/plugin-transform-unicode-property-regex": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz",
- "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz",
+ "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2750,13 +2890,14 @@
}
},
"node_modules/@babel/plugin-transform-unicode-regex": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz",
- "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz",
+ "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2766,13 +2907,14 @@
}
},
"node_modules/@babel/plugin-transform-unicode-sets-regex": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz",
- "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz",
+ "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.22.5",
- "@babel/helper-plugin-utils": "^7.22.5"
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2782,90 +2924,80 @@
}
},
"node_modules/@babel/preset-env": {
- "version": "7.22.9",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.9.tgz",
- "integrity": "sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g==",
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.27.2.tgz",
+ "integrity": "sha512-Ma4zSuYSlGNRlCLO+EAzLnCmJK2vdstgv+n7aUP+/IKZrOfWHOJVdSJtuub8RzHTj3ahD37k5OKJWvzf16TQyQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.22.9",
- "@babel/helper-compilation-targets": "^7.22.9",
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-validator-option": "^7.22.5",
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5",
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5",
+ "@babel/compat-data": "^7.27.2",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-validator-option": "^7.27.1",
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1",
+ "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1",
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.27.1",
"@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/plugin-syntax-class-properties": "^7.12.13",
- "@babel/plugin-syntax-class-static-block": "^7.14.5",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
- "@babel/plugin-syntax-import-assertions": "^7.22.5",
- "@babel/plugin-syntax-import-attributes": "^7.22.5",
- "@babel/plugin-syntax-import-meta": "^7.10.4",
- "@babel/plugin-syntax-json-strings": "^7.8.3",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
- "@babel/plugin-syntax-top-level-await": "^7.14.5",
+ "@babel/plugin-syntax-import-assertions": "^7.27.1",
+ "@babel/plugin-syntax-import-attributes": "^7.27.1",
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
- "@babel/plugin-transform-arrow-functions": "^7.22.5",
- "@babel/plugin-transform-async-generator-functions": "^7.22.7",
- "@babel/plugin-transform-async-to-generator": "^7.22.5",
- "@babel/plugin-transform-block-scoped-functions": "^7.22.5",
- "@babel/plugin-transform-block-scoping": "^7.22.5",
- "@babel/plugin-transform-class-properties": "^7.22.5",
- "@babel/plugin-transform-class-static-block": "^7.22.5",
- "@babel/plugin-transform-classes": "^7.22.6",
- "@babel/plugin-transform-computed-properties": "^7.22.5",
- "@babel/plugin-transform-destructuring": "^7.22.5",
- "@babel/plugin-transform-dotall-regex": "^7.22.5",
- "@babel/plugin-transform-duplicate-keys": "^7.22.5",
- "@babel/plugin-transform-dynamic-import": "^7.22.5",
- "@babel/plugin-transform-exponentiation-operator": "^7.22.5",
- "@babel/plugin-transform-export-namespace-from": "^7.22.5",
- "@babel/plugin-transform-for-of": "^7.22.5",
- "@babel/plugin-transform-function-name": "^7.22.5",
- "@babel/plugin-transform-json-strings": "^7.22.5",
- "@babel/plugin-transform-literals": "^7.22.5",
- "@babel/plugin-transform-logical-assignment-operators": "^7.22.5",
- "@babel/plugin-transform-member-expression-literals": "^7.22.5",
- "@babel/plugin-transform-modules-amd": "^7.22.5",
- "@babel/plugin-transform-modules-commonjs": "^7.22.5",
- "@babel/plugin-transform-modules-systemjs": "^7.22.5",
- "@babel/plugin-transform-modules-umd": "^7.22.5",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5",
- "@babel/plugin-transform-new-target": "^7.22.5",
- "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5",
- "@babel/plugin-transform-numeric-separator": "^7.22.5",
- "@babel/plugin-transform-object-rest-spread": "^7.22.5",
- "@babel/plugin-transform-object-super": "^7.22.5",
- "@babel/plugin-transform-optional-catch-binding": "^7.22.5",
- "@babel/plugin-transform-optional-chaining": "^7.22.6",
- "@babel/plugin-transform-parameters": "^7.22.5",
- "@babel/plugin-transform-private-methods": "^7.22.5",
- "@babel/plugin-transform-private-property-in-object": "^7.22.5",
- "@babel/plugin-transform-property-literals": "^7.22.5",
- "@babel/plugin-transform-regenerator": "^7.22.5",
- "@babel/plugin-transform-reserved-words": "^7.22.5",
- "@babel/plugin-transform-shorthand-properties": "^7.22.5",
- "@babel/plugin-transform-spread": "^7.22.5",
- "@babel/plugin-transform-sticky-regex": "^7.22.5",
- "@babel/plugin-transform-template-literals": "^7.22.5",
- "@babel/plugin-transform-typeof-symbol": "^7.22.5",
- "@babel/plugin-transform-unicode-escapes": "^7.22.5",
- "@babel/plugin-transform-unicode-property-regex": "^7.22.5",
- "@babel/plugin-transform-unicode-regex": "^7.22.5",
- "@babel/plugin-transform-unicode-sets-regex": "^7.22.5",
- "@babel/preset-modules": "^0.1.5",
- "@babel/types": "^7.22.5",
- "babel-plugin-polyfill-corejs2": "^0.4.4",
- "babel-plugin-polyfill-corejs3": "^0.8.2",
- "babel-plugin-polyfill-regenerator": "^0.5.1",
- "core-js-compat": "^3.31.0",
+ "@babel/plugin-transform-arrow-functions": "^7.27.1",
+ "@babel/plugin-transform-async-generator-functions": "^7.27.1",
+ "@babel/plugin-transform-async-to-generator": "^7.27.1",
+ "@babel/plugin-transform-block-scoped-functions": "^7.27.1",
+ "@babel/plugin-transform-block-scoping": "^7.27.1",
+ "@babel/plugin-transform-class-properties": "^7.27.1",
+ "@babel/plugin-transform-class-static-block": "^7.27.1",
+ "@babel/plugin-transform-classes": "^7.27.1",
+ "@babel/plugin-transform-computed-properties": "^7.27.1",
+ "@babel/plugin-transform-destructuring": "^7.27.1",
+ "@babel/plugin-transform-dotall-regex": "^7.27.1",
+ "@babel/plugin-transform-duplicate-keys": "^7.27.1",
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1",
+ "@babel/plugin-transform-dynamic-import": "^7.27.1",
+ "@babel/plugin-transform-exponentiation-operator": "^7.27.1",
+ "@babel/plugin-transform-export-namespace-from": "^7.27.1",
+ "@babel/plugin-transform-for-of": "^7.27.1",
+ "@babel/plugin-transform-function-name": "^7.27.1",
+ "@babel/plugin-transform-json-strings": "^7.27.1",
+ "@babel/plugin-transform-literals": "^7.27.1",
+ "@babel/plugin-transform-logical-assignment-operators": "^7.27.1",
+ "@babel/plugin-transform-member-expression-literals": "^7.27.1",
+ "@babel/plugin-transform-modules-amd": "^7.27.1",
+ "@babel/plugin-transform-modules-commonjs": "^7.27.1",
+ "@babel/plugin-transform-modules-systemjs": "^7.27.1",
+ "@babel/plugin-transform-modules-umd": "^7.27.1",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1",
+ "@babel/plugin-transform-new-target": "^7.27.1",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1",
+ "@babel/plugin-transform-numeric-separator": "^7.27.1",
+ "@babel/plugin-transform-object-rest-spread": "^7.27.2",
+ "@babel/plugin-transform-object-super": "^7.27.1",
+ "@babel/plugin-transform-optional-catch-binding": "^7.27.1",
+ "@babel/plugin-transform-optional-chaining": "^7.27.1",
+ "@babel/plugin-transform-parameters": "^7.27.1",
+ "@babel/plugin-transform-private-methods": "^7.27.1",
+ "@babel/plugin-transform-private-property-in-object": "^7.27.1",
+ "@babel/plugin-transform-property-literals": "^7.27.1",
+ "@babel/plugin-transform-regenerator": "^7.27.1",
+ "@babel/plugin-transform-regexp-modifiers": "^7.27.1",
+ "@babel/plugin-transform-reserved-words": "^7.27.1",
+ "@babel/plugin-transform-shorthand-properties": "^7.27.1",
+ "@babel/plugin-transform-spread": "^7.27.1",
+ "@babel/plugin-transform-sticky-regex": "^7.27.1",
+ "@babel/plugin-transform-template-literals": "^7.27.1",
+ "@babel/plugin-transform-typeof-symbol": "^7.27.1",
+ "@babel/plugin-transform-unicode-escapes": "^7.27.1",
+ "@babel/plugin-transform-unicode-property-regex": "^7.27.1",
+ "@babel/plugin-transform-unicode-regex": "^7.27.1",
+ "@babel/plugin-transform-unicode-sets-regex": "^7.27.1",
+ "@babel/preset-modules": "0.1.6-no-external-plugins",
+ "babel-plugin-polyfill-corejs2": "^0.4.10",
+ "babel-plugin-polyfill-corejs3": "^0.11.0",
+ "babel-plugin-polyfill-regenerator": "^0.6.1",
+ "core-js-compat": "^3.40.0",
"semver": "^6.3.1"
},
"engines": {
@@ -2876,14 +3008,13 @@
}
},
"node_modules/@babel/preset-modules": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6.tgz",
- "integrity": "sha512-ID2yj6K/4lKfhuU3+EX4UvNbIt7eACFbHmNUjzA+ep+B5971CknnA/9DEWKbRokfbbtblxxxXFJJrH47UEAMVg==",
+ "version": "0.1.6-no-external-plugins",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
+ "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.0.0",
- "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
- "@babel/plugin-transform-dotall-regex": "^7.4.4",
"@babel/types": "^7.4.4",
"esutils": "^2.0.2"
},
@@ -2892,16 +3023,17 @@
}
},
"node_modules/@babel/preset-typescript": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.22.5.tgz",
- "integrity": "sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz",
+ "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.22.5",
- "@babel/helper-validator-option": "^7.22.5",
- "@babel/plugin-syntax-jsx": "^7.22.5",
- "@babel/plugin-transform-modules-commonjs": "^7.22.5",
- "@babel/plugin-transform-typescript": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-validator-option": "^7.27.1",
+ "@babel/plugin-syntax-jsx": "^7.27.1",
+ "@babel/plugin-transform-modules-commonjs": "^7.27.1",
+ "@babel/plugin-transform-typescript": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2910,53 +3042,34 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/regjsgen": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz",
- "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==",
- "dev": true
- },
- "node_modules/@babel/runtime": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
- "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
- "dev": true,
- "dependencies": {
- "regenerator-runtime": "^0.13.11"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/template": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
- "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "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.22.13",
- "@babel/parser": "^7.22.15",
- "@babel/types": "^7.22.15"
+ "@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.23.2",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
- "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
+ "version": "7.27.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.7.tgz",
+ "integrity": "sha512-X6ZlfR/O/s5EQ/SnUSLzr+6kGnkg8HXGMzpgsMsrJVcfDtH1vIp6ctCN4eZ1LS5c0+te5Cb6Y514fASjMRJ1nw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.22.13",
- "@babel/generator": "^7.23.0",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-hoist-variables": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/parser": "^7.23.0",
- "@babel/types": "^7.23.0",
- "debug": "^4.1.0",
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.27.5",
+ "@babel/parser": "^7.27.7",
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.27.7",
+ "debug": "^4.3.1",
"globals": "^11.1.0"
},
"engines": {
@@ -2964,13 +3077,13 @@
}
},
"node_modules/@babel/types": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
- "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
+ "version": "7.27.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.7.tgz",
+ "integrity": "sha512-8OLQgDScAOHXnAz2cV+RfzzNMipuLVBz2biuAJFMV9bfkNf393je3VM8CLkjQodW5+iWsSJdSgSWT6rsZoXHPw==",
+ "license": "MIT",
"dependencies": {
- "@babel/helper-string-parser": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.20",
- "to-fast-properties": "^2.0.0"
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2980,12 +3093,14 @@
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@colors/colors": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
- "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
+ "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
+ "license": "MIT",
"engines": {
"node": ">=0.1.90"
}
@@ -2995,6 +3110,7 @@
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
},
@@ -3007,6 +3123,7 @@
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
@@ -3016,6 +3133,7 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
"integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
+ "license": "MIT",
"dependencies": {
"colorspace": "1.1.x",
"enabled": "2.0.x",
@@ -3030,6 +3148,7 @@
"arm"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
@@ -3046,6 +3165,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
@@ -3062,6 +3182,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"android"
@@ -3078,6 +3199,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -3094,6 +3216,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -3110,6 +3233,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"freebsd"
@@ -3126,6 +3250,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"freebsd"
@@ -3142,6 +3267,7 @@
"arm"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -3158,6 +3284,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -3174,6 +3301,7 @@
"ia32"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -3190,6 +3318,7 @@
"loong64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -3206,6 +3335,7 @@
"mips64el"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -3222,6 +3352,7 @@
"ppc64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -3238,6 +3369,7 @@
"riscv64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -3254,6 +3386,7 @@
"s390x"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -3270,6 +3403,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -3286,6 +3420,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"netbsd"
@@ -3302,6 +3437,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"openbsd"
@@ -3318,6 +3454,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"sunos"
@@ -3334,6 +3471,7 @@
"arm64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -3350,6 +3488,7 @@
"ia32"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -3366,6 +3505,7 @@
"x64"
],
"dev": true,
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -3375,34 +3515,40 @@
}
},
"node_modules/@eslint-community/eslint-utils": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
- "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "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.3.0"
+ "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.6.2",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz",
- "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==",
+ "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.0",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz",
- "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==",
+ "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",
@@ -3422,10 +3568,11 @@
}
},
"node_modules/@eslint/eslintrc/node_modules/globals": {
- "version": "13.20.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
- "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
+ "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"
},
@@ -3436,11 +3583,25 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/@eslint/eslintrc/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/@eslint/eslintrc/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"
},
@@ -3449,10 +3610,11 @@
}
},
"node_modules/@eslint/js": {
- "version": "8.44.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz",
- "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==",
+ "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"
}
@@ -3461,6 +3623,7 @@
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/@fast-csv/format/-/format-4.3.5.tgz",
"integrity": "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==",
+ "license": "MIT",
"dependencies": {
"@types/node": "^14.0.1",
"lodash.escaperegexp": "^4.1.2",
@@ -3471,14 +3634,16 @@
}
},
"node_modules/@fast-csv/format/node_modules/@types/node": {
- "version": "14.18.54",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.54.tgz",
- "integrity": "sha512-uq7O52wvo2Lggsx1x21tKZgqkJpvwCseBBPtX/nKQfpVlEsLOb11zZ1CRsWUKvJF0+lzuA9jwvA7Pr2Wt7i3xw=="
+ "version": "14.18.63",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz",
+ "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==",
+ "license": "MIT"
},
"node_modules/@fast-csv/parse": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/@fast-csv/parse/-/parse-4.3.6.tgz",
"integrity": "sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==",
+ "license": "MIT",
"dependencies": {
"@types/node": "^14.0.1",
"lodash.escaperegexp": "^4.1.2",
@@ -3490,29 +3655,46 @@
}
},
"node_modules/@fast-csv/parse/node_modules/@types/node": {
- "version": "14.18.54",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.54.tgz",
- "integrity": "sha512-uq7O52wvo2Lggsx1x21tKZgqkJpvwCseBBPtX/nKQfpVlEsLOb11zZ1CRsWUKvJF0+lzuA9jwvA7Pr2Wt7i3xw=="
+ "version": "14.18.63",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz",
+ "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==",
+ "license": "MIT"
},
"node_modules/@humanwhocodes/config-array": {
- "version": "0.11.10",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
- "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==",
+ "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": "^1.2.1",
- "debug": "^4.1.1",
+ "@humanwhocodes/object-schema": "^2.0.3",
+ "debug": "^4.3.1",
"minimatch": "^3.0.5"
},
"engines": {
"node": ">=10.10.0"
}
},
+ "node_modules/@humanwhocodes/config-array/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/@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"
},
@@ -3522,16 +3704,89 @@
}
},
"node_modules/@humanwhocodes/object-schema": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
- "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
- "dev": true
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@isaacs/balanced-match": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
+ "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/@isaacs/brace-expansion": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
+ "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@isaacs/balanced-match": "^4.0.1"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
},
"node_modules/@istanbuljs/load-nyc-config": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
"integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"camelcase": "^5.3.1",
"find-up": "^4.1.0",
@@ -3548,6 +3803,7 @@
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"sprintf-js": "~1.0.2"
}
@@ -3557,6 +3813,7 @@
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
@@ -3570,6 +3827,7 @@
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
@@ -3583,6 +3841,7 @@
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-locate": "^4.1.0"
},
@@ -3595,6 +3854,7 @@
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-try": "^2.0.0"
},
@@ -3610,6 +3870,7 @@
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-limit": "^2.2.0"
},
@@ -3622,21 +3883,17 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
- "node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
- "dev": true
- },
"node_modules/@istanbuljs/schema": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
"integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -3646,6 +3903,7 @@
"resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz",
"integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/types": "^28.1.3",
"@types/node": "*",
@@ -3658,81 +3916,12 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/@jest/console/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@jest/console/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@jest/console/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/@jest/console/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/@jest/console/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/console/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/@jest/core": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz",
"integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/console": "^28.1.3",
"@jest/reporters": "^28.1.3",
@@ -3776,74 +3965,56 @@
}
}
},
- "node_modules/@jest/core/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==",
+ "node_modules/@jest/core/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": {
- "color-convert": "^2.0.1"
+ "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": ">=8"
+ "node": "*"
},
"funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/@jest/core/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "node_modules/@jest/core/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": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
+ "brace-expansion": "^1.1.7"
},
"engines": {
- "node": ">=10"
+ "node": "*"
+ }
+ },
+ "node_modules/@jest/core/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/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@jest/core/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/@jest/core/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/@jest/core/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/core/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@jest/environment": {
@@ -3851,6 +4022,7 @@
"resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz",
"integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/fake-timers": "^28.1.3",
"@jest/types": "^28.1.3",
@@ -3866,6 +4038,7 @@
"resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz",
"integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"expect": "^28.1.3",
"jest-snapshot": "^28.1.3"
@@ -3879,6 +4052,7 @@
"resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz",
"integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"jest-get-type": "^28.0.2"
},
@@ -3891,6 +4065,7 @@
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz",
"integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/types": "^28.1.3",
"@sinonjs/fake-timers": "^9.1.2",
@@ -3908,6 +4083,7 @@
"resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz",
"integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/environment": "^28.1.3",
"@jest/expect": "^28.1.3",
@@ -3922,6 +4098,7 @@
"resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz",
"integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@bcoe/v8-coverage": "^0.2.3",
"@jest/console": "^28.1.3",
@@ -3961,74 +4138,39 @@
}
}
},
- "node_modules/@jest/reporters/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==",
+ "node_modules/@jest/reporters/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": {
- "color-convert": "^2.0.1"
+ "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": ">=8"
+ "node": "*"
},
"funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/@jest/reporters/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "node_modules/@jest/reporters/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": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
+ "brace-expansion": "^1.1.7"
},
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@jest/reporters/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/@jest/reporters/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/@jest/reporters/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/reporters/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
+ "node": "*"
}
},
"node_modules/@jest/schemas": {
@@ -4036,6 +4178,7 @@
"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz",
"integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@sinclair/typebox": "^0.24.1"
},
@@ -4048,6 +4191,7 @@
"resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz",
"integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.13",
"callsites": "^3.0.0",
@@ -4062,6 +4206,7 @@
"resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz",
"integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/console": "^28.1.3",
"@jest/types": "^28.1.3",
@@ -4077,6 +4222,7 @@
"resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz",
"integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/test-result": "^28.1.3",
"graceful-fs": "^4.2.9",
@@ -4092,6 +4238,7 @@
"resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz",
"integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/core": "^7.11.6",
"@jest/types": "^28.1.3",
@@ -4113,81 +4260,19 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/@jest/transform/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "node_modules/@jest/transform/node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@jest/transform/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@jest/transform/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/@jest/transform/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/@jest/transform/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/transform/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
+ "license": "MIT"
},
"node_modules/@jest/types": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz",
"integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/schemas": "^28.1.3",
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -4200,140 +4285,68 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/@jest/types/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@jest/types/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@jest/types/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/@jest/types/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/@jest/types/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/types/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
- "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.11.tgz",
+ "integrity": "sha512-C512c1ytBTio4MrpWKlJpyFHT6+qfFL8SZ58zBzJ1OOzUEjHeF1BtjY2fH7n4x/g2OV/KiiMLAivOp1DXmiMMw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/set-array": "^1.0.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
- },
- "engines": {
- "node": ">=6.0.0"
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
}
},
"node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
- "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "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.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.9.tgz",
+ "integrity": "sha512-amBU75CKOOkcQLfyM6J+DnWwz41yTsWI7o8MQ003LwUIWb4NYX/evAblTx1oBBYJySqL/zHPxHXDw5ewpQaUFw==",
"dev": true,
- "engines": {
- "node": ">=6.0.0"
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
- "dev": true
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.3.tgz",
+ "integrity": "sha512-AiR5uKpFxP3PjO4R19kQGIMwxyRyPuXmKEEy301V1C0+1rVjS94EZQXf1QKZYN8Q0YM+estSPhmx5JwNftv6nw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.18",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz",
- "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==",
+ "version": "0.3.28",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.28.tgz",
+ "integrity": "sha512-KNNHHwW3EIp4EDYOvYFGyIFfx36R2dNJYH4knnZlF8T5jdbD5Wx8xmSaQ2gP9URkJ04LGEtlcCtwArKcmFcwKw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/resolve-uri": "3.1.0",
- "@jridgewell/sourcemap-codec": "1.4.14"
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
}
},
- "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.14",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
- "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
- "dev": true
- },
"node_modules/@jsdevtools/ono": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
"integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@mapbox/node-pre-gyp": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
"integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
+ "license": "BSD-3-Clause",
"dependencies": {
"detect-libc": "^2.0.0",
"https-proxy-agent": "^5.0.0",
@@ -4349,24 +4362,85 @@
"node-pre-gyp": "bin/node-pre-gyp"
}
},
- "node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "node_modules/@mapbox/node-pre-gyp/node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "license": "MIT",
"dependencies": {
- "yallist": "^4.0.0"
+ "debug": "4"
},
"engines": {
- "node": ">=10"
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp/node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@mapbox/node-pre-gyp/node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -4374,16 +4448,12 @@
"node": ">=10"
}
},
- "node_modules/@mapbox/node-pre-gyp/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- },
"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"
@@ -4397,6 +4467,7 @@
"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"
}
@@ -4406,6 +4477,7 @@
"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"
@@ -4418,14 +4490,16 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
"integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
+ "license": "MIT",
"peerDependencies": {
"@redis/client": "^1.0.0"
}
},
"node_modules/@redis/client": {
- "version": "1.5.8",
- "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.5.8.tgz",
- "integrity": "sha512-xzElwHIO6rBAqzPeVnCzgvrnBEcFL1P0w8P65VNLRkdVW8rOE58f52hdj0BDgmsdOm4f1EoXPZtH4Fh7M/qUpw==",
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.1.tgz",
+ "integrity": "sha512-/KCsg3xSlR+nCK8/8ZYSknYxvXHwubJrU82F3Lm1Fp6789VQ0/3RJKfsmRXjqfaTA++23CvC3hqmqe/2GEt6Kw==",
+ "license": "MIT",
"dependencies": {
"cluster-key-slot": "1.1.2",
"generic-pool": "3.9.0",
@@ -4438,36 +4512,41 @@
"node_modules/@redis/client/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "license": "ISC"
},
"node_modules/@redis/graph": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.0.tgz",
- "integrity": "sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
+ "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
+ "license": "MIT",
"peerDependencies": {
"@redis/client": "^1.0.0"
}
},
"node_modules/@redis/json": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.4.tgz",
- "integrity": "sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz",
+ "integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==",
+ "license": "MIT",
"peerDependencies": {
"@redis/client": "^1.0.0"
}
},
"node_modules/@redis/search": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.1.3.tgz",
- "integrity": "sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz",
+ "integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==",
+ "license": "MIT",
"peerDependencies": {
"@redis/client": "^1.0.0"
}
},
"node_modules/@redis/time-series": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.0.4.tgz",
- "integrity": "sha512-ThUIgo2U/g7cCuZavucQTQzA9g9JbDDY2f64u3AbAoz/8vE2lt2U37LamDUVChhaDA3IRT9R6VvJwqnUfTJzng==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz",
+ "integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==",
+ "license": "MIT",
"peerDependencies": {
"@redis/client": "^1.0.0"
}
@@ -4476,13 +4555,15 @@
"version": "0.24.51",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
"integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@sinonjs/commons": {
"version": "1.8.6",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
"integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"type-detect": "4.0.8"
}
@@ -4492,635 +4573,770 @@
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
"integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"@sinonjs/commons": "^1.7.0"
}
},
"node_modules/@smithy/abort-controller": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.1.tgz",
- "integrity": "sha512-0s7XjIbsTwZyUW9OwXQ8J6x1UiA1TNCh60Vaw56nHahL7kUZsLhmTlWiaxfLkFtO2Utkj8YewcpHTYpxaTzO+w==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.4.tgz",
+ "integrity": "sha512-gJnEjZMvigPDQWHrW3oPrFhQtkrgqBkyjj3pCIdF3A5M6vsZODG93KNlfJprv6bp4245bdT32fsHK4kkH3KYDA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/chunked-blob-reader": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-2.0.0.tgz",
- "integrity": "sha512-k+J4GHJsMSAIQPChGBrjEmGS+WbPonCXesoqP9fynIqjn7rdOThdH8FAeCmokP9mxTYKQAKoHCLPzNlm6gh7Wg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.0.0.tgz",
+ "integrity": "sha512-+sKqDBQqb036hh4NPaUiEkYFkTUGYzRsn3EuFhyfQfMy6oGHEUJDurLP9Ufb5dasr/XiAmPNMr6wa9afjQB+Gw==",
+ "license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.5.0"
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/chunked-blob-reader-native": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-2.0.0.tgz",
- "integrity": "sha512-HM8V2Rp1y8+1343tkZUKZllFhEQPNmpNdgFAncbTsxkZ18/gqjk23XXv3qGyXWp412f3o43ZZ1UZHVcHrpRnCQ==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.0.0.tgz",
+ "integrity": "sha512-R9wM2yPmfEMsUmlMlIgSzOyICs0x9uu7UTHoccMyt7BWw8shcGM8HqB355+BZCPBcySvbTYMs62EgEQkNxz2ig==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/util-base64": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/util-base64": "^4.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/config-resolver": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.1.tgz",
- "integrity": "sha512-l83Pm7hV+8CBQOCmBRopWDtF+CURUJol7NsuPYvimiDhkC2F8Ba9T1imSFE+pD1UIJ9jlsDPAnZfPJT5cjnuEw==",
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.1.4.tgz",
+ "integrity": "sha512-prmU+rDddxHOH0oNcwemL+SwnzcG65sBF2yXRO7aeXIn/xTlq2pX7JLVbkBnVLowHLg4/OL4+jBmv9hVrVGS+w==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "@smithy/util-config-provider": "^2.0.0",
- "@smithy/util-middleware": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-config-provider": "^4.0.0",
+ "@smithy/util-middleware": "^4.0.4",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/core": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.6.0.tgz",
+ "integrity": "sha512-Pgvfb+TQ4wUNLyHzvgCP4aYZMh16y7GcfF59oirRHcgGgkH1e/s9C0nv/v3WP+Quymyr5je71HeFQCwh+44XLg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/middleware-serde": "^4.0.8",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-base64": "^4.0.0",
+ "@smithy/util-body-length-browser": "^4.0.0",
+ "@smithy/util-middleware": "^4.0.4",
+ "@smithy/util-stream": "^4.2.2",
+ "@smithy/util-utf8": "^4.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/credential-provider-imds": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.0.1.tgz",
- "integrity": "sha512-8VxriuRINNEfVZjEFKBY75y9ZWAx73DZ5K/u+3LmB6r8WR2h3NaFxFKMlwlq0uzNdGhD1ouKBn9XWEGYHKiPLw==",
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.6.tgz",
+ "integrity": "sha512-hKMWcANhUiNbCJouYkZ9V3+/Qf9pteR1dnwgdyzR09R4ODEYx8BbUysHwRSyex4rZ9zapddZhLFTnT4ZijR4pw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/node-config-provider": "^2.0.1",
- "@smithy/property-provider": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "@smithy/url-parser": "^2.0.1",
- "tslib": "^2.5.0"
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/property-provider": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "@smithy/url-parser": "^4.0.4",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/eventstream-codec": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.1.tgz",
- "integrity": "sha512-/IiNB7gQM2y2ZC/GAWOWDa8+iXfhr1g9Xe5979cQEOdCWDISvrAiv18cn3OtIQUhbYOR3gm7QtCpkq1to2takQ==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.0.4.tgz",
+ "integrity": "sha512-7XoWfZqWb/QoR/rAU4VSi0mWnO2vu9/ltS6JZ5ZSZv0eovLVfDfu0/AX4ub33RsJTOth3TiFWSHS5YdztvFnig==",
+ "license": "Apache-2.0",
"dependencies": {
- "@aws-crypto/crc32": "3.0.0",
- "@smithy/types": "^2.0.2",
- "@smithy/util-hex-encoding": "^2.0.0",
- "tslib": "^2.5.0"
+ "@aws-crypto/crc32": "5.2.0",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-hex-encoding": "^4.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/eventstream-serde-browser": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-2.0.1.tgz",
- "integrity": "sha512-9E1/6ZGF7nB/Td3G1kcatU7VjjP8eZ/p/Q+0KsZc1AUPyv4lR15pmWnWj3iGBEGYI9qZBJ/7a/wPEPayabmA3Q==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.0.4.tgz",
+ "integrity": "sha512-3fb/9SYaYqbpy/z/H3yIi0bYKyAa89y6xPmIqwr2vQiUT2St+avRt8UKwsWt9fEdEasc5d/V+QjrviRaX1JRFA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/eventstream-serde-universal": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/eventstream-serde-universal": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/eventstream-serde-config-resolver": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-2.0.1.tgz",
- "integrity": "sha512-J8a+8HH8oDPIgq8Px/nPLfu9vpIjQ7XUPtP3orbs8KUh0GznNthSTy1xZP5RXjRqGQEkxPvsHf1po2+QOsgNFw==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.1.2.tgz",
+ "integrity": "sha512-JGtambizrWP50xHgbzZI04IWU7LdI0nh/wGbqH3sJesYToMi2j/DcoElqyOcqEIG/D4tNyxgRuaqBXWE3zOFhQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/eventstream-serde-node": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.0.1.tgz",
- "integrity": "sha512-wklowUz0zXJuqC7FMpriz66J8OAko3z6INTg+iMJWYB1bWv4pc5V7q36PxlZ0RKRbj0u+EThlozWgzE7Stz2Sw==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.0.4.tgz",
+ "integrity": "sha512-RD6UwNZ5zISpOWPuhVgRz60GkSIp0dy1fuZmj4RYmqLVRtejFqQ16WmfYDdoSoAjlp1LX+FnZo+/hkdmyyGZ1w==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/eventstream-serde-universal": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/eventstream-serde-universal": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/eventstream-serde-universal": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.0.1.tgz",
- "integrity": "sha512-WPPylIgVZ6wOYVgpF0Rs1LlocYyj248MRtKEEehnDvC+0tV7wmGt7H/SchCh10W4y4YUxuzPlW+mUvVMGmLSVg==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.0.4.tgz",
+ "integrity": "sha512-UeJpOmLGhq1SLox79QWw/0n2PFX+oPRE1ZyRMxPIaFEfCqWaqpB7BU9C8kpPOGEhLF7AwEqfFbtwNxGy4ReENA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/eventstream-codec": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/eventstream-codec": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/fetch-http-handler": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.0.1.tgz",
- "integrity": "sha512-/SoU/ClazgcdOxgE4zA7RX8euiELwpsrKCSvulVQvu9zpmqJRyEJn8ZTWYFV17/eHOBdHTs9kqodhNhsNT+cUw==",
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.4.tgz",
+ "integrity": "sha512-AMtBR5pHppYMVD7z7G+OlHHAcgAN7v0kVKEpHuTO4Gb199Gowh0taYi9oDStFeUhetkeP55JLSVlTW1n9rFtUw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/querystring-builder": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "@smithy/util-base64": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/querystring-builder": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-base64": "^4.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/hash-blob-browser": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-2.0.1.tgz",
- "integrity": "sha512-i/o2+sHb4jDRz5nf2ilTTbC0nVmm4LO//FbODCAB7pbzMdywxbZ6z+q56FmEa8R+aFbtApxQ1SJ3umEiNz6IPg==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.0.4.tgz",
+ "integrity": "sha512-WszRiACJiQV3QG6XMV44i5YWlkrlsM5Yxgz4jvsksuu7LDXA6wAtypfPajtNTadzpJy3KyJPoWehYpmZGKUFIQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/chunked-blob-reader": "^2.0.0",
- "@smithy/chunked-blob-reader-native": "^2.0.0",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/chunked-blob-reader": "^5.0.0",
+ "@smithy/chunked-blob-reader-native": "^4.0.0",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/hash-node": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.0.1.tgz",
- "integrity": "sha512-oTKYimQdF4psX54ZonpcIE+MXjMUWFxLCNosjPkJPFQ9whRX0K/PFX/+JZGRQh3zO9RlEOEUIbhy9NO+Wha6hw==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.4.tgz",
+ "integrity": "sha512-qnbTPUhCVnCgBp4z4BUJUhOEkVwxiEi1cyFM+Zj6o+aY8OFGxUQleKWq8ltgp3dujuhXojIvJWdoqpm6dVO3lQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "@smithy/util-buffer-from": "^2.0.0",
- "@smithy/util-utf8": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-buffer-from": "^4.0.0",
+ "@smithy/util-utf8": "^4.0.0",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/hash-stream-node": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-2.0.1.tgz",
- "integrity": "sha512-AequnQdPRuXf4AuvvFlSjnkWI460xxhAd6y362gFtOE4jjJLLXblbMAXVFrkV8/pDMGNjpVegVSpRmHXZsbKhg==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.0.4.tgz",
+ "integrity": "sha512-wHo0d8GXyVmpmMh/qOR0R7Y46/G1y6OR8U+bSTB4ppEzRxd1xVAQ9xOE9hOc0bSjhz0ujCPAbfNLkLrpa6cevg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "@smithy/util-utf8": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-utf8": "^4.0.0",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/invalid-dependency": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.0.1.tgz",
- "integrity": "sha512-2q/Eb0AE662zwyMV+z+TL7deBwcHCgaZZGc0RItamBE8kak3MzCi/EZCNoFWoBfxgQ4jfR12wm8KKsSXhJzJtQ==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.4.tgz",
+ "integrity": "sha512-bNYMi7WKTJHu0gn26wg8OscncTt1t2b8KcsZxvOv56XA6cyXtOAAAaNP7+m45xfppXfOatXF3Sb1MNsLUgVLTw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/is-array-buffer": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.0.0.tgz",
- "integrity": "sha512-z3PjFjMyZNI98JFRJi/U0nGoLWMSJlDjAW4QUX2WNZLas5C0CmVV6LJ01JI0k90l7FvpmixjWxPFmENSClQ7ug==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz",
+ "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==",
+ "license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.5.0"
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/md5-js": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-2.0.1.tgz",
- "integrity": "sha512-8WWOtwWMmIDgTkRv1o3opy3ABsRXs4/XunETK53ckxQRAiOML1PlnqLBK9Uwk9bvOD6cpmsC6dioIfmKGpJ25w==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.0.4.tgz",
+ "integrity": "sha512-uGLBVqcOwrLvGh/v/jw423yWHq/ofUGK1W31M2TNspLQbUV1Va0F5kTxtirkoHawODAZcjXTSGi7JwbnPcDPJg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "@smithy/util-utf8": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-utf8": "^4.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/middleware-content-length": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.0.1.tgz",
- "integrity": "sha512-IZhRSk5GkVBcrKaqPXddBS2uKhaqwBgaSgbBb1OJyGsKe7SxRFbclWS0LqOR9fKUkDl+3lL8E2ffpo6EQg0igw==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.4.tgz",
+ "integrity": "sha512-F7gDyfI2BB1Kc+4M6rpuOLne5LOcEknH1n6UQB69qv+HucXBR1rkzXBnQTB2q46sFy1PM/zuSJOB532yc8bg3w==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/middleware-endpoint": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.0.1.tgz",
- "integrity": "sha512-uz/KI1MBd9WHrrkVFZO4L4Wyv24raf0oR4EsOYEeG5jPJO5U+C7MZGLcMxX8gWERDn1sycBDqmGv8fjUMLxT6w==",
+ "version": "4.1.13",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.13.tgz",
+ "integrity": "sha512-xg3EHV/Q5ZdAO5b0UiIMj3RIOCobuS40pBBODguUDVdko6YK6QIzCVRrHTogVuEKglBWqWenRnZ71iZnLL3ZAQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/middleware-serde": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "@smithy/url-parser": "^2.0.1",
- "@smithy/util-middleware": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/core": "^3.6.0",
+ "@smithy/middleware-serde": "^4.0.8",
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/shared-ini-file-loader": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "@smithy/url-parser": "^4.0.4",
+ "@smithy/util-middleware": "^4.0.4",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/middleware-retry": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.1.tgz",
- "integrity": "sha512-NKHF4i0gjSyjO6C0ZyjEpNqzGgIu7s8HOK6oT/1Jqws2Q1GynR1xV8XTUs1gKXeaNRzbzKQRewHHmfPwZjOtHA==",
+ "version": "4.1.14",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.14.tgz",
+ "integrity": "sha512-eoXaLlDGpKvdmvt+YBfRXE7HmIEtFF+DJCbTPwuLunP0YUnrydl+C4tS+vEM0+nyxXrX3PSUFqC+lP1+EHB1Tw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/service-error-classification": "^2.0.0",
- "@smithy/types": "^2.0.2",
- "@smithy/util-middleware": "^2.0.0",
- "@smithy/util-retry": "^2.0.0",
- "tslib": "^2.5.0",
- "uuid": "^8.3.2"
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/service-error-classification": "^4.0.6",
+ "@smithy/smithy-client": "^4.4.5",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-middleware": "^4.0.4",
+ "@smithy/util-retry": "^4.0.6",
+ "tslib": "^2.6.2",
+ "uuid": "^9.0.1"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/middleware-serde": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.0.1.tgz",
- "integrity": "sha512-uKxPaC6ItH9ZXdpdqNtf8sda7GcU4SPMp0tomq/5lUg9oiMa/Q7+kD35MUrpKaX3IVXVrwEtkjCU9dogZ/RAUA==",
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.8.tgz",
+ "integrity": "sha512-iSSl7HJoJaGyMIoNn2B7czghOVwJ9nD7TMvLhMWeSB5vt0TnEYyRRqPJu/TqW76WScaNvYYB8nRoiBHR9S1Ddw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/middleware-stack": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.0.0.tgz",
- "integrity": "sha512-31XC1xNF65nlbc16yuh3wwTudmqs6qy4EseQUGF8A/p2m/5wdd/cnXJqpniy/XvXVwkHPz/GwV36HqzHtIKATQ==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.4.tgz",
+ "integrity": "sha512-kagK5ggDrBUCCzI93ft6DjteNSfY8Ulr83UtySog/h09lTIOAJ/xUSObutanlPT0nhoHAkpmW9V5K8oPyLh+QA==",
+ "license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/node-config-provider": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.0.1.tgz",
- "integrity": "sha512-Zoel4CPkKRTQ2XxmozZUfqBYqjPKL53/SvTDhJHj+VBSiJy6MXRav1iDCyFPS92t40Uh+Yi+Km5Ch3hQ+c/zSA==",
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.1.3.tgz",
+ "integrity": "sha512-HGHQr2s59qaU1lrVH6MbLlmOBxadtzTsoO4c+bF5asdgVik3I8o7JIOzoeqWc5MjVa+vD36/LWE0iXKpNqooRw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/property-provider": "^2.0.1",
- "@smithy/shared-ini-file-loader": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/property-provider": "^4.0.4",
+ "@smithy/shared-ini-file-loader": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/node-http-handler": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.0.1.tgz",
- "integrity": "sha512-Zv3fxk3p9tsmPT2CKMsbuwbbxnq2gzLDIulxv+yI6aE+02WPYorObbbe9gh7SW3weadMODL1vTfOoJ9yFypDzg==",
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.6.tgz",
+ "integrity": "sha512-NqbmSz7AW2rvw4kXhKGrYTiJVDHnMsFnX4i+/FzcZAfbOBauPYs2ekuECkSbtqaxETLLTu9Rl/ex6+I2BKErPA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/abort-controller": "^2.0.1",
- "@smithy/protocol-http": "^2.0.1",
- "@smithy/querystring-builder": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/abort-controller": "^4.0.4",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/querystring-builder": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/property-provider": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.0.1.tgz",
- "integrity": "sha512-pmJRyY9SF6sutWIktIhe+bUdSQDxv/qZ4mYr3/u+u45riTPN7nmRxPo+e4sjWVoM0caKFjRSlj3tf5teRFy0Vg==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.4.tgz",
+ "integrity": "sha512-qHJ2sSgu4FqF4U/5UUp4DhXNmdTrgmoAai6oQiM+c5RZ/sbDwJ12qxB1M6FnP+Tn/ggkPZf9ccn4jqKSINaquw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/protocol-http": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-2.0.1.tgz",
- "integrity": "sha512-mrkMAp0wtaDEIkgRObWYxI1Kun1tm6Iu6rK+X4utb6Ah7Uc3Kk4VIWwK/rBHdYGReiLIrxFCB1rq4a2gyZnSgg==",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.1.2.tgz",
+ "integrity": "sha512-rOG5cNLBXovxIrICSBm95dLqzfvxjEmuZx4KK3hWwPFHGdW3lxY0fZNXfv2zebfRO7sJZ5pKJYHScsqopeIWtQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/querystring-builder": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.0.1.tgz",
- "integrity": "sha512-bp+93WFzx1FojVEIeFPtG0A1pKsFdCUcZvVdZdRlmNooOUrz9Mm9bneRd8hDwAQ37pxiZkCOxopSXXRQN10mYw==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.4.tgz",
+ "integrity": "sha512-SwREZcDnEYoh9tLNgMbpop+UTGq44Hl9tdj3rf+yeLcfH7+J8OXEBaMc2kDxtyRHu8BhSg9ADEx0gFHvpJgU8w==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "@smithy/util-uri-escape": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-uri-escape": "^4.0.0",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/querystring-parser": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.0.1.tgz",
- "integrity": "sha512-h+e7k1z+IvI2sSbUBG9Aq46JsgLl4UqIUl6aigAlRBj+P6ocNXpM6Yn1vMBw5ijtXeZbYpd1YvCxwDgdw3jhmg==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.4.tgz",
+ "integrity": "sha512-6yZf53i/qB8gRHH/l2ZwUG5xgkPgQF15/KxH0DdXMDHjesA9MeZje/853ifkSY0x4m5S+dfDZ+c4x439PF0M2w==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/service-error-classification": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.0.0.tgz",
- "integrity": "sha512-2z5Nafy1O0cTf69wKyNjGW/sNVMiqDnb4jgwfMG8ye8KnFJ5qmJpDccwIbJNhXIfbsxTg9SEec2oe1cexhMJvw==",
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.6.tgz",
+ "integrity": "sha512-RRoTDL//7xi4tn5FrN2NzH17jbgmnKidUqd4KvquT0954/i6CXXkh1884jBiunq24g9cGtPBEXlU40W6EpNOOg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/types": "^4.3.1"
+ },
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/shared-ini-file-loader": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.0.1.tgz",
- "integrity": "sha512-a463YiZrPGvM+F336rIF8pLfQsHAdCRAn/BiI/EWzg5xLoxbC7GSxIgliDDXrOu0z8gT3nhVsif85eU6jyct3A==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.4.tgz",
+ "integrity": "sha512-63X0260LoFBjrHifPDs+nM9tV0VMkOTl4JRMYNuKh/f5PauSjowTfvF3LogfkWdcPoxsA9UjqEOgjeYIbhb7Nw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/signature-v4": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.0.1.tgz",
- "integrity": "sha512-jztv5Mirca42ilxmMDjzLdXcoAmRhZskGafGL49sRo5u7swEZcToEFrq6vtX5YMbSyTVrE9Teog5EFexY5Ff2Q==",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.1.2.tgz",
+ "integrity": "sha512-d3+U/VpX7a60seHziWnVZOHuEgJlclufjkS6zhXvxcJgkJq4UWdH5eOBLzHRMx6gXjsdT9h6lfpmLzbrdupHgQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/eventstream-codec": "^2.0.1",
- "@smithy/is-array-buffer": "^2.0.0",
- "@smithy/types": "^2.0.2",
- "@smithy/util-hex-encoding": "^2.0.0",
- "@smithy/util-middleware": "^2.0.0",
- "@smithy/util-uri-escape": "^2.0.0",
- "@smithy/util-utf8": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/is-array-buffer": "^4.0.0",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-hex-encoding": "^4.0.0",
+ "@smithy/util-middleware": "^4.0.4",
+ "@smithy/util-uri-escape": "^4.0.0",
+ "@smithy/util-utf8": "^4.0.0",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/smithy-client": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.0.1.tgz",
- "integrity": "sha512-LHC5m6tYpEu1iNbONfvMbwtErboyTZJfEIPoD78Ei5MVr36vZQCaCla5mvo36+q/a2NAk2//fA5Rx3I1Kf7+lQ==",
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.4.5.tgz",
+ "integrity": "sha512-+lynZjGuUFJaMdDYSTMnP/uPBBXXukVfrJlP+1U/Dp5SFTEI++w6NMga8DjOENxecOF71V9Z2DllaVDYRnGlkg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/middleware-stack": "^2.0.0",
- "@smithy/types": "^2.0.2",
- "@smithy/util-stream": "^2.0.1",
- "tslib": "^2.5.0"
+ "@smithy/core": "^3.6.0",
+ "@smithy/middleware-endpoint": "^4.1.13",
+ "@smithy/middleware-stack": "^4.0.4",
+ "@smithy/protocol-http": "^5.1.2",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-stream": "^4.2.2",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/types": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.0.2.tgz",
- "integrity": "sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw==",
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.3.1.tgz",
+ "integrity": "sha512-UqKOQBL2x6+HWl3P+3QqFD4ncKq0I8Nuz9QItGv5WuKuMHuuwlhvqcZCoXGfc+P1QmfJE7VieykoYYmrOoFJxA==",
+ "license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.5.0"
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/url-parser": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.0.1.tgz",
- "integrity": "sha512-NpHVOAwddo+OyyIoujDL9zGL96piHWrTNXqltWmBvlUoWgt1HPyBuKs6oHjioyFnNZXUqveTOkEEq0U5w6Uv8A==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.4.tgz",
+ "integrity": "sha512-eMkc144MuN7B0TDA4U2fKs+BqczVbk3W+qIvcoCY6D1JY3hnAdCuhCZODC+GAeaxj0p6Jroz4+XMUn3PCxQQeQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/querystring-parser": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/querystring-parser": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-base64": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-2.0.0.tgz",
- "integrity": "sha512-Zb1E4xx+m5Lud8bbeYi5FkcMJMnn+1WUnJF3qD7rAdXpaL7UjkFQLdmW5fHadoKbdHpwH9vSR8EyTJFHJs++tA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz",
+ "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/util-buffer-from": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/util-buffer-from": "^4.0.0",
+ "@smithy/util-utf8": "^4.0.0",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-body-length-browser": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-2.0.0.tgz",
- "integrity": "sha512-JdDuS4ircJt+FDnaQj88TzZY3+njZ6O+D3uakS32f2VNnDo3vyEuNdBOh/oFd8Df1zSZOuH1HEChk2AOYDezZg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz",
+ "integrity": "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==",
+ "license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.5.0"
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-body-length-node": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-2.0.0.tgz",
- "integrity": "sha512-ZV7Z/WHTMxHJe/xL/56qZwSUcl63/5aaPAGjkfynJm4poILjdD4GmFI+V+YWabh2WJIjwTKZ5PNsuvPQKt93Mg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.0.0.tgz",
+ "integrity": "sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==",
+ "license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.5.0"
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-buffer-from": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.0.0.tgz",
- "integrity": "sha512-/YNnLoHsR+4W4Vf2wL5lGv0ksg8Bmk3GEGxn2vEQt52AQaPSCuaO5PM5VM7lP1K9qHRKHwrPGktqVoAHKWHxzw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz",
+ "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/is-array-buffer": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/is-array-buffer": "^4.0.0",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-config-provider": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-2.0.0.tgz",
- "integrity": "sha512-xCQ6UapcIWKxXHEU4Mcs2s7LcFQRiU3XEluM2WcCjjBtQkUN71Tb+ydGmJFPxMUrW/GWMgQEEGipLym4XG0jZg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.0.0.tgz",
+ "integrity": "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==",
+ "license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.5.0"
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-defaults-mode-browser": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.1.tgz",
- "integrity": "sha512-w72Qwsb+IaEYEFtYICn0Do42eFju78hTaBzzJfT107lFOPdbjWjKnFutV+6GL/nZd5HWXY7ccAKka++C3NrjHw==",
+ "version": "4.0.21",
+ "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.21.tgz",
+ "integrity": "sha512-wM0jhTytgXu3wzJoIqpbBAG5U6BwiubZ6QKzSbP7/VbmF1v96xlAbX2Am/mz0Zep0NLvLh84JT0tuZnk3wmYQA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/property-provider": "^2.0.1",
- "@smithy/types": "^2.0.2",
+ "@smithy/property-provider": "^4.0.4",
+ "@smithy/smithy-client": "^4.4.5",
+ "@smithy/types": "^4.3.1",
"bowser": "^2.11.0",
- "tslib": "^2.5.0"
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">= 10.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-defaults-mode-node": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.1.tgz",
- "integrity": "sha512-dNF45caelEBambo0SgkzQ0v76m4YM+aFKZNTtSafy7P5dVF8TbjZuR2UX1A5gJABD9XK6lzN+v/9Yfzj/EDgGg==",
+ "version": "4.0.21",
+ "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.21.tgz",
+ "integrity": "sha512-/F34zkoU0GzpUgLJydHY8Rxu9lBn8xQC/s/0M0U9lLBkYbA1htaAFjWYJzpzsbXPuri5D1H8gjp2jBum05qBrA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/config-resolver": "^2.0.1",
- "@smithy/credential-provider-imds": "^2.0.1",
- "@smithy/node-config-provider": "^2.0.1",
- "@smithy/property-provider": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/config-resolver": "^4.1.4",
+ "@smithy/credential-provider-imds": "^4.0.6",
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/property-provider": "^4.0.4",
+ "@smithy/smithy-client": "^4.4.5",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">= 10.0.0"
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@smithy/util-endpoints": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.0.6.tgz",
+ "integrity": "sha512-YARl3tFL3WgPuLzljRUnrS2ngLiUtkwhQtj8PAL13XZSyUiNLQxwG3fBBq3QXFqGFUXepIN73pINp3y8c2nBmA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@smithy/node-config-provider": "^4.1.3",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-hex-encoding": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.0.0.tgz",
- "integrity": "sha512-c5xY+NUnFqG6d7HFh1IFfrm3mGl29lC+vF+geHv4ToiuJCBmIfzx6IeHLg+OgRdPFKDXIw6pvi+p3CsscaMcMA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz",
+ "integrity": "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==",
+ "license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.5.0"
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-middleware": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.0.0.tgz",
- "integrity": "sha512-eCWX4ECuDHn1wuyyDdGdUWnT4OGyIzV0LN1xRttBFMPI9Ff/4heSHVxneyiMtOB//zpXWCha1/SWHJOZstG7kA==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.4.tgz",
+ "integrity": "sha512-9MLKmkBmf4PRb0ONJikCbCwORACcil6gUWojwARCClT7RmLzF04hUR4WdRprIXal7XVyrddadYNfp2eF3nrvtQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.5.0"
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-retry": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.0.0.tgz",
- "integrity": "sha512-/dvJ8afrElasuiiIttRJeoS2sy8YXpksQwiM/TcepqdRVp7u4ejd9C4IQURHNjlfPUT7Y6lCDSa2zQJbdHhVTg==",
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.6.tgz",
+ "integrity": "sha512-+YekoF2CaSMv6zKrA6iI/N9yva3Gzn4L6n35Luydweu5MMPYpiGZlWqehPHDHyNbnyaYlz/WJyYAZnC+loBDZg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/service-error-classification": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/service-error-classification": "^4.0.6",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">= 14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-stream": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.1.tgz",
- "integrity": "sha512-2a0IOtwIKC46EEo7E7cxDN8u2jwOiYYJqcFKA6rd5rdXqKakHT2Gc+AqHWngr0IEHUfW92zX12wRQKwyoqZf2Q==",
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.2.2.tgz",
+ "integrity": "sha512-aI+GLi7MJoVxg24/3J1ipwLoYzgkB4kUfogZfnslcYlynj3xsQ0e7vk4TnTro9hhsS5PvX1mwmkRqqHQjwcU7w==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/fetch-http-handler": "^2.0.1",
- "@smithy/node-http-handler": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "@smithy/util-base64": "^2.0.0",
- "@smithy/util-buffer-from": "^2.0.0",
- "@smithy/util-hex-encoding": "^2.0.0",
- "@smithy/util-utf8": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/fetch-http-handler": "^5.0.4",
+ "@smithy/node-http-handler": "^4.0.6",
+ "@smithy/types": "^4.3.1",
+ "@smithy/util-base64": "^4.0.0",
+ "@smithy/util-buffer-from": "^4.0.0",
+ "@smithy/util-hex-encoding": "^4.0.0",
+ "@smithy/util-utf8": "^4.0.0",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-uri-escape": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.0.0.tgz",
- "integrity": "sha512-ebkxsqinSdEooQduuk9CbKcI+wheijxEb3utGXkCoYQkJnwTnLbH1JXGimJtUkQwNQbsbuYwG2+aFVyZf5TLaw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz",
+ "integrity": "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==",
+ "license": "Apache-2.0",
"dependencies": {
- "tslib": "^2.5.0"
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-utf8": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.0.0.tgz",
- "integrity": "sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz",
+ "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/util-buffer-from": "^2.0.0",
- "tslib": "^2.5.0"
+ "@smithy/util-buffer-from": "^4.0.0",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@smithy/util-waiter": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-2.0.1.tgz",
- "integrity": "sha512-bSyGFicPRYuGFFWAr72UvYI7tE7KmEeFJJ5iaLuTTdo8RGaNBZ2kE25coGtzrejYh9AhwSfckBvbxgEDxIxhlA==",
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.0.6.tgz",
+ "integrity": "sha512-slcr1wdRbX7NFphXZOxtxRNA7hXAAtJAXJDE/wdoMAos27SIquVCKiSqfB6/28YzQ8FCsB5NKkhdM5gMADbqxg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@smithy/abort-controller": "^2.0.1",
- "@smithy/types": "^2.0.2",
- "tslib": "^2.5.0"
+ "@smithy/abort-controller": "^4.0.4",
+ "@smithy/types": "^4.3.1",
+ "tslib": "^2.6.2"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/@socket.io/component-emitter": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
- "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
+ "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
+ "license": "MIT"
},
"node_modules/@tsconfig/node10": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
- "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
- "dev": true
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
+ "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@tsconfig/node16": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/babel__core": {
- "version": "7.20.1",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz",
- "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==",
+ "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",
@@ -5130,72 +5346,81 @@
}
},
"node_modules/@types/babel__generator": {
- "version": "7.6.4",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz",
- "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==",
+ "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.1",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
- "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
+ "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.1",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz",
- "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==",
+ "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/bcrypt": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz",
- "integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz",
+ "integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/bluebird": {
- "version": "3.5.38",
- "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.38.tgz",
- "integrity": "sha512-yR/Kxc0dd4FfwtEoLZMoqJbM/VE/W7hXn/MIjb+axcwag0iFmSPK7OBUZq1YWLynJUoWQkfUrI7T0HDqGApNSg==",
- "dev": true
+ "version": "3.5.42",
+ "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.42.tgz",
+ "integrity": "sha512-Jhy+MWRlro6UjVi578V/4ZGNfeCOcNCp0YaFNIUGFKlImowqwb1O/22wDVk3FDGMLqxdpOV3qQHD5fPEH4hK6A==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/body-parser": {
- "version": "1.19.2",
- "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
- "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
+ "version": "1.19.6",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
+ "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/connect": "*",
"@types/node": "*"
}
},
"node_modules/@types/compression": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.7.2.tgz",
- "integrity": "sha512-lwEL4M/uAGWngWFLSG87ZDr2kLrbuR8p7X+QZB1OQlT+qkHsCPDVFnHPyXf4Vyl4yDDorNY+mAhosxkCvppatg==",
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.8.1.tgz",
+ "integrity": "sha512-kCFuWS0ebDbmxs0AXYn6e2r2nrGAb5KwQhknjSPSPgJcGd8+HVSILlUyFhGqML2gk39HcG7D1ydW9/qpYkN00Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@types/express": "*"
+ "@types/express": "*",
+ "@types/node": "*"
}
},
"node_modules/@types/connect": {
- "version": "3.4.35",
- "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
- "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
+ "version": "3.4.38",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
+ "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*"
}
@@ -5205,29 +5430,25 @@
"resolved": "https://registry.npmjs.org/@types/connect-flash/-/connect-flash-0.0.37.tgz",
"integrity": "sha512-SfmGGYpKvPfZeA+v74FS0HlYqVsx8Inb4d3px99kz2xSMx/IQiz/K/i+7MHTmk/OkE+0suZX108tHrQJ8QEGag==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/express": "*"
}
},
- "node_modules/@types/cookie": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
- "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==",
- "license": "MIT"
- },
"node_modules/@types/cookie-parser": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.3.tgz",
- "integrity": "sha512-CqSKwFwefj4PzZ5n/iwad/bow2hTCh0FlNAeWLtQM3JA/NX/iYagIpWG2cf1bQKQ2c9gU2log5VUCrn7LDOs0w==",
+ "version": "1.4.9",
+ "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.9.tgz",
+ "integrity": "sha512-tGZiZ2Gtc4m3wIdLkZ8mkj1T6CEHb35+VApbL2T14Dew8HA7c+04dmKqsKRNC+8RJPm16JEK0tFSwdZqubfc4g==",
"dev": true,
- "dependencies": {
+ "license": "MIT",
+ "peerDependencies": {
"@types/express": "*"
}
},
"node_modules/@types/cors": {
- "version": "2.8.17",
- "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
- "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
+ "version": "2.8.19",
+ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz",
+ "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
@@ -5238,6 +5459,7 @@
"resolved": "https://registry.npmjs.org/@types/cron/-/cron-2.0.1.tgz",
"integrity": "sha512-WHa/1rtNtD2Q/H0+YTTZoty+/5rcE66iAFX2IY+JuUoOACsevYyFkSYu/2vdw+G5LrmO7Lxowrqm0av4k3qWNQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/luxon": "*",
"@types/node": "*"
@@ -5247,22 +5469,25 @@
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.2.tgz",
"integrity": "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/csurf": {
- "version": "1.11.2",
- "resolved": "https://registry.npmjs.org/@types/csurf/-/csurf-1.11.2.tgz",
- "integrity": "sha512-9bc98EnwmC1S0aSJiA8rWwXtgXtXHHOQOsGHptImxFgqm6CeH+mIOunHRg6+/eg2tlmDMX3tY7XrWxo2M/nUNQ==",
+ "version": "1.11.5",
+ "resolved": "https://registry.npmjs.org/@types/csurf/-/csurf-1.11.5.tgz",
+ "integrity": "sha512-5rw87+5YGixyL2W8wblSUl5DSZi5YOlXE6Awwn2ofLvqKr/1LruKffrQipeJKUX44VaxKj8m5es3vfhltJTOoA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/express-serve-static-core": "*"
}
},
"node_modules/@types/express": {
- "version": "4.17.17",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz",
- "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==",
+ "version": "4.17.23",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz",
+ "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.33",
@@ -5271,10 +5496,11 @@
}
},
"node_modules/@types/express-brute": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@types/express-brute/-/express-brute-1.0.2.tgz",
- "integrity": "sha512-p+3ks+pW04poJobPxyEK3FLnBhEbEAVYhc6QXXBoVBzw5yfW+HobKvgCnaQ6d/egBym+tDXGKIuGoAAZbaJadw==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/express-brute/-/express-brute-1.0.6.tgz",
+ "integrity": "sha512-yKVX0N9dTR4CNSMEMlSLfNkDgkNws2DMfRJZD6EsqZbtpDp4wAPSLo6N2e+c4OMPC72q2V82YWDtvYUCmBfvvA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/express": "*"
}
@@ -5284,24 +5510,17 @@
"resolved": "https://registry.npmjs.org/@types/express-brute-redis/-/express-brute-redis-0.0.4.tgz",
"integrity": "sha512-pjarPr7id4sPuTMeltb8Z50rxbJxjAhLtkDbaiobeIcjnN1i+vwhq4YOeNTyAJneUPP0lossi0uvuvx9Of/zJg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/redis": "^2.8.0"
}
},
- "node_modules/@types/express-brute-redis/node_modules/@types/redis": {
- "version": "2.8.32",
- "resolved": "https://registry.npmjs.org/@types/redis/-/redis-2.8.32.tgz",
- "integrity": "sha512-7jkMKxcGq9p242exlbsVzuJb57KqHRhNl4dHoQu2Y5v9bCAbtIXXH0R3HleSQW4CTOqpHIYUW3t6tpUj4BVQ+w==",
- "dev": true,
- "dependencies": {
- "@types/node": "*"
- }
- },
"node_modules/@types/express-serve-static-core": {
- "version": "4.17.35",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz",
- "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==",
+ "version": "4.19.6",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
+ "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*",
"@types/qs": "*",
@@ -5310,10 +5529,11 @@
}
},
"node_modules/@types/express-session": {
- "version": "1.17.7",
- "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.7.tgz",
- "integrity": "sha512-L25080PBYoRLu472HY/HNCxaXY8AaGgqGC8/p/8+BYMhG0RDOLQ1wpXOpAzr4Gi5TGozTKyJv5BVODM5UNyVMw==",
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.18.2.tgz",
+ "integrity": "sha512-k+I0BxwVXsnEU2hV77cCobC08kIsn4y44C3gC0b46uxZVMaXA04lSPgRLR/bSL2w0t0ShJiG8o4jPzRG/nscFg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/express": "*"
}
@@ -5323,24 +5543,27 @@
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/graceful-fs": {
- "version": "4.1.6",
- "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz",
- "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==",
+ "version": "4.1.9",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
+ "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/hpp": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/@types/hpp/-/hpp-0.2.2.tgz",
- "integrity": "sha512-BLgsawqFFbS3tFUr+mcBRfst+DumnSfi4PgyNeJAGk0eIxm7lKX1axmHVlbgKNAZS0caZA5/LSopuj0T2LKRPw==",
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/@types/hpp/-/hpp-0.2.6.tgz",
+ "integrity": "sha512-6gn1RuHA1/XFCVCqCkSV+AWy07YwtGg4re4SHhLMoiARTg9XlrbYMtVR+Uvws0VlERXzzcA+1UYvxEV6O+sgPg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/express": "*"
}
@@ -5349,28 +5572,32 @@
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.8.2.tgz",
"integrity": "sha512-EqX+YQxINb+MeXaIqYDASb6U6FCHbWjkj4a1CKDBks3d/QiB2+PqBLyO72vLDgAO1wUI4O+9gweRcQK11bTL/w==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/istanbul-lib-coverage": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
- "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
- "dev": true
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/istanbul-lib-report": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
- "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
+ "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/istanbul-lib-coverage": "*"
}
},
"node_modules/@types/istanbul-reports": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
- "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+ "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/istanbul-lib-report": "*"
}
@@ -5380,69 +5607,90 @@
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-28.1.8.tgz",
"integrity": "sha512-8TJkV++s7B6XqnDrzR1m/TT0A0h948Pnl/097veySPN67VRAgQ4gZ7n2KfJo2rVq6njQjdxU3GCCyDvAeuHoiw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"expect": "^28.0.0",
"pretty-format": "^28.0.0"
}
},
"node_modules/@types/json-schema": {
- "version": "7.0.12",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz",
- "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==",
- "dev": true
+ "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/jsonwebtoken": {
- "version": "9.0.2",
- "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
- "integrity": "sha512-drE6uz7QBKq1fYqqoFKTDRdFCPHd5TCub75BM+D+cMx7NU9hUz7SESLfC2fSCXVFMO5Yj8sOWHuGqPgjc+fz0Q==",
+ "version": "9.0.10",
+ "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz",
+ "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
+ "@types/ms": "*",
"@types/node": "*"
}
},
"node_modules/@types/lodash": {
- "version": "4.14.196",
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.196.tgz",
- "integrity": "sha512-22y3o88f4a94mKljsZcanlNWPzO0uBsBdzLAngf2tp533LzZcQzb6+eZPJ+vCTt+bqF2XnvT9gejTLsAcJAJyQ==",
- "dev": true
+ "version": "4.17.19",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.19.tgz",
+ "integrity": "sha512-NYqRyg/hIQrYPT9lbOeYc3kIRabJDn/k4qQHIXUpx88CBDww2fD15Sg5kbXlW86zm2XEW4g0QxkTI3/Kfkc7xQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/luxon": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.1.tgz",
- "integrity": "sha512-XOS5nBcgEeP2PpcqJHjCWhUCAzGfXIU8ILOSLpx2FhxqMW9KdxgCGXNOEKGVBfveKtIpztHzKK5vSRVLyW/NqA==",
- "dev": true
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.6.2.tgz",
+ "integrity": "sha512-R/BdP7OxEMc44l2Ex5lSXHoIXTB2JLNa3y2QISIbr58U/YcsffyQrYW//hZSdrfxrjRZj3GcUoxMPGdO8gSYuw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/mime": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
- "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
- "dev": true
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
+ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/mime-types": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.1.tgz",
- "integrity": "sha512-vXOTGVSLR2jMw440moWTC7H19iUyLtP3Z1YTj7cSsubOICinjMxFeb/V57v9QdyyPGbbWolUFSSmSiRSn94tFw==",
- "dev": true
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.4.tgz",
+ "integrity": "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/morgan": {
- "version": "1.9.4",
- "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.4.tgz",
- "integrity": "sha512-cXoc4k+6+YAllH3ZHmx4hf7La1dzUk6keTR4bF4b4Sc0mZxU/zK4wO7l+ZzezXm/jkYj/qC+uYGZrarZdIVvyQ==",
+ "version": "1.9.10",
+ "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.10.tgz",
+ "integrity": "sha512-sS4A1zheMvsADRVfT0lYbJ4S9lmsey8Zo2F7cnbYjWHP67Q0AwMYuuzLlkIM2N8gAbb9cubhIVFwcIN2XyYCkA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/node": {
- "version": "18.17.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.1.tgz",
- "integrity": "sha512-xlR1jahfizdplZYRU59JlUx9uzF1ARa8jbhM11ccpCJya8kvos5jwdm2ZAgxSCwOl0fq21svP18EVwPBXMQudw=="
+ "version": "18.19.113",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.113.tgz",
+ "integrity": "sha512-TmSTE9vyebJ9vSEiU+P+0Sp4F5tMgjiEOZaQUW6wA3ODvi6uBgkHQ+EsIu0pbiKvf9QHEvyRCiaz03rV0b+IaA==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
},
"node_modules/@types/oauth": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.1.tgz",
- "integrity": "sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A==",
+ "version": "0.9.6",
+ "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.6.tgz",
+ "integrity": "sha512-H9TRCVKBNOhZZmyHLqFt9drPM9l+ShWiqqJijU1B8P3DX3ub84NjxDuy+Hjrz+fEca5Kwip3qPMKNyiLgNJtIA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*"
}
@@ -5482,10 +5730,11 @@
}
},
"node_modules/@types/passport-oauth2": {
- "version": "1.4.12",
- "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.12.tgz",
- "integrity": "sha512-RZg6cYTyEGinrZn/7REYQds6zrTxoBorX1/fdaz5UHzkG8xdFE7QQxkJagCr2ETzGII58FAFDmnmbTUVMrltNA==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.8.0.tgz",
+ "integrity": "sha512-6//z+4orIOy/g3zx17HyQ71GSRK4bs7Sb+zFasRoc2xzlv7ZCJ+vkDBYFci8U6HY+or6Zy7ajf4mz4rK7nsWJQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/express": "*",
"@types/oauth": "*",
@@ -5493,84 +5742,103 @@
}
},
"node_modules/@types/passport-strategy": {
- "version": "0.2.35",
- "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.35.tgz",
- "integrity": "sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==",
+ "version": "0.2.38",
+ "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz",
+ "integrity": "sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/express": "*",
"@types/passport": "*"
}
},
"node_modules/@types/pg": {
- "version": "8.11.11",
- "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.11.tgz",
- "integrity": "sha512-kGT1qKM8wJQ5qlawUrEkXgvMSXoV213KfMGXcwfDwUIfUHXqXYXOfS1nE1LINRJVVVx5wCm70XnFlMHaIcQAfw==",
+ "version": "8.15.4",
+ "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.4.tgz",
+ "integrity": "sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg==",
"license": "MIT",
"dependencies": {
"@types/node": "*",
"pg-protocol": "*",
- "pg-types": "^4.0.1"
+ "pg-types": "^2.2.0"
}
},
"node_modules/@types/prettier": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz",
"integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/pug": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.6.tgz",
- "integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==",
- "dev": true
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz",
+ "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/qs": {
- "version": "6.9.7",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
- "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
- "dev": true
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/range-parser": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
- "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
- "dev": true
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
+ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/redis": {
+ "version": "2.8.32",
+ "resolved": "https://registry.npmjs.org/@types/redis/-/redis-2.8.32.tgz",
+ "integrity": "sha512-7jkMKxcGq9p242exlbsVzuJb57KqHRhNl4dHoQu2Y5v9bCAbtIXXH0R3HleSQW4CTOqpHIYUW3t6tpUj4BVQ+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
},
"node_modules/@types/sanitize-html": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-2.9.0.tgz",
- "integrity": "sha512-4fP/kEcKNj2u39IzrxWYuf/FnCCwwQCpif6wwY6ROUS1EPRIfWJjGkY3HIowY1EX/VbX5e86yq8AAE7UPMgATg==",
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-2.16.0.tgz",
+ "integrity": "sha512-l6rX1MUXje5ztPT0cAFtUayXF06DqPhRyfVXareEN5gGCFaP/iwsxIyKODr9XDhfxPpN6vXUFNfo5kZMXCxBtw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"htmlparser2": "^8.0.0"
}
},
"node_modules/@types/semver": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz",
- "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==",
- "dev": true
+ "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/send": {
- "version": "0.17.1",
- "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz",
- "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==",
+ "version": "0.17.5",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz",
+ "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/mime": "^1",
"@types/node": "*"
}
},
"node_modules/@types/serve-static": {
- "version": "1.15.2",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz",
- "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==",
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz",
+ "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/http-errors": "*",
- "@types/mime": "*",
- "@types/node": "*"
+ "@types/node": "*",
+ "@types/send": "*"
}
},
"node_modules/@types/sharp": {
@@ -5578,68 +5846,84 @@
"resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.31.1.tgz",
"integrity": "sha512-5nWwamN9ZFHXaYEincMSuza8nNfOof8nmO+mcI+Agx1uMUk4/pQnNIcix+9rLPXzKrm1pS34+6WRDbDV0Jn7ag==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/stack-utils": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
- "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
- "dev": true
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
+ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/swagger-jsdoc": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/@types/swagger-jsdoc/-/swagger-jsdoc-6.0.1.tgz",
- "integrity": "sha512-+MUpcbyxD528dECUBCEVm6abNuORdbuGjbrUdHDeAQ+rkPuo2a+L4N02WJHF3bonSSE6SJ3dUJwF2V6+cHnf0w==",
- "dev": true
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/@types/swagger-jsdoc/-/swagger-jsdoc-6.0.4.tgz",
+ "integrity": "sha512-W+Xw5epcOZrF/AooUM/PccNMSAFOKWZA5dasNyMujTwsBkU74njSJBpvCCJhHAJ95XRMzQrrW844Btu0uoetwQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/toobusy-js": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/@types/toobusy-js/-/toobusy-js-0.5.2.tgz",
- "integrity": "sha512-jK/CMvC5h/ECMhWRNjeFYIZzGFFvjt38+zbMndFKyDUHl1dm89SX7u8njoNHQKrW+OZoqxteBLvtSBFQOdGyHA==",
- "dev": true
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/@types/toobusy-js/-/toobusy-js-0.5.4.tgz",
+ "integrity": "sha512-hsKMbYiaL3ZWx7B3FYyN0rEJexw7I1HgKbNToX3ZZJv6373to954wlA7zrXR3/XoVwZnFwWqFguBs91sNzJGKQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/triple-beam": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.2.tgz",
- "integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g=="
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz",
+ "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==",
+ "license": "MIT"
},
"node_modules/@types/uglify-js": {
- "version": "3.17.1",
- "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.17.1.tgz",
- "integrity": "sha512-GkewRA4i5oXacU/n4MA9+bLgt5/L3F1mKrYvFGm7r2ouLXhRKjuWwo9XHNnbx6WF3vlGW21S3fCvgqxvxXXc5g==",
+ "version": "3.17.5",
+ "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.17.5.tgz",
+ "integrity": "sha512-TU+fZFBTBcXj/GpDpDaBmgWk/gn96kMZ+uocaFUlV2f8a6WdMzzI44QBCmGcCiYR0Y6ZlNRiyUyKKt5nl/lbzQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"source-map": "^0.6.1"
}
},
+ "node_modules/@types/uuid": {
+ "version": "9.0.8",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
+ "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
+ "license": "MIT"
+ },
"node_modules/@types/xss-filters": {
"version": "0.0.27",
"resolved": "https://registry.npmjs.org/@types/xss-filters/-/xss-filters-0.0.27.tgz",
"integrity": "sha512-ctN3f7vl4tBXa+W11hm0oDwp67K6SYK07h4OmNgaEoIOVJ/rksnc2prpbjK+Ju3/fYIa3HQaH4x9Y525CXFOow==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/yargs": {
- "version": "17.0.24",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz",
- "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==",
+ "version": "17.0.33",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
+ "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/yargs-parser": "*"
}
},
"node_modules/@types/yargs-parser": {
- "version": "21.0.0",
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
- "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
- "dev": true
+ "version": "21.0.3",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
+ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
+ "dev": true,
+ "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",
@@ -5669,26 +5953,12 @@
}
}
},
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -5696,17 +5966,12 @@
"node": ">=10"
}
},
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"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",
@@ -5734,6 +5999,7 @@
"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"
@@ -5751,6 +6017,7 @@
"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",
@@ -5778,6 +6045,7 @@
"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"
},
@@ -5791,6 +6059,7 @@
"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",
@@ -5813,26 +6082,12 @@
}
}
},
- "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -5840,17 +6095,12 @@
"node": ">=10"
}
},
- "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"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",
@@ -5872,26 +6122,12 @@
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
- "node_modules/@typescript-eslint/utils/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@typescript-eslint/utils/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -5899,17 +6135,12 @@
"node": ">=10"
}
},
- "node_modules/@typescript-eslint/utils/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"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"
@@ -5922,15 +6153,38 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/@typespec/ts-http-runtime": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.2.3.tgz",
+ "integrity": "sha512-oRhjSzcVjX8ExyaF8hC0zzTqxlVuRlgMHL/Bh4w3xB9+wjbm0FpXylVU/lBrn+kgphwYTrOk3tp+AVShGmlYCg==",
+ "license": "MIT",
+ "dependencies": {
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "license": "ISC"
},
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "license": "MIT",
"dependencies": {
"mime-types": "~2.1.34",
"negotiator": "0.6.3"
@@ -5939,11 +6193,21 @@
"node": ">= 0.6"
}
},
+ "node_modules/accepts/node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/acorn": {
- "version": "8.10.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
- "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
+ "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"
},
@@ -5956,37 +6220,31 @@
"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.2.0",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
- "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+ "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/adm-zip": {
- "version": "0.5.10",
- "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz",
- "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==",
- "dev": true,
- "engines": {
- "node": ">=6.0"
- }
- },
"node_modules/agent-base": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
- "dependencies": {
- "debug": "4"
- },
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
+ "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
+ "license": "MIT",
"engines": {
- "node": ">= 6.0.0"
+ "node": ">= 14"
}
},
"node_modules/ajv": {
@@ -5994,6 +6252,7 @@
"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",
@@ -6010,6 +6269,7 @@
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
"integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"type-fest": "^0.21.3"
},
@@ -6024,20 +6284,25 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "color-convert": "^1.9.0"
+ "color-convert": "^2.0.1"
},
"engines": {
- "node": ">=4"
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/anymatch": {
@@ -6045,6 +6310,7 @@
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
@@ -6056,18 +6322,20 @@
"node_modules/aproba": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
- "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
+ "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
+ "license": "ISC"
},
"node_modules/archiver": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz",
- "integrity": "sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz",
+ "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==",
+ "license": "MIT",
"dependencies": {
"archiver-utils": "^2.1.0",
- "async": "^3.2.3",
+ "async": "^3.2.4",
"buffer-crc32": "^0.2.1",
"readable-stream": "^3.6.0",
- "readdir-glob": "^1.0.0",
+ "readdir-glob": "^1.1.2",
"tar-stream": "^2.2.0",
"zip-stream": "^4.1.0"
},
@@ -6079,6 +6347,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz",
"integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==",
+ "license": "MIT",
"dependencies": {
"glob": "^7.1.4",
"graceful-fs": "^4.2.0",
@@ -6095,10 +6364,44 @@
"node": ">= 6"
}
},
+ "node_modules/archiver-utils/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/archiver-utils/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/archiver-utils/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
@@ -6109,10 +6412,17 @@
"util-deprecate": "~1.0.1"
}
},
+ "node_modules/archiver-utils/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
"node_modules/archiver-utils/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
@@ -6121,6 +6431,8 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
+ "deprecated": "This package is no longer supported.",
+ "license": "ISC",
"dependencies": {
"delegates": "^1.0.0",
"readable-stream": "^3.6.0"
@@ -6133,19 +6445,21 @@
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
+ "dev": true,
+ "license": "Python-2.0"
},
"node_modules/array-each": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
"integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -6153,13 +6467,14 @@
"node_modules/array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+ "license": "MIT"
},
"node_modules/array-slice": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
"integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -6169,6 +6484,7 @@
"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"
}
@@ -6176,7 +6492,8 @@
"node_modules/asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
- "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
+ "license": "MIT"
},
"node_modules/assert-never": {
"version": "1.4.0",
@@ -6185,19 +6502,21 @@
"license": "MIT"
},
"node_modules/async": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
- "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+ "license": "MIT"
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
},
"node_modules/axios": {
- "version": "1.7.9",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
- "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz",
+ "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
@@ -6206,15 +6525,17 @@
}
},
"node_modules/b4a": {
- "version": "1.6.4",
- "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz",
- "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw=="
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz",
+ "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==",
+ "license": "Apache-2.0"
},
"node_modules/babel-jest": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz",
"integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/transform": "^28.1.3",
"@types/babel__core": "^7.1.14",
@@ -6231,81 +6552,12 @@
"@babel/core": "^7.8.0"
}
},
- "node_modules/babel-jest/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/babel-jest/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/babel-jest/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/babel-jest/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/babel-jest/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/babel-jest/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/babel-plugin-istanbul": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
"integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"@babel/helper-plugin-utils": "^7.0.0",
"@istanbuljs/load-nyc-config": "^1.0.0",
@@ -6322,6 +6574,7 @@
"resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz",
"integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/template": "^7.3.3",
"@babel/types": "^7.3.3",
@@ -6333,13 +6586,14 @@
}
},
"node_modules/babel-plugin-polyfill-corejs2": {
- "version": "0.4.5",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz",
- "integrity": "sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==",
+ "version": "0.4.14",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz",
+ "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.22.6",
- "@babel/helper-define-polyfill-provider": "^0.4.2",
+ "@babel/compat-data": "^7.27.7",
+ "@babel/helper-define-polyfill-provider": "^0.6.5",
"semver": "^6.3.1"
},
"peerDependencies": {
@@ -6347,48 +6601,54 @@
}
},
"node_modules/babel-plugin-polyfill-corejs3": {
- "version": "0.8.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz",
- "integrity": "sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==",
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz",
+ "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.4.2",
- "core-js-compat": "^3.31.0"
+ "@babel/helper-define-polyfill-provider": "^0.6.3",
+ "core-js-compat": "^3.40.0"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
"node_modules/babel-plugin-polyfill-regenerator": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz",
- "integrity": "sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==",
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz",
+ "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.4.2"
+ "@babel/helper-define-polyfill-provider": "^0.6.5"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
"node_modules/babel-preset-current-node-syntax": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
- "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz",
+ "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/plugin-syntax-async-generators": "^7.8.4",
"@babel/plugin-syntax-bigint": "^7.8.3",
- "@babel/plugin-syntax-class-properties": "^7.8.3",
- "@babel/plugin-syntax-import-meta": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-import-attributes": "^7.24.7",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
"@babel/plugin-syntax-json-strings": "^7.8.3",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-numeric-separator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
"@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-top-level-await": "^7.8.3"
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5"
},
"peerDependencies": {
"@babel/core": "^7.0.0"
@@ -6399,6 +6659,7 @@
"resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz",
"integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"babel-plugin-jest-hoist": "^28.1.3",
"babel-preset-current-node-syntax": "^1.0.0"
@@ -6425,7 +6686,80 @@
"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=="
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "license": "MIT"
+ },
+ "node_modules/bare-events": {
+ "version": "2.5.4",
+ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz",
+ "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==",
+ "license": "Apache-2.0",
+ "optional": true
+ },
+ "node_modules/bare-fs": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.5.tgz",
+ "integrity": "sha512-1zccWBMypln0jEE05LzZt+V/8y8AQsQQqxtklqaIyg5nu6OAYFhZxPXinJTSG+kU5qyNmeLgcn9AW7eHiCHVLA==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "bare-events": "^2.5.4",
+ "bare-path": "^3.0.0",
+ "bare-stream": "^2.6.4"
+ },
+ "engines": {
+ "bare": ">=1.16.0"
+ },
+ "peerDependencies": {
+ "bare-buffer": "*"
+ },
+ "peerDependenciesMeta": {
+ "bare-buffer": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/bare-os": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz",
+ "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "engines": {
+ "bare": ">=1.14.0"
+ }
+ },
+ "node_modules/bare-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz",
+ "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "bare-os": "^3.0.1"
+ }
+ },
+ "node_modules/bare-stream": {
+ "version": "2.6.5",
+ "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz",
+ "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "streamx": "^2.21.0"
+ },
+ "peerDependencies": {
+ "bare-buffer": "*",
+ "bare-events": "*"
+ },
+ "peerDependenciesMeta": {
+ "bare-buffer": {
+ "optional": true
+ },
+ "bare-events": {
+ "optional": true
+ }
+ }
},
"node_modules/base64-js": {
"version": "1.5.1",
@@ -6444,7 +6778,8 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ]
+ ],
+ "license": "MIT"
},
"node_modules/base64id": {
"version": "2.0.0",
@@ -6459,6 +6794,7 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
"integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==",
+ "license": "MIT",
"engines": {
"node": ">=6.0.0"
}
@@ -6467,6 +6803,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
+ "license": "MIT",
"dependencies": {
"safe-buffer": "5.1.2"
},
@@ -6474,13 +6811,20 @@
"node": ">= 0.8"
}
},
+ "node_modules/basic-auth/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
"node_modules/bcrypt": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.0.tgz",
- "integrity": "sha512-RHBS7HI5N5tEnGTmtR/pppX0mmDSBpQ4aCBsj7CEQfYXDcO74A8sIBYcJMuCsis2E81zDxeENYhv66oZwLiA+Q==",
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz",
+ "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==",
"hasInstallScript": true,
+ "license": "MIT",
"dependencies": {
- "@mapbox/node-pre-gyp": "^1.0.10",
+ "@mapbox/node-pre-gyp": "^1.0.11",
"node-addon-api": "^5.0.0"
},
"engines": {
@@ -6488,9 +6832,10 @@
}
},
"node_modules/big-integer": {
- "version": "1.6.51",
- "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
- "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
+ "version": "1.6.52",
+ "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
+ "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==",
+ "license": "Unlicense",
"engines": {
"node": ">=0.6"
}
@@ -6499,6 +6844,7 @@
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
"integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==",
+ "license": "MIT",
"dependencies": {
"buffers": "~0.1.1",
"chainsaw": "~0.1.0"
@@ -6508,18 +6854,23 @@
}
},
"node_modules/binary-extensions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "license": "MIT",
"dependencies": {
"file-uri-to-path": "1.0.0"
}
@@ -6528,6 +6879,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "license": "MIT",
"dependencies": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
@@ -6537,19 +6889,8 @@
"node_modules/bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
- "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
- },
- "node_modules/body": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz",
- "integrity": "sha512-chUsBxGRtuElD6fmw1gHLpvnKdVLK302peeFa9ZqAEk8TyzZ3fygLyUEDDPTJvL9+Bor0dIwn6ePOsRM2y0zQQ==",
- "dev": true,
- "dependencies": {
- "continuable-cache": "^0.3.1",
- "error": "^7.0.0",
- "raw-body": "~1.1.0",
- "safe-json-parse": "~1.0.1"
- }
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "license": "MIT"
},
"node_modules/body-parser": {
"version": "1.20.3",
@@ -6575,15 +6916,6 @@
"npm": "1.2.8000 || >= 1.4.16"
}
},
- "node_modules/body-parser/node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/body-parser/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -6599,40 +6931,17 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
},
- "node_modules/body/node_modules/bytes": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz",
- "integrity": "sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ==",
- "dev": true
- },
- "node_modules/body/node_modules/raw-body": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz",
- "integrity": "sha512-WmJJU2e9Y6M5UzTOkHaM7xJGAPQD8PNzx3bAd2+uhZAim6wDk6dAZxPVYLF67XhbR4hmKGh33Lpmh4XWrCH5Mg==",
- "dev": true,
- "dependencies": {
- "bytes": "1",
- "string_decoder": "0.10"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/body/node_modules/string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
- "dev": true
- },
"node_modules/bowser": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
- "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA=="
+ "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==",
+ "license": "MIT"
},
"node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -6642,7 +6951,6 @@
"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"
@@ -6652,9 +6960,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.21.9",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz",
- "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==",
+ "version": "4.25.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz",
+ "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==",
"dev": true,
"funding": [
{
@@ -6670,11 +6978,12 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "caniuse-lite": "^1.0.30001503",
- "electron-to-chromium": "^1.4.431",
- "node-releases": "^2.0.12",
- "update-browserslist-db": "^1.0.11"
+ "caniuse-lite": "^1.0.30001726",
+ "electron-to-chromium": "^1.5.173",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.3"
},
"bin": {
"browserslist": "cli.js"
@@ -6688,6 +6997,7 @@
"resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
"integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"fast-json-stable-stringify": "2.x"
},
@@ -6700,6 +7010,7 @@
"resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
"integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"node-int64": "^0.4.0"
}
@@ -6722,6 +7033,7 @@
"url": "https://feross.org/support"
}
],
+ "license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
@@ -6731,6 +7043,7 @@
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+ "license": "MIT",
"engines": {
"node": "*"
}
@@ -6738,18 +7051,21 @@
"node_modules/buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
- "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
+ "license": "BSD-3-Clause"
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/buffer-indexof-polyfill": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz",
"integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==",
+ "license": "MIT",
"engines": {
"node": ">=0.10"
}
@@ -6767,34 +7083,24 @@
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
"integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/bytes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
- "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
- "node_modules/call-bind": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
- "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
- "dependencies": {
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/call-bind-apply-helpers": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
- "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
+ "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",
@@ -6805,13 +7111,13 @@
}
},
"node_modules/call-bound": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
- "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"license": "MIT",
"dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "get-intrinsic": "^1.2.6"
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
@@ -6824,13 +7130,15 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
"integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"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"
}
@@ -6840,14 +7148,15 @@
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001517",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz",
- "integrity": "sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==",
+ "version": "1.0.30001726",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz",
+ "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==",
"dev": true,
"funding": [
{
@@ -6862,12 +7171,14 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
- ]
+ ],
+ "license": "CC-BY-4.0"
},
"node_modules/chainsaw": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
"integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==",
+ "license": "MIT/X11",
"dependencies": {
"traverse": ">=0.3.0 <0.4"
},
@@ -6876,17 +7187,33 @@
}
},
"node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chalk/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
"node_modules/char-regex": {
@@ -6894,6 +7221,7 @@
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
}
@@ -6902,6 +7230,7 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
"integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==",
+ "license": "MIT",
"dependencies": {
"is-regex": "^1.0.3"
}
@@ -6910,22 +7239,18 @@
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/chartjs-to-image/-/chartjs-to-image-1.2.2.tgz",
"integrity": "sha512-qnYedDlNSPsrISQyRhJk4gWciKMtK8mlx2VWbFMJIPLVokSHJBEUuoxE6LLDFGnOhdvLd3K5E6lmGap7/phWFQ==",
+ "license": "MIT",
"dependencies": {
"axios": "^1.6.0",
"javascript-stringify": "^2.1.0"
}
},
"node_modules/chokidar": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
- "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://paulmillr.com/funding/"
- }
- ],
+ "license": "MIT",
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
@@ -6938,6 +7263,9 @@
"engines": {
"node": ">= 8.10.0"
},
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
"optionalDependencies": {
"fsevents": "~2.3.2"
}
@@ -6946,14 +7274,15 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "license": "ISC",
"engines": {
"node": ">=10"
}
},
"node_modules/ci-info": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz",
- "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==",
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
+ "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
"dev": true,
"funding": [
{
@@ -6961,21 +7290,24 @@
"url": "https://github.com/sponsors/sibiraj-s"
}
],
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/cjs-module-lexer": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz",
- "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==",
- "dev": true
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz",
+ "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.1",
@@ -6985,10 +7317,51 @@
"node": ">=12"
}
},
+ "node_modules/cliui/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
"node_modules/cluster-key-slot": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
"integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
+ "license": "Apache-2.0",
"engines": {
"node": ">=0.10.0"
}
@@ -6998,6 +7371,7 @@
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"iojs": ">= 1.0.0",
"node": ">= 0.12.0"
@@ -7007,12 +7381,14 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
"integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/color": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
+ "license": "MIT",
"dependencies": {
"color-convert": "^2.0.1",
"color-string": "^1.9.0"
@@ -7022,22 +7398,28 @@
}
},
"node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "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.3"
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
}
},
"node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+ "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/color-string": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+ "license": "MIT",
"dependencies": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
@@ -7047,31 +7429,17 @@
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "license": "ISC",
"bin": {
"color-support": "bin.js"
}
},
- "node_modules/color/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==",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/color/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=="
- },
"node_modules/colors": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
- "integrity": "sha512-ENwblkFQpqqia6b++zLD/KUWafYlVY/UNnAp7oz7LY7E924wmpye416wBOmvv/HMWzl8gL1kJlfvId/1Dg176w==",
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+ "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.1.90"
}
@@ -7080,6 +7448,7 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
"integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
+ "license": "MIT",
"dependencies": {
"color": "^3.1.3",
"text-hex": "1.0.x"
@@ -7089,15 +7458,32 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
"integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
+ "license": "MIT",
"dependencies": {
"color-convert": "^1.9.3",
"color-string": "^1.6.0"
}
},
+ "node_modules/colorspace/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/colorspace/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "license": "MIT"
+ },
"node_modules/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"
},
@@ -7110,14 +7496,16 @@
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz",
"integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 6"
}
},
"node_modules/compress-commons": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz",
- "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz",
+ "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==",
+ "license": "MIT",
"dependencies": {
"buffer-crc32": "^0.2.13",
"crc32-stream": "^4.0.2",
@@ -7132,6 +7520,7 @@
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
"integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+ "license": "MIT",
"dependencies": {
"mime-db": ">= 1.43.0 < 2"
},
@@ -7140,16 +7529,17 @@
}
},
"node_modules/compression": {
- "version": "1.7.4",
- "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
- "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz",
+ "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==",
+ "license": "MIT",
"dependencies": {
- "accepts": "~1.3.5",
- "bytes": "3.0.0",
- "compressible": "~2.0.16",
+ "bytes": "3.1.2",
+ "compressible": "~2.0.18",
"debug": "2.6.9",
+ "negotiator": "~0.6.4",
"on-headers": "~1.0.2",
- "safe-buffer": "5.1.2",
+ "safe-buffer": "5.2.1",
"vary": "~1.1.2"
},
"engines": {
@@ -7160,6 +7550,7 @@
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
@@ -7167,12 +7558,40 @@
"node_modules/compression/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "license": "MIT"
+ },
+ "node_modules/concurrently": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.0.tgz",
+ "integrity": "sha512-IsB/fiXTupmagMW4MNp2lx2cdSN2FfZq78vF90LBB+zZHArbIQZjQtzXCiXnvTxCZSvXanTqFLWBjw2UkLx1SQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.2",
+ "lodash": "^4.17.21",
+ "rxjs": "^7.8.1",
+ "shell-quote": "^1.8.1",
+ "supports-color": "^8.1.1",
+ "tree-kill": "^1.2.2",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "conc": "dist/bin/concurrently.js",
+ "concurrently": "dist/bin/concurrently.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/open-cli-tools/concurrently?sponsor=1"
+ }
},
"node_modules/connect-flash": {
"version": "0.1.1",
@@ -7186,6 +7605,7 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/connect-pg-simple/-/connect-pg-simple-7.0.0.tgz",
"integrity": "sha512-fbNZUkxz8m+FRbctoxAU18DzRKp8GQSL+9gTJ0+LgSCElXLon2q8tDE8V74jUzf+w2ARZX8HKKyV0laX1NUZ/Q==",
+ "license": "MIT",
"dependencies": {
"@types/pg": "^8.6.1",
"pg": "^8.7.1"
@@ -7197,12 +7617,14 @@
"node_modules/console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
- "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
+ "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
+ "license": "ISC"
},
"node_modules/constantinople": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz",
"integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==",
+ "license": "MIT",
"dependencies": {
"@babel/parser": "^7.6.0",
"@babel/types": "^7.6.1"
@@ -7212,6 +7634,7 @@
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "license": "MIT",
"dependencies": {
"safe-buffer": "5.2.1"
},
@@ -7219,25 +7642,6 @@
"node": ">= 0.6"
}
},
- "node_modules/content-disposition/node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
"node_modules/content-type": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
@@ -7247,17 +7651,12 @@
"node": ">= 0.6"
}
},
- "node_modules/continuable-cache": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz",
- "integrity": "sha512-TF30kpKhTH8AGCG3dut0rdd/19B7Z+qCnrMoBLpyQu/2drZdNrrpcjPEoJeSVsQM+8KmWG5O56oPDjSSUsuTyA==",
- "dev": true
- },
"node_modules/convert-source-map": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
- "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
- "dev": true
+ "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": "0.7.2",
@@ -7284,15 +7683,17 @@
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+ "license": "MIT"
},
"node_modules/core-js-compat": {
- "version": "3.31.1",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.31.1.tgz",
- "integrity": "sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA==",
+ "version": "3.43.0",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.43.0.tgz",
+ "integrity": "sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "browserslist": "^4.21.9"
+ "browserslist": "^4.25.0"
},
"funding": {
"type": "opencollective",
@@ -7302,12 +7703,14 @@
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
- "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "license": "MIT"
},
"node_modules/cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "license": "MIT",
"dependencies": {
"object-assign": "^4",
"vary": "^1"
@@ -7316,10 +7719,65 @@
"node": ">= 0.10"
}
},
+ "node_modules/cpx2": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/cpx2/-/cpx2-8.0.0.tgz",
+ "integrity": "sha512-RxD9jrSVNSOmfcbiPlr3XnKbUKH9K1w2HCv0skczUKhsZTueiDBecxuaSAKQkYSLQaGVA4ZQJZlTj5hVNNEvKg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debounce": "^2.0.0",
+ "debug": "^4.1.1",
+ "duplexer": "^0.1.1",
+ "fs-extra": "^11.1.0",
+ "glob": "^11.0.0",
+ "glob2base": "0.0.12",
+ "ignore": "^6.0.2",
+ "minimatch": "^10.0.1",
+ "p-map": "^7.0.0",
+ "resolve": "^1.12.0",
+ "safe-buffer": "^5.2.0",
+ "shell-quote": "^1.8.0",
+ "subarg": "^1.0.0"
+ },
+ "bin": {
+ "cpx": "bin/index.js"
+ },
+ "engines": {
+ "node": "^20.0.0 || >=22.0.0",
+ "npm": ">=10"
+ }
+ },
+ "node_modules/cpx2/node_modules/fs-extra": {
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+ "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/cpx2/node_modules/ignore": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz",
+ "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
"node_modules/crc-32": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
+ "license": "Apache-2.0",
"bin": {
"crc32": "bin/crc32.njs"
},
@@ -7328,9 +7786,10 @@
}
},
"node_modules/crc32-stream": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz",
- "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz",
+ "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==",
+ "license": "MIT",
"dependencies": {
"crc-32": "^1.2.0",
"readable-stream": "^3.4.0"
@@ -7343,16 +7802,25 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/cron": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/cron/-/cron-2.4.0.tgz",
- "integrity": "sha512-Cx77ic1TyIAtUggr0oAhtS8MLzPBUqGNIvdDM7jE3oFIxfe8LXWI9q3iQN/H2CebAiMir53LQKWOhEKnzkJTAQ==",
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/cron/-/cron-2.4.4.tgz",
+ "integrity": "sha512-MHlPImXJj3K7x7lyUHjtKEOl69CSlTOWxS89jiFgNkzXfvhVjhMz/nc7/EIfN9vgooZp8XTtXJ1FREdmbyXOiQ==",
+ "license": "MIT",
"dependencies": {
- "luxon": "^3.2.1"
+ "@types/luxon": "~3.3.0",
+ "luxon": "~3.3.0"
}
},
+ "node_modules/cron/node_modules/@types/luxon": {
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.3.8.tgz",
+ "integrity": "sha512-jYvz8UMLDgy3a5SkGJne8H7VA7zPV2Lwohjx0V8V31+SqAjNmurWMkk9cQhfvlcnXWudBpK9xPM1n4rljOcHYQ==",
+ "license": "MIT"
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -7378,6 +7846,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/csrf/-/csrf-3.1.0.tgz",
"integrity": "sha512-uTqEnCvWRk042asU6JtapDTcJeeailFy4ydOQS28bj1hcLnYRiqi8SsD2jS412AY1I/4qdOwWZun774iqywf9w==",
+ "license": "MIT",
"dependencies": {
"rndm": "1.2.0",
"tsscmp": "1.0.6",
@@ -7387,11 +7856,21 @@
"node": ">= 0.8"
}
},
+ "node_modules/csrf-sync": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/csrf-sync/-/csrf-sync-4.2.1.tgz",
+ "integrity": "sha512-+q9tlUSCi/kbwr1NYwn5+MeuNhwxz3wSv1yl42BgIWfIuErZ3HajRwzvZTkfiyIqt1PZT8lQSlffhSYjCneN7g==",
+ "license": "ISC",
+ "dependencies": {
+ "http-errors": "^2.0.0"
+ }
+ },
"node_modules/csurf": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/csurf/-/csurf-1.11.0.tgz",
"integrity": "sha512-UCtehyEExKTxgiu8UHdGvHj4tnpE/Qctue03Giq5gPgMQ9cg/ciod5blZQ5a4uCEenNQjxyGuzygLdKUmee/bQ==",
- "deprecated": "Please use another csrf package",
+ "deprecated": "This package is archived and no longer maintained. For support, visit https://github.com/expressjs/express/discussions",
+ "license": "MIT",
"dependencies": {
"cookie": "0.4.0",
"cookie-signature": "1.0.6",
@@ -7406,6 +7885,7 @@
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -7414,6 +7894,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -7422,6 +7903,7 @@
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
"integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
+ "license": "MIT",
"dependencies": {
"depd": "~1.1.2",
"inherits": "2.0.4",
@@ -7436,12 +7918,14 @@
"node_modules/csurf/node_modules/setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
- "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
+ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+ "license": "ISC"
},
"node_modules/csurf/node_modules/statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -7450,30 +7934,37 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+ "license": "MIT",
"engines": {
"node": ">=0.6"
}
},
- "node_modules/dateformat": {
- "version": "4.6.3",
- "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz",
- "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==",
+ "node_modules/dayjs": {
+ "version": "1.11.13",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
+ "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
+ "license": "MIT"
+ },
+ "node_modules/debounce": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debounce/-/debounce-2.2.0.tgz",
+ "integrity": "sha512-Xks6RUDLZFdz8LIdR6q0MTH44k7FikOmnh5xkSjMig6ch45afc8sjTjRQf3P6ax8dMgcQrYO/AR2RGWURrruqw==",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": "*"
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/dayjs": {
- "version": "1.11.9",
- "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz",
- "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA=="
- },
"node_modules/debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "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.2"
+ "ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
@@ -7488,6 +7979,7 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "license": "MIT",
"dependencies": {
"mimic-response": "^3.1.0"
},
@@ -7502,12 +7994,14 @@
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
"integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "license": "MIT",
"engines": {
"node": ">=4.0.0"
}
@@ -7516,12 +8010,14 @@
"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
+ "dev": true,
+ "license": "MIT"
},
"node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -7530,6 +8026,7 @@
"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"
}
@@ -7537,12 +8034,14 @@
"node_modules/delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
- "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
+ "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
+ "license": "MIT"
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -7561,15 +8060,16 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
"integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/detect-libc": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
- "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
+ "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
+ "license": "Apache-2.0",
"engines": {
"node": ">=8"
}
@@ -7579,6 +8079,7 @@
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
"integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -7588,6 +8089,7 @@
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
}
@@ -7597,6 +8099,7 @@
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz",
"integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
@@ -7606,6 +8109,7 @@
"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"
},
@@ -7618,6 +8122,7 @@
"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"
},
@@ -7635,6 +8140,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "license": "MIT",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
@@ -7653,12 +8159,14 @@
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
- ]
+ ],
+ "license": "BSD-2-Clause"
},
"node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "license": "BSD-2-Clause",
"dependencies": {
"domelementtype": "^2.3.0"
},
@@ -7670,9 +8178,10 @@
}
},
"node_modules/domutils": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
- "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "license": "BSD-2-Clause",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
@@ -7683,14 +8192,15 @@
}
},
"node_modules/dotenv": {
- "version": "16.3.1",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
- "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=12"
},
"funding": {
- "url": "https://github.com/motdotla/dotenv?sponsor=1"
+ "url": "https://dotenvx.com"
}
},
"node_modules/dunder-proto": {
@@ -7711,12 +8221,14 @@
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/duplexer2": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
"integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==",
+ "license": "BSD-3-Clause",
"dependencies": {
"readable-stream": "^2.0.2"
}
@@ -7725,6 +8237,7 @@
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
@@ -7735,18 +8248,33 @@
"util-deprecate": "~1.0.1"
}
},
+ "node_modules/duplexer2/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
"node_modules/duplexer2/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "license": "Apache-2.0",
"dependencies": {
"safe-buffer": "^5.0.1"
}
@@ -7754,19 +8282,22 @@
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "license": "MIT"
},
"node_modules/electron-to-chromium": {
- "version": "1.4.473",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.473.tgz",
- "integrity": "sha512-aVfC8+440vGfl06l8HKKn8/PD5jRfSnLkTTD65EFvU46igbpQRri1gxSzW9/+TeUlwYzrXk1sw867T96zlyECA==",
- "dev": true
+ "version": "1.5.178",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.178.tgz",
+ "integrity": "sha512-wObbz/ar3Bc6e4X5vf0iO8xTN8YAjN/tgiAOJLr7yjYFtP9wAjq8Mb5h0yn6kResir+VYx2DXBj9NNobs0ETSA==",
+ "dev": true,
+ "license": "ISC"
},
"node_modules/emittery": {
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz",
"integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=12"
},
@@ -7775,14 +8306,17 @@
}
},
"node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/enabled": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
- "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
+ "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==",
+ "license": "MIT"
},
"node_modules/encodeurl": {
"version": "2.0.0",
@@ -7794,20 +8328,20 @@
}
},
"node_modules/end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
+ "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
+ "license": "MIT",
"dependencies": {
"once": "^1.4.0"
}
},
"node_modules/engine.io": {
- "version": "6.6.2",
- "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz",
- "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==",
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz",
+ "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==",
"license": "MIT",
"dependencies": {
- "@types/cookie": "^0.4.1",
"@types/cors": "^2.8.12",
"@types/node": ">=10.0.0",
"accepts": "~1.3.4",
@@ -7831,10 +8365,28 @@
"node": ">=10.0.0"
}
},
+ "node_modules/engine.io/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
@@ -7842,20 +8394,12 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
- "node_modules/error": {
- "version": "7.2.1",
- "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz",
- "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==",
- "dev": true,
- "dependencies": {
- "string-template": "~0.2.1"
- }
- },
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-arrayish": "^0.2.1"
}
@@ -7879,9 +8423,9 @@
}
},
"node_modules/es-object-atoms": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
- "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
+ "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"
@@ -7890,12 +8434,28 @@
"node": ">= 0.4"
}
},
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/esbuild": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz",
"integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==",
"dev": true,
"hasInstallScript": true,
+ "license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
@@ -7928,44 +8488,50 @@
}
},
"node_modules/esbuild-envfile-plugin": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/esbuild-envfile-plugin/-/esbuild-envfile-plugin-1.0.5.tgz",
- "integrity": "sha512-AT6mUTI4pbVodwLRYOrXYeXmFCAKO3SpRqAktS0IlKvpohTgvw/cYWUgkOXpB46BhMwhjwucBKO5UVejNg/DPg==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/esbuild-envfile-plugin/-/esbuild-envfile-plugin-1.0.7.tgz",
+ "integrity": "sha512-Qy2AUafFBY4T/OsMTlMab9h0ozostIqbJ/ZCLZXei3pgbxow3nyZixV0JTlpolNMQ56/g0UbcvPSuOgUnt4esg==",
"dev": true,
+ "license": "ISC",
"dependencies": {
- "dotenv": "16.0.3"
+ "dotenv": "16.4.5"
}
},
"node_modules/esbuild-envfile-plugin/node_modules/dotenv": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
- "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
+ "version": "16.4.5",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
+ "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
"dev": true,
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
}
},
"node_modules/esbuild-node-externals": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/esbuild-node-externals/-/esbuild-node-externals-1.8.0.tgz",
- "integrity": "sha512-pYslmT8Bl383UnfxzHQQRpCgBNIOwAzDaYheuIeI4CODxelsN/eQroVn5STDow5QOpRalMgWUR+R8LfSgUROcw==",
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/esbuild-node-externals/-/esbuild-node-externals-1.18.0.tgz",
+ "integrity": "sha512-suFVX3SzZlXrGIS9Yqx+ZaHL4w1p0e/j7dQbOM9zk8SfFpnAGnDplHUKXIf9kcPEAfZRL66JuYeVSVlsSEQ5Eg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "find-up": "^5.0.0",
- "tslib": "^2.4.1"
+ "find-up": "^5.0.0"
},
"engines": {
"node": ">=12"
},
"peerDependencies": {
- "esbuild": "0.12 - 0.18"
+ "esbuild": "0.12 - 0.25"
}
},
"node_modules/escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "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"
}
@@ -7977,36 +8543,42 @@
"license": "MIT"
},
"node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "license": "MIT",
"engines": {
- "node": ">=0.8.0"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint": {
- "version": "8.45.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz",
- "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==",
+ "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.4.0",
- "@eslint/eslintrc": "^2.1.0",
- "@eslint/js": "8.44.0",
- "@humanwhocodes/config-array": "^0.11.10",
+ "@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",
- "ajv": "^6.10.0",
+ "@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.0",
- "eslint-visitor-keys": "^3.4.1",
- "espree": "^9.6.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",
@@ -8044,6 +8616,7 @@
"resolved": "https://registry.npmjs.org/eslint-plugin-security/-/eslint-plugin-security-1.7.1.tgz",
"integrity": "sha512-sMStceig8AFglhhT2LqlU5r+/fn9OwsA72O5bBuQVTssPCdQAOQzL+oMn/ZcpeUY6KcNfLJArgcrsSULNjYYdQ==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"safe-regex": "^2.1.1"
}
@@ -8053,6 +8626,7 @@
"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"
@@ -8062,10 +8636,11 @@
}
},
"node_modules/eslint-visitor-keys": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
- "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
+ "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"
},
@@ -8073,72 +8648,12 @@
"url": "https://opencollective.com/eslint"
}
},
- "node_modules/eslint/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/eslint/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "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/eslint/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/eslint/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/eslint/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,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/eslint/node_modules/eslint-scope": {
- "version": "7.2.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.1.tgz",
- "integrity": "sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==",
+ "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"
@@ -8155,6 +8670,7 @@
"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"
}
@@ -8164,6 +8680,7 @@
"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"
},
@@ -8172,10 +8689,11 @@
}
},
"node_modules/eslint/node_modules/globals": {
- "version": "13.20.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
- "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
+ "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"
},
@@ -8186,25 +8704,17 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/eslint/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/eslint/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==",
+ "node_modules/eslint/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": {
- "has-flag": "^4.0.0"
+ "brace-expansion": "^1.1.7"
},
"engines": {
- "node": ">=8"
+ "node": "*"
}
},
"node_modules/eslint/node_modules/type-fest": {
@@ -8212,6 +8722,7 @@
"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"
},
@@ -8224,6 +8735,7 @@
"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",
@@ -8241,6 +8753,7 @@
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true,
+ "license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
@@ -8250,10 +8763,11 @@
}
},
"node_modules/esquery": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
- "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "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"
},
@@ -8266,6 +8780,7 @@
"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"
}
@@ -8275,6 +8790,7 @@
"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"
},
@@ -8287,6 +8803,7 @@
"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"
}
@@ -8296,6 +8813,7 @@
"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"
}
@@ -8305,6 +8823,7 @@
"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"
}
@@ -8318,12 +8837,6 @@
"node": ">= 0.6"
}
},
- "node_modules/eventemitter2": {
- "version": "0.4.14",
- "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
- "integrity": "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==",
- "dev": true
- },
"node_modules/events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
@@ -8334,14 +8847,15 @@
}
},
"node_modules/exceljs": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/exceljs/-/exceljs-4.3.0.tgz",
- "integrity": "sha512-hTAeo5b5TPvf8Z02I2sKIT4kSfCnOO2bCxYX8ABqODCdAjppI3gI9VYiGCQQYVcBaBSKlFDMKlAQRqC+kV9O8w==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/exceljs/-/exceljs-4.4.0.tgz",
+ "integrity": "sha512-XctvKaEMaj1Ii9oDOqbW/6e1gXknSY4g/aLCDicOXqBE4M0nRWkUu0PTp++UPNzoFY12BNHMfs/VadKIS6llvg==",
+ "license": "MIT",
"dependencies": {
"archiver": "^5.0.0",
"dayjs": "^1.8.34",
"fast-csv": "^4.3.1",
- "jszip": "^3.5.0",
+ "jszip": "^3.10.1",
"readable-stream": "^3.6.0",
"saxes": "^5.0.1",
"tmp": "^0.2.0",
@@ -8352,11 +8866,21 @@
"node": ">=8.3.0"
}
},
+ "node_modules/exceljs/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/execa": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"cross-spawn": "^7.0.3",
"get-stream": "^6.0.0",
@@ -8375,17 +8899,12 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
- "node_modules/execa/node_modules/npm-run-path": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "node_modules/execa/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true,
- "dependencies": {
- "path-key": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
+ "license": "ISC"
},
"node_modules/exit": {
"version": "0.1.2",
@@ -8400,6 +8919,7 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+ "license": "(MIT OR WTFPL)",
"engines": {
"node": ">=6"
}
@@ -8408,7 +8928,7 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
"integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"homedir-polyfill": "^1.0.1"
},
@@ -8421,6 +8941,7 @@
"resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz",
"integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/expect-utils": "^28.1.3",
"jest-get-type": "^28.0.2",
@@ -8479,11 +9000,12 @@
}
},
"node_modules/express-rate-limit": {
- "version": "6.8.0",
- "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.8.0.tgz",
- "integrity": "sha512-yVeDWczkh8qgo9INJB1tT4j7LFu+n6ei/oqSMsqpsUIGYjTM+gk+Q3wv19TMUdo8chvus8XohAuOhG7RYRM9ZQ==",
+ "version": "6.11.2",
+ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.11.2.tgz",
+ "integrity": "sha512-a7uwwfNTh1U60ssiIkuLFWHt4hAC5yxlLGU2VP0X4YNlyEDZAqF4tK3GD3NSitVBrCQmQ0++0uOyFOgC2y4DDw==",
+ "license": "MIT",
"engines": {
- "node": ">= 14.0.0"
+ "node": ">= 14"
},
"peerDependencies": {
"express": "^4 || ^5"
@@ -8518,6 +9040,7 @@
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
@@ -8525,31 +9048,14 @@
"node_modules/express-session/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
- },
- "node_modules/express-session/node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
},
"node_modules/express-validator": {
"version": "6.15.0",
"resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.15.0.tgz",
"integrity": "sha512-r05VYoBL3i2pswuehoFSy+uM8NBuVaY7avp5qrYjQBDzagx2Z5A77FZqPT8/gNLF3HopWkIzaTFaC4JysWXLqg==",
+ "license": "MIT",
"dependencies": {
"lodash": "^4.17.21",
"validator": "^13.9.0"
@@ -8571,6 +9077,7 @@
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
@@ -8578,37 +9085,20 @@
"node_modules/express/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
- },
- "node_modules/express/node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
},
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
- "dev": true
+ "license": "MIT"
},
"node_modules/fast-csv": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/fast-csv/-/fast-csv-4.3.6.tgz",
"integrity": "sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==",
+ "license": "MIT",
"dependencies": {
"@fast-csv/format": "4.3.5",
"@fast-csv/parse": "4.3.6"
@@ -8621,24 +9111,27 @@
"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
+ "dev": true,
+ "license": "MIT"
},
"node_modules/fast-fifo": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
- "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="
+ "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
+ "license": "MIT"
},
"node_modules/fast-glob": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
- "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==",
+ "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.4"
+ "micromatch": "^4.0.8"
},
"engines": {
"node": ">=8.6.0"
@@ -8648,28 +9141,31 @@
"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
+ "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
+ "dev": true,
+ "license": "MIT"
},
"node_modules/fast-xml-parser": {
- "version": "4.2.5",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz",
- "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz",
+ "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==",
"funding": [
- {
- "type": "paypal",
- "url": "https://paypal.me/naturalintelligence"
- },
{
"type": "github",
"url": "https://github.com/sponsors/NaturalIntelligence"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/naturalintelligence"
}
],
+ "license": "MIT",
"dependencies": {
"strnum": "^1.0.5"
},
@@ -8678,31 +9174,21 @@
}
},
"node_modules/fastq": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
- "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+ "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/faye-websocket": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
- "integrity": "sha512-Xhj93RXbMSq8urNCUq4p9l0P6hnySJ/7YNRhYNug0bLOuii7pKO7xQFb5mx9xZXWCar88pLPb805PvUkwrLZpQ==",
- "dev": true,
- "dependencies": {
- "websocket-driver": ">=0.5.1"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
"node_modules/fb-watchman": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
"integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"bser": "2.1.1"
}
@@ -8710,28 +9196,15 @@
"node_modules/fecha": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
- "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
- },
- "node_modules/figures": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
- "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
- "dev": true,
- "dependencies": {
- "escape-string-regexp": "^1.0.5"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
+ "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==",
+ "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"
},
@@ -8739,22 +9212,16 @@
"node": "^10.12.0 || >=12.0.0"
}
},
- "node_modules/file-sync-cmp": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz",
- "integrity": "sha512-0k45oWBokCqh2MOexeYKpyqmGKG+8mQ2Wd8iawx+uWd/weWJQAZ6SoPybagdCI4xFisag8iAR77WPm4h3pTfxA==",
- "dev": true
- },
"node_modules/file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
- "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+ "license": "MIT"
},
"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"
@@ -8796,11 +9263,19 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
},
+ "node_modules/find-index": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz",
+ "integrity": "sha512-uJ5vWrfBKMcE6y2Z8834dwEZj9mNGxYa3t3I53OwFeuZ8D9oc2E5zcsrkuhX6h4iYrjhiv0T3szQmxlAV9uxDg==",
+ "dev": true,
+ "license": "MIT"
+ },
"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"
@@ -8813,25 +9288,25 @@
}
},
"node_modules/findup-sync": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz",
- "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==",
- "dev": true,
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz",
+ "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==",
+ "license": "MIT",
"dependencies": {
"detect-file": "^1.0.0",
- "is-glob": "^4.0.3",
- "micromatch": "^4.0.4",
+ "is-glob": "^4.0.0",
+ "micromatch": "^4.0.2",
"resolve-dir": "^1.0.1"
},
"engines": {
- "node": ">= 10.13.0"
+ "node": ">= 8"
}
},
"node_modules/fined": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz",
"integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"expand-tilde": "^2.0.2",
"is-plain-object": "^2.0.3",
@@ -8847,34 +9322,90 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
"integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/flat-cache": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
- "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+ "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.1.0",
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
"rimraf": "^3.0.2"
},
"engines": {
"node": "^10.12.0 || >=12.0.0"
}
},
+ "node_modules/flat-cache/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/flat-cache/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/flat-cache/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/flatted": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
- "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
- "dev": true
+ "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/fn.name": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
- "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
+ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==",
+ "license": "MIT"
},
"node_modules/follow-redirects": {
"version": "1.15.9",
@@ -8900,7 +9431,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
"integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -8909,7 +9440,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
"integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"for-in": "^1.0.1"
},
@@ -8917,13 +9448,33 @@
"node": ">=0.10.0"
}
},
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "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": {
@@ -8934,6 +9485,7 @@
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -8950,13 +9502,15 @@
"node_modules/fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
- "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+ "license": "MIT"
},
"node_modules/fs-extra": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
@@ -8970,6 +9524,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "license": "ISC",
"dependencies": {
"minipass": "^3.0.0"
},
@@ -8981,6 +9536,7 @@
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "license": "ISC",
"dependencies": {
"yallist": "^4.0.0"
},
@@ -8991,19 +9547,22 @@
"node_modules/fs-minipass/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "license": "ISC"
},
"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=="
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "license": "ISC"
},
"node_modules/fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "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"
@@ -9016,6 +9575,8 @@
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
+ "deprecated": "This package is no longer supported.",
+ "license": "ISC",
"dependencies": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
@@ -9026,10 +9587,44 @@
"node": ">=0.6"
}
},
+ "node_modules/fstream/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/fstream/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/fstream/node_modules/mkdirp": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "license": "MIT",
"dependencies": {
"minimist": "^1.2.6"
},
@@ -9041,6 +9636,8 @@
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "license": "ISC",
"dependencies": {
"glob": "^7.1.3"
},
@@ -9061,6 +9658,8 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
+ "deprecated": "This package is no longer supported.",
+ "license": "ISC",
"dependencies": {
"aproba": "^1.0.3 || ^2.0.0",
"color-support": "^1.1.2",
@@ -9076,22 +9675,37 @@
"node": ">=10"
}
},
- "node_modules/gaze": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
- "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
- "dev": true,
+ "node_modules/gauge/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
+ "node_modules/gauge/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "license": "ISC"
+ },
+ "node_modules/gauge/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
"dependencies": {
- "globule": "^1.0.0"
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
},
"engines": {
- "node": ">= 4.0.0"
+ "node": ">=8"
}
},
"node_modules/generic-pool": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
"integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
+ "license": "MIT",
"engines": {
"node": ">= 4"
}
@@ -9101,6 +9715,7 @@
"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"
}
@@ -9110,26 +9725,27 @@
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
+ "license": "ISC",
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/get-intrinsic": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz",
- "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==",
+ "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.1",
- "dunder-proto": "^1.0.0",
+ "call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
- "es-object-atoms": "^1.0.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.0.0"
+ "math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
@@ -9143,15 +9759,30 @@
"resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
"integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
+ "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": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
},
@@ -9159,34 +9790,31 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/getobject": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.2.tgz",
- "integrity": "sha512-2zblDBaFcb3rB4rF77XVnuINOE2h2k/OnqXAiy0IrTxUfV1iFp3la33oAQVY9pCpWU268WFYVt2t71hlMuLsOg==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
- "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="
+ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
+ "license": "MIT"
},
"node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz",
+ "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==",
+ "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"
+ "foreground-child": "^3.3.1",
+ "jackspeak": "^4.1.1",
+ "minimatch": "^10.0.3",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^2.0.0"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
},
"engines": {
- "node": "*"
+ "node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -9197,6 +9825,7 @@
"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"
},
@@ -9204,11 +9833,23 @@
"node": ">= 6"
}
},
+ "node_modules/glob2base": {
+ "version": "0.0.12",
+ "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz",
+ "integrity": "sha512-ZyqlgowMbfj2NPjxaZZ/EtsXlOch28FRXgMd64vqZWk1bT9+wvSRLYD1om9M7QfQru51zJPAT17qXm4/zd+9QA==",
+ "dev": true,
+ "dependencies": {
+ "find-index": "^0.1.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/global-modules": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
"integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"global-prefix": "^1.0.1",
"is-windows": "^1.0.1",
@@ -9222,7 +9863,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
"integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"expand-tilde": "^2.0.2",
"homedir-polyfill": "^1.0.1",
@@ -9238,7 +9879,7 @@
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "dev": true,
+ "license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
@@ -9251,6 +9892,7 @@
"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"
}
@@ -9260,6 +9902,7 @@
"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",
@@ -9275,52 +9918,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/globule": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz",
- "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==",
- "dev": true,
- "dependencies": {
- "glob": "~7.1.1",
- "lodash": "^4.17.21",
- "minimatch": "~3.0.2"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/globule/node_modules/glob": {
- "version": "7.1.7",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
- "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/globule/node_modules/minimatch": {
- "version": "3.0.8",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
- "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -9336,52 +9933,27 @@
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "license": "ISC"
},
"node_modules/graphemer": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
- "dev": true
- },
- "node_modules/grunt": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.6.1.tgz",
- "integrity": "sha512-/ABUy3gYWu5iBmrUSRBP97JLpQUm0GgVveDCp6t3yRNIoltIYw7rEj3g5y1o2PGPR2vfTRGa7WC/LZHLTXnEzA==",
"dev": true,
- "dependencies": {
- "dateformat": "~4.6.2",
- "eventemitter2": "~0.4.13",
- "exit": "~0.1.2",
- "findup-sync": "~5.0.0",
- "glob": "~7.1.6",
- "grunt-cli": "~1.4.3",
- "grunt-known-options": "~2.0.0",
- "grunt-legacy-log": "~3.0.0",
- "grunt-legacy-util": "~2.0.1",
- "iconv-lite": "~0.6.3",
- "js-yaml": "~3.14.0",
- "minimatch": "~3.0.4",
- "nopt": "~3.0.6"
- },
- "bin": {
- "grunt": "bin/grunt"
- },
- "engines": {
- "node": ">=16"
- }
+ "license": "MIT"
},
"node_modules/grunt-cli": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz",
- "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==",
- "dev": true,
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.5.0.tgz",
+ "integrity": "sha512-rILKAFoU0dzlf22SUfDtq2R1fosChXXlJM5j7wI6uoW8gwmXDXzbUvirlKZSYCdXl3LXFbR+8xyS+WFo+b6vlA==",
+ "license": "MIT",
"dependencies": {
"grunt-known-options": "~2.0.0",
"interpret": "~1.1.0",
"liftup": "~3.0.1",
- "nopt": "~4.0.1",
- "v8flags": "~3.2.0"
+ "nopt": "~5.0.0",
+ "v8flags": "^4.0.1"
},
"bin": {
"grunt": "bin/grunt"
@@ -9390,702 +9962,23 @@
"node": ">=10"
}
},
- "node_modules/grunt-cli/node_modules/nopt": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
- "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
- "dev": true,
- "dependencies": {
- "abbrev": "1",
- "osenv": "^0.1.4"
- },
- "bin": {
- "nopt": "bin/nopt.js"
- }
- },
- "node_modules/grunt-contrib-clean": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-2.0.1.tgz",
- "integrity": "sha512-uRvnXfhiZt8akb/ZRDHJpQQtkkVkqc/opWO4Po/9ehC2hPxgptB9S6JHDC/Nxswo4CJSM0iFPT/Iym3cEMWzKA==",
- "dev": true,
- "dependencies": {
- "async": "^3.2.3",
- "rimraf": "^2.6.2"
- },
- "engines": {
- "node": ">=12"
- },
- "peerDependencies": {
- "grunt": ">=0.4.5"
- }
- },
- "node_modules/grunt-contrib-clean/node_modules/rimraf": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
- "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- }
- },
- "node_modules/grunt-contrib-compress": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/grunt-contrib-compress/-/grunt-contrib-compress-2.0.0.tgz",
- "integrity": "sha512-r/dAGx4qG+rmBFF4lb/hTktW2huGMGxkSLf9msh3PPtq0+cdQRQerZJ30UKevX3BLQsohwLzO0p1z/LrH6aKXQ==",
- "dev": true,
- "dependencies": {
- "adm-zip": "^0.5.1",
- "archiver": "^5.1.0",
- "chalk": "^4.1.0",
- "lodash": "^4.17.20",
- "pretty-bytes": "^5.4.1",
- "stream-buffers": "^3.0.2"
- },
- "engines": {
- "node": ">=10.16"
- }
- },
- "node_modules/grunt-contrib-compress/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/grunt-contrib-compress/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "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/grunt-contrib-compress/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/grunt-contrib-compress/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/grunt-contrib-compress/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/grunt-contrib-compress/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/grunt-contrib-copy": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz",
- "integrity": "sha512-gFRFUB0ZbLcjKb67Magz1yOHGBkyU6uL29hiEW1tdQ9gQt72NuMKIy/kS6dsCbV0cZ0maNCb0s6y+uT1FKU7jA==",
- "dev": true,
- "dependencies": {
- "chalk": "^1.1.1",
- "file-sync-cmp": "^0.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/grunt-contrib-copy/node_modules/ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/grunt-contrib-copy/node_modules/ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/grunt-contrib-copy/node_modules/chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^2.2.1",
- "escape-string-regexp": "^1.0.2",
- "has-ansi": "^2.0.0",
- "strip-ansi": "^3.0.0",
- "supports-color": "^2.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/grunt-contrib-copy/node_modules/strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^2.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/grunt-contrib-copy/node_modules/supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
- "dev": true,
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/grunt-contrib-uglify": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-5.2.2.tgz",
- "integrity": "sha512-ITxiWxrjjP+RZu/aJ5GLvdele+sxlznh+6fK9Qckio5ma8f7Iv8woZjRkGfafvpuygxNefOJNc+hfjjBayRn2Q==",
- "dev": true,
- "dependencies": {
- "chalk": "^4.1.2",
- "maxmin": "^3.0.0",
- "uglify-js": "^3.16.1",
- "uri-path": "^1.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/grunt-contrib-uglify/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/grunt-contrib-uglify/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "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/grunt-contrib-uglify/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/grunt-contrib-uglify/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/grunt-contrib-uglify/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/grunt-contrib-uglify/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/grunt-contrib-watch": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz",
- "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==",
- "dev": true,
- "dependencies": {
- "async": "^2.6.0",
- "gaze": "^1.1.0",
- "lodash": "^4.17.10",
- "tiny-lr": "^1.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/grunt-contrib-watch/node_modules/async": {
- "version": "2.6.4",
- "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
- "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
- "dev": true,
- "dependencies": {
- "lodash": "^4.17.14"
- }
- },
"node_modules/grunt-known-options": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz",
"integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/grunt-legacy-log": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz",
- "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==",
- "dev": true,
- "dependencies": {
- "colors": "~1.1.2",
- "grunt-legacy-log-utils": "~2.1.0",
- "hooker": "~0.2.3",
- "lodash": "~4.17.19"
- },
- "engines": {
- "node": ">= 0.10.0"
- }
- },
- "node_modules/grunt-legacy-log-utils": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz",
- "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==",
- "dev": true,
- "dependencies": {
- "chalk": "~4.1.0",
- "lodash": "~4.17.19"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/grunt-legacy-log-utils/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/grunt-legacy-log-utils/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "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/grunt-legacy-log-utils/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/grunt-legacy-log-utils/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/grunt-legacy-log-utils/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/grunt-legacy-log-utils/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/grunt-legacy-util": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz",
- "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==",
- "dev": true,
- "dependencies": {
- "async": "~3.2.0",
- "exit": "~0.1.2",
- "getobject": "~1.0.0",
- "hooker": "~0.2.3",
- "lodash": "~4.17.21",
- "underscore.string": "~3.3.5",
- "which": "~2.0.2"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/grunt-shell": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/grunt-shell/-/grunt-shell-4.0.0.tgz",
- "integrity": "sha512-dHFy8VZDfWGYLTeNvIHze4PKXGvIlDWuN0UE7hUZstTQeiEyv1VmW1MaDYQ3X5tE3bCi3bEia1gGKH8z/f1czQ==",
- "dev": true,
- "dependencies": {
- "chalk": "^3.0.0",
- "npm-run-path": "^2.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- },
- "peerDependencies": {
- "grunt": ">=1"
- }
- },
- "node_modules/grunt-shell/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/grunt-shell/node_modules/chalk": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
- "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/grunt-shell/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/grunt-shell/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/grunt-shell/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/grunt-shell/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/grunt-sync": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/grunt-sync/-/grunt-sync-0.8.2.tgz",
- "integrity": "sha512-PB+xKI9YPyZn3NZQXpKHfZVlxHdf1L8GMl+Wi0mLhYypWuOdZPW2EzTmSuhhFbXjkb0aIOxvII1zdZZEl9zqGg==",
- "dev": true,
- "dependencies": {
- "fs-extra": "^6.0.1",
- "glob": "^7.0.5",
- "md5-file": "^2.0.3"
- },
- "engines": {
- "node": ">=6 <7 || >=8"
- }
- },
- "node_modules/grunt-sync/node_modules/fs-extra": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz",
- "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- }
- },
- "node_modules/grunt-sync/node_modules/jsonfile": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
- "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
- "dev": true,
- "optionalDependencies": {
- "graceful-fs": "^4.1.6"
- }
- },
- "node_modules/grunt-sync/node_modules/universalify": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
- "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
- "dev": true,
- "engines": {
- "node": ">= 4.0.0"
- }
- },
- "node_modules/grunt/node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
- },
- "node_modules/grunt/node_modules/glob": {
- "version": "7.1.7",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
- "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/grunt/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,
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/grunt/node_modules/js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
- "dev": true,
- "dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/grunt/node_modules/minimatch": {
- "version": "3.0.8",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
- "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/grunt/node_modules/nopt": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
- "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==",
- "dev": true,
- "dependencies": {
- "abbrev": "1"
- },
- "bin": {
- "nopt": "bin/nopt.js"
- }
- },
- "node_modules/grunt/node_modules/sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
- "dev": true
- },
- "node_modules/gzip-size": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz",
- "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==",
- "dev": true,
- "dependencies": {
- "duplexer": "^0.1.1",
- "pify": "^4.0.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "dependencies": {
- "function-bind": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^2.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/has-ansi/node_modules/ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=4"
+ "node": ">=8"
}
},
"node_modules/has-symbols": {
@@ -10101,11 +9994,12 @@
}
},
"node_modules/has-tostringtag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
- "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "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.2"
+ "has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
@@ -10117,7 +10011,8 @@
"node_modules/has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
- "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
+ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
+ "license": "ISC"
},
"node_modules/hasown": {
"version": "2.0.2",
@@ -10135,6 +10030,7 @@
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/helmet/-/helmet-6.2.0.tgz",
"integrity": "sha512-DWlwuXLLqbrIOltR6tFQXShj/+7Cyp0gLi6uAb8qMdFh/YBBFbKSgQ6nbXmScYd8emMctuthmgIa7tUfo9Rtyg==",
+ "license": "MIT",
"engines": {
"node": ">=14.0.0"
}
@@ -10150,7 +10046,7 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
"integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"parse-passwd": "^1.0.0"
},
@@ -10158,19 +10054,11 @@
"node": ">=0.10.0"
}
},
- "node_modules/hooker": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
- "integrity": "sha512-t+UerCsQviSymAInD01Pw+Dn/usmz1sRO+3Zk1+lx8eg+WKpD2ulcwWqHHL0+aseRBr+3+vIhiG1K1JTwaIcTA==",
- "dev": true,
- "engines": {
- "node": "*"
- }
- },
"node_modules/hpp": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/hpp/-/hpp-0.2.3.tgz",
"integrity": "sha512-4zDZypjQcxK/8pfFNR7jaON7zEUpXZxz4viyFmqjb3kWNWAHsLEUmWXcdn25c5l76ISvnD6hbOGO97cXUI3Ryw==",
+ "license": "ISC",
"dependencies": {
"lodash": "^4.17.12",
"type-is": "^1.6.12"
@@ -10183,7 +10071,8 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/htmlparser2": {
"version": "8.0.2",
@@ -10196,6 +10085,7 @@
"url": "https://github.com/sponsors/fb55"
}
],
+ "license": "MIT",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3",
@@ -10207,6 +10097,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "license": "MIT",
"dependencies": {
"depd": "2.0.0",
"inherits": "2.0.4",
@@ -10218,12 +10109,6 @@
"node": ">= 0.8"
}
},
- "node_modules/http-parser-js": {
- "version": "0.5.8",
- "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz",
- "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==",
- "dev": true
- },
"node_modules/http-proxy-agent": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
@@ -10237,25 +10122,17 @@
"node": ">= 14"
}
},
- "node_modules/http-proxy-agent/node_modules/agent-base": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
- "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
"node_modules/https-proxy-agent": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "license": "MIT",
"dependencies": {
- "agent-base": "6",
+ "agent-base": "^7.1.2",
"debug": "4"
},
"engines": {
- "node": ">= 6"
+ "node": ">= 14"
}
},
"node_modules/human-signals": {
@@ -10263,6 +10140,7 @@
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": ">=10.17.0"
}
@@ -10296,13 +10174,15 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ]
+ ],
+ "license": "BSD-3-Clause"
},
"node_modules/ignore": {
- "version": "5.2.4",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
- "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+ "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"
}
@@ -10310,13 +10190,15 @@
"node_modules/immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
- "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
+ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
+ "license": "MIT"
},
"node_modules/import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "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"
@@ -10329,10 +10211,11 @@
}
},
"node_modules/import-local": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
- "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
+ "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"pkg-dir": "^4.2.0",
"resolve-cwd": "^3.0.0"
@@ -10352,6 +10235,7 @@
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.8.19"
}
@@ -10360,6 +10244,8 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "license": "ISC",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@@ -10368,23 +10254,26 @@
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
},
"node_modules/ini": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "license": "ISC"
},
"node_modules/interpret": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
"integrity": "sha512-CLM8SNMDu7C5psFCn6Wg/tgpj/bKAg7hc2gWqcuR9OD5Ft9PhBpIu8PLicPeis+xDd6YX2ncI8MCA64I9tftIA==",
- "dev": true
+ "license": "MIT"
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "license": "MIT",
"engines": {
"node": ">= 0.10"
}
@@ -10393,7 +10282,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
"integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"is-relative": "^1.0.0",
"is-windows": "^1.0.1"
@@ -10406,13 +10295,15 @@
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"binary-extensions": "^2.0.0"
},
@@ -10421,11 +10312,15 @@
}
},
"node_modules/is-core-module": {
- "version": "2.12.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
- "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "license": "MIT",
"dependencies": {
- "has": "^1.0.3"
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -10435,6 +10330,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz",
"integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==",
+ "license": "MIT",
"dependencies": {
"acorn": "^7.1.1",
"object-assign": "^4.1.1"
@@ -10444,6 +10340,7 @@
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
@@ -10455,7 +10352,7 @@
"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"
}
@@ -10464,6 +10361,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -10473,6 +10371,7 @@
"resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
"integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -10481,7 +10380,7 @@
"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"
},
@@ -10493,7 +10392,6 @@
"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"
@@ -10504,6 +10402,7 @@
"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"
}
@@ -10512,7 +10411,7 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"isobject": "^3.0.1"
},
@@ -10523,15 +10422,19 @@
"node_modules/is-promise": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
- "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
+ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
+ "license": "MIT"
},
"node_modules/is-regex": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
- "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "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==",
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -10544,7 +10447,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
"integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"is-unc-path": "^1.0.0"
},
@@ -10556,6 +10459,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "license": "MIT",
"engines": {
"node": ">=8"
},
@@ -10567,7 +10471,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
"integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"unc-path-regex": "^0.1.2"
},
@@ -10579,7 +10483,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -10587,28 +10491,30 @@
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "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/isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
"integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/istanbul-lib-coverage": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
- "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=8"
}
@@ -10618,6 +10524,7 @@
"resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
"integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"@babel/core": "^7.12.3",
"@babel/parser": "^7.14.7",
@@ -10634,6 +10541,7 @@
"resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
"integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"istanbul-lib-coverage": "^3.0.0",
"make-dir": "^4.0.0",
@@ -10643,32 +10551,12 @@
"node": ">=10"
}
},
- "node_modules/istanbul-lib-report/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-report/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/istanbul-lib-report/node_modules/make-dir": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
"integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"semver": "^7.5.3"
},
@@ -10680,13 +10568,11 @@
}
},
"node_modules/istanbul-lib-report/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -10699,6 +10585,7 @@
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -10706,17 +10593,12 @@
"node": ">=8"
}
},
- "node_modules/istanbul-lib-report/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"node_modules/istanbul-lib-source-maps": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
"integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"debug": "^4.1.1",
"istanbul-lib-coverage": "^3.0.0",
@@ -10727,10 +10609,11 @@
}
},
"node_modules/istanbul-reports": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz",
- "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==",
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
+ "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"html-escaper": "^2.0.0",
"istanbul-lib-report": "^3.0.0"
@@ -10739,16 +10622,34 @@
"node": ">=8"
}
},
+ "node_modules/jackspeak": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz",
+ "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/javascript-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz",
- "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg=="
+ "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
+ "license": "MIT"
},
"node_modules/jest": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz",
"integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/core": "^28.1.3",
"@jest/types": "^28.1.3",
@@ -10775,6 +10676,7 @@
"resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz",
"integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"execa": "^5.0.0",
"p-limit": "^3.1.0"
@@ -10788,6 +10690,7 @@
"resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz",
"integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/environment": "^28.1.3",
"@jest/expect": "^28.1.3",
@@ -10813,81 +10716,12 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/jest-circus/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-circus/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-circus/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-circus/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-circus/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-circus/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/jest-cli": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz",
"integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/core": "^28.1.3",
"@jest/test-result": "^28.1.3",
@@ -10917,81 +10751,12 @@
}
}
},
- "node_modules/jest-cli/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-cli/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-cli/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-cli/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-cli/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-cli/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/jest-config": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz",
"integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/core": "^7.11.6",
"@jest/test-sequencer": "^28.1.3",
@@ -11032,74 +10797,39 @@
}
}
},
- "node_modules/jest-config/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==",
+ "node_modules/jest-config/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": {
- "color-convert": "^2.0.1"
+ "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": ">=8"
+ "node": "*"
},
"funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/jest-config/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "node_modules/jest-config/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": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
+ "brace-expansion": "^1.1.7"
},
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-config/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-config/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-config/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-config/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
+ "node": "*"
}
},
"node_modules/jest-diff": {
@@ -11107,6 +10837,7 @@
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz",
"integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"chalk": "^4.0.0",
"diff-sequences": "^28.1.1",
@@ -11117,81 +10848,12 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/jest-diff/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-diff/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-diff/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-diff/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-diff/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-diff/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/jest-docblock": {
"version": "28.1.1",
"resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz",
"integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"detect-newline": "^3.0.0"
},
@@ -11204,6 +10866,7 @@
"resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz",
"integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/types": "^28.1.3",
"chalk": "^4.0.0",
@@ -11215,81 +10878,12 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/jest-each/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-each/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-each/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-each/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-each/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-each/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/jest-environment-node": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz",
"integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/environment": "^28.1.3",
"@jest/fake-timers": "^28.1.3",
@@ -11307,6 +10901,7 @@
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz",
"integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
@@ -11316,6 +10911,7 @@
"resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz",
"integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/types": "^28.1.3",
"@types/graceful-fs": "^4.1.3",
@@ -11341,6 +10937,7 @@
"resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz",
"integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"jest-get-type": "^28.0.2",
"pretty-format": "^28.1.3"
@@ -11354,6 +10951,7 @@
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz",
"integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"chalk": "^4.0.0",
"jest-diff": "^28.1.3",
@@ -11364,81 +10962,12 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/jest-matcher-utils/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-matcher-utils/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-matcher-utils/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-matcher-utils/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-matcher-utils/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-matcher-utils/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/jest-message-util": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz",
"integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.12.13",
"@jest/types": "^28.1.3",
@@ -11454,81 +10983,12 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/jest-message-util/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-message-util/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-message-util/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-message-util/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-message-util/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-message-util/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/jest-mock": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz",
"integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/types": "^28.1.3",
"@types/node": "*"
@@ -11542,6 +11002,7 @@
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
"integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
},
@@ -11559,6 +11020,7 @@
"resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz",
"integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
@@ -11568,6 +11030,7 @@
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz",
"integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"chalk": "^4.0.0",
"graceful-fs": "^4.2.9",
@@ -11588,6 +11051,7 @@
"resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz",
"integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"jest-regex-util": "^28.0.2",
"jest-snapshot": "^28.1.3"
@@ -11596,81 +11060,12 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/jest-resolve/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-resolve/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-resolve/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-resolve/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-resolve/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-resolve/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/jest-runner": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz",
"integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/console": "^28.1.3",
"@jest/environment": "^28.1.3",
@@ -11698,81 +11093,12 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/jest-runner/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-runner/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-runner/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-runner/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-runner/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-runner/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/jest-runtime": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz",
"integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/environment": "^28.1.3",
"@jest/fake-timers": "^28.1.3",
@@ -11801,74 +11127,39 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/jest-runtime/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==",
+ "node_modules/jest-runtime/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": {
- "color-convert": "^2.0.1"
+ "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": ">=8"
+ "node": "*"
},
"funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/jest-runtime/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "node_modules/jest-runtime/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": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
+ "brace-expansion": "^1.1.7"
},
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-runtime/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-runtime/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-runtime/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-runtime/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
+ "node": "*"
}
},
"node_modules/jest-snapshot": {
@@ -11876,6 +11167,7 @@
"resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz",
"integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/core": "^7.11.6",
"@babel/generator": "^7.7.2",
@@ -11905,84 +11197,12 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/jest-snapshot/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-snapshot/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-snapshot/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-snapshot/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-snapshot/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-snapshot/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/jest-snapshot/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -11990,29 +11210,12 @@
"node": ">=10"
}
},
- "node_modules/jest-snapshot/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-snapshot/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"node_modules/jest-sonar-reporter": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/jest-sonar-reporter/-/jest-sonar-reporter-2.0.0.tgz",
"integrity": "sha512-ZervDCgEX5gdUbdtWsjdipLN3bKJwpxbvhkYNXTAYvAckCihobSLr9OT/IuyNIRT1EZMDDwR6DroWtrq+IL64w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"xml": "^1.0.1"
},
@@ -12025,6 +11228,7 @@
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz",
"integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/types": "^28.1.3",
"@types/node": "*",
@@ -12037,81 +11241,12 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/jest-util/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-util/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-util/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-util/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-util/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-util/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/jest-validate": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz",
"integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/types": "^28.1.3",
"camelcase": "^6.2.0",
@@ -12124,26 +11259,12 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/jest-validate/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
"node_modules/jest-validate/node_modules/camelcase": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
},
@@ -12151,66 +11272,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/jest-validate/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-validate/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-validate/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-validate/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-validate/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/jest-watcher": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz",
"integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/test-result": "^28.1.3",
"@jest/types": "^28.1.3",
@@ -12225,81 +11292,12 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/jest-watcher/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jest-watcher/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jest-watcher/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/jest-watcher/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/jest-watcher/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-watcher/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/jest-worker": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz",
"integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/node": "*",
"merge-stream": "^2.0.0",
@@ -12309,30 +11307,6 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
- "node_modules/jest-worker/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-worker/node_modules/supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
- }
- },
"node_modules/js-stringify": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
@@ -12343,13 +11317,15 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
@@ -12358,40 +11334,52 @@
}
},
"node_modules/jsesc": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
- "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "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": ">=4"
+ "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-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
- "dev": true
+ "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
+ "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
+ "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"
},
@@ -12404,6 +11392,7 @@
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"universalify": "^2.0.0"
},
@@ -12412,46 +11401,41 @@
}
},
"node_modules/jsonschema": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz",
- "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.5.0.tgz",
+ "integrity": "sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==",
+ "license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/jsonwebtoken": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz",
- "integrity": "sha512-K8wx7eJ5TPvEjuiVSkv167EVboBDv9PZdDoF7BgeQnBLVvZWW9clr2PsQHVJDTKaEIH5JBIwHujGcHp7GgI2eg==",
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
+ "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
+ "license": "MIT",
"dependencies": {
"jws": "^3.2.2",
- "lodash": "^4.17.21",
+ "lodash.includes": "^4.3.0",
+ "lodash.isboolean": "^3.0.3",
+ "lodash.isinteger": "^4.0.4",
+ "lodash.isnumber": "^3.0.3",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.isstring": "^4.0.1",
+ "lodash.once": "^4.0.0",
"ms": "^2.1.1",
- "semver": "^7.3.8"
+ "semver": "^7.5.4"
},
"engines": {
"node": ">=12",
"npm": ">=6"
}
},
- "node_modules/jsonwebtoken/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/jsonwebtoken/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -12459,15 +11443,11 @@
"node": ">=10"
}
},
- "node_modules/jsonwebtoken/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- },
"node_modules/jstransformer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
"integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==",
+ "license": "MIT",
"dependencies": {
"is-promise": "^2.0.0",
"promise": "^7.0.1"
@@ -12477,6 +11457,7 @@
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
"integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
+ "license": "(MIT OR GPL-3.0-or-later)",
"dependencies": {
"lie": "~3.3.0",
"pako": "~1.0.2",
@@ -12488,6 +11469,7 @@
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
@@ -12498,20 +11480,28 @@
"util-deprecate": "~1.0.1"
}
},
+ "node_modules/jszip/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
"node_modules/jszip/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/jwa": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
- "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
+ "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
+ "license": "MIT",
"dependencies": {
- "buffer-equal-constant-time": "1.0.1",
+ "buffer-equal-constant-time": "^1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
@@ -12520,16 +11510,27 @@
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+ "license": "MIT",
"dependencies": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
+ "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/kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -12539,6 +11540,7 @@
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
"integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -12546,12 +11548,14 @@
"node_modules/kuler": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
- "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
+ "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==",
+ "license": "MIT"
},
"node_modules/lazystream": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
"integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==",
+ "license": "MIT",
"dependencies": {
"readable-stream": "^2.0.5"
},
@@ -12563,6 +11567,7 @@
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
@@ -12573,10 +11578,17 @@
"util-deprecate": "~1.0.1"
}
},
+ "node_modules/lazystream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
"node_modules/lazystream/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
@@ -12586,6 +11598,7 @@
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
"integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -12595,6 +11608,7 @@
"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"
@@ -12603,21 +11617,11 @@
"node": ">= 0.8.0"
}
},
- "node_modules/libpq": {
- "version": "1.8.14",
- "resolved": "https://registry.npmjs.org/libpq/-/libpq-1.8.14.tgz",
- "integrity": "sha512-/DDvQCiXP0KBMZ31U2mmURKaxoKt9kNqqgrSO2RuBKS+OJjw5b7uHi5jFoV8zPAUa2TNtq2XfcWL1OWDEyjwlg==",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "bindings": "1.5.0",
- "nan": "2.22.0"
- }
- },
"node_modules/lie": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+ "license": "MIT",
"dependencies": {
"immediate": "~3.0.5"
}
@@ -12626,7 +11630,7 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz",
"integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"extend": "^3.0.2",
"findup-sync": "^4.0.0",
@@ -12641,43 +11645,25 @@
"node": ">=10"
}
},
- "node_modules/liftup/node_modules/findup-sync": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz",
- "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==",
- "dev": true,
- "dependencies": {
- "detect-file": "^1.0.0",
- "is-glob": "^4.0.0",
- "micromatch": "^4.0.2",
- "resolve-dir": "^1.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
"node_modules/lines-and-columns": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/listenercount": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz",
- "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ=="
- },
- "node_modules/livereload-js": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz",
- "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==",
- "dev": true
+ "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==",
+ "license": "ISC"
},
"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"
},
@@ -12691,114 +11677,169 @@
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "license": "MIT"
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/lodash.defaults": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
- "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="
+ "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==",
+ "license": "MIT"
},
"node_modules/lodash.difference": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
- "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA=="
+ "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==",
+ "license": "MIT"
},
"node_modules/lodash.escaperegexp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
- "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw=="
+ "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==",
+ "license": "MIT"
},
"node_modules/lodash.flatten": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
- "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g=="
+ "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==",
+ "license": "MIT"
},
"node_modules/lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
- "dev": true
+ "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/lodash.groupby": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz",
- "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw=="
+ "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.includes": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+ "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
+ "license": "MIT"
},
"node_modules/lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
- "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
+ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
+ "license": "MIT"
},
"node_modules/lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
- "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
+ "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.",
+ "license": "MIT"
},
"node_modules/lodash.isfunction": {
"version": "3.0.9",
"resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
- "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw=="
+ "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isinteger": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+ "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
+ "license": "MIT"
},
"node_modules/lodash.isnil": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz",
- "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng=="
+ "integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isnumber": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+ "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
+ "license": "MIT"
},
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
- "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isstring": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
+ "license": "MIT"
},
"node_modules/lodash.isundefined": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz",
- "integrity": "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA=="
+ "integrity": "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==",
+ "license": "MIT"
},
"node_modules/lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
"integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
- "dev": true
+ "dev": true,
+ "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
+ "dev": true,
+ "license": "MIT"
},
"node_modules/lodash.mergewith": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
+ "license": "MIT"
},
"node_modules/lodash.union": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
- "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw=="
+ "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==",
+ "license": "MIT"
},
"node_modules/lodash.uniq": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
- "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="
+ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
+ "license": "MIT"
},
"node_modules/logform": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/logform/-/logform-2.5.1.tgz",
- "integrity": "sha512-9FyqAm9o9NKKfiAKfZoYo9bGXXuwMkxQiQttkT4YjjVtQVIQtK6LmVtlxmCaFswo6N4AfEkHqZTV0taDtPotNg==",
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz",
+ "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==",
+ "license": "MIT",
"dependencies": {
- "@colors/colors": "1.5.0",
+ "@colors/colors": "1.6.0",
"@types/triple-beam": "^1.3.2",
"fecha": "^4.2.0",
"ms": "^2.1.1",
"safe-stable-stringify": "^2.3.1",
"triple-beam": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
}
},
"node_modules/lru-cache": {
@@ -12806,14 +11847,16 @@
"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/luxon": {
- "version": "3.4.4",
- "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz",
- "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz",
+ "integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==",
+ "license": "MIT",
"engines": {
"node": ">=12"
}
@@ -12822,6 +11865,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "license": "MIT",
"dependencies": {
"semver": "^6.0.0"
},
@@ -12836,13 +11880,14 @@
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/make-iterator": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
"integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"kind-of": "^6.0.2"
},
@@ -12855,6 +11900,7 @@
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
"integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"tmpl": "1.0.5"
}
@@ -12863,7 +11909,7 @@
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
"integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -12877,104 +11923,11 @@
"node": ">= 0.4"
}
},
- "node_modules/maxmin": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-3.0.0.tgz",
- "integrity": "sha512-wcahMInmGtg/7c6a75fr21Ch/Ks1Tb+Jtoan5Ft4bAI0ZvJqyOw8kkM7e7p8hDSzY805vmxwHT50KcjGwKyJ0g==",
- "dev": true,
- "dependencies": {
- "chalk": "^4.1.0",
- "figures": "^3.2.0",
- "gzip-size": "^5.1.1",
- "pretty-bytes": "^5.3.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/maxmin/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/maxmin/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "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/maxmin/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/maxmin/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/maxmin/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/maxmin/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/md5-file": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-2.0.7.tgz",
- "integrity": "sha512-kWAICpJv8fIY0Ka/90iOX9nCJ407Fgj82ceWwcxi2HvVkKGHRMS/Y4caqBaju5skNYXiQohGUjwGZ7rVgzUhRw==",
- "dev": true
- },
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -12992,13 +11945,15 @@
"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
+ "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"
}
@@ -13007,6 +11962,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -13015,7 +11971,6 @@
"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",
@@ -13038,9 +11993,10 @@
}
},
"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==",
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
@@ -13049,6 +12005,7 @@
"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"
},
@@ -13056,11 +12013,21 @@
"node": ">= 0.6"
}
},
+ "node_modules/mime-types/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/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -13069,6 +12036,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "license": "MIT",
"engines": {
"node": ">=10"
},
@@ -13077,36 +12045,45 @@
}
},
"node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "10.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz",
+ "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==",
+ "dev": true,
+ "license": "ISC",
"dependencies": {
- "brace-expansion": "^1.1.7"
+ "@isaacs/brace-expansion": "^5.0.0"
},
"engines": {
- "node": "*"
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/minipass": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
- "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "license": "ISC",
"engines": {
- "node": ">=8"
+ "node": ">=16 || 14 >=14.17"
}
},
"node_modules/minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "license": "MIT",
"dependencies": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
@@ -13119,6 +12096,7 @@
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "license": "ISC",
"dependencies": {
"yallist": "^4.0.0"
},
@@ -13129,12 +12107,14 @@
"node_modules/minizlib/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "license": "ISC"
},
"node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "license": "MIT",
"bin": {
"mkdirp": "bin/cmd.js"
},
@@ -13145,20 +12125,23 @@
"node_modules/mkdirp-classic": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
- "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+ "license": "MIT"
},
"node_modules/moment": {
- "version": "2.29.4",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
- "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+ "version": "2.30.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
+ "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
+ "license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/moment-timezone": {
- "version": "0.5.43",
- "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz",
- "integrity": "sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==",
+ "version": "0.5.48",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz",
+ "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==",
+ "license": "MIT",
"dependencies": {
"moment": "^2.29.4"
},
@@ -13170,6 +12153,7 @@
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
"integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==",
+ "license": "MIT",
"dependencies": {
"basic-auth": "~2.0.1",
"debug": "2.6.9",
@@ -13185,6 +12169,7 @@
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
@@ -13192,12 +12177,14 @@
"node_modules/morgan/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT"
},
"node_modules/morgan/node_modules/on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
+ "license": "MIT",
"dependencies": {
"ee-first": "1.1.1"
},
@@ -13206,20 +12193,21 @@
}
},
"node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ "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/nan": {
- "version": "2.22.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz",
- "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==",
+ "version": "2.22.2",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz",
+ "integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==",
"license": "MIT"
},
"node_modules/nanoid": {
- "version": "3.3.8",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
- "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"funding": [
{
"type": "github",
@@ -13235,43 +12223,49 @@
}
},
"node_modules/napi-build-utils": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
- "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
+ "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
+ "license": "MIT"
},
"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
+ "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
+ "dev": true,
+ "license": "MIT"
},
"node_modules/ncp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
"integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==",
"dev": true,
+ "license": "MIT",
"bin": {
"ncp": "bin/ncp"
}
},
"node_modules/negotiator": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
+ "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/node-abi": {
- "version": "3.45.0",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.45.0.tgz",
- "integrity": "sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ==",
+ "version": "3.75.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz",
+ "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==",
+ "license": "MIT",
"dependencies": {
"semver": "^7.3.5"
},
@@ -13279,24 +12273,11 @@
"node": ">=10"
}
},
- "node_modules/node-abi/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/node-abi/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -13304,20 +12285,17 @@
"node": ">=10"
}
},
- "node_modules/node-abi/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- },
"node_modules/node-addon-api": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
- "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="
+ "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==",
+ "license": "MIT"
},
"node_modules/node-fetch": {
- "version": "2.6.12",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
- "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
@@ -13337,13 +12315,15 @@
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
"integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/node-releases": {
- "version": "2.0.13",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
- "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
- "dev": true
+ "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/nodeman": {
"version": "1.1.2",
@@ -13365,6 +12345,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+ "license": "ISC",
"dependencies": {
"abbrev": "1"
},
@@ -13379,35 +12360,30 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/npm-run-path": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
- "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "path-key": "^2.0.0"
+ "path-key": "^3.0.0"
},
"engines": {
- "node": ">=4"
- }
- },
- "node_modules/npm-run-path/node_modules/path-key": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
- "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
- "dev": true,
- "engines": {
- "node": ">=4"
+ "node": ">=8"
}
},
"node_modules/npmlog": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
"integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
+ "deprecated": "This package is no longer supported.",
+ "license": "ISC",
"dependencies": {
"are-we-there-yet": "^2.0.0",
"console-control-strings": "^1.1.0",
@@ -13416,22 +12392,24 @@
}
},
"node_modules/oauth": {
- "version": "0.9.15",
- "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
- "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA=="
+ "version": "0.10.2",
+ "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.10.2.tgz",
+ "integrity": "sha512-JtFnB+8nxDEXgNyniwz573xxbKSOu3R8D40xQKqcjwJ2CDkYqUDI53o6IuzDJBx60Z8VKCm271+t8iFjakrl8Q==",
+ "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.3",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
- "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -13444,7 +12422,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
"integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"array-each": "^1.0.1",
"array-slice": "^1.0.0",
@@ -13459,7 +12437,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
"integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"for-own": "^1.0.0",
"make-iterator": "^1.0.0"
@@ -13472,7 +12450,7 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
"integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"isobject": "^3.0.1"
},
@@ -13480,11 +12458,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/obuf": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
- "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg=="
- },
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@@ -13501,6 +12474,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -13509,6 +12483,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "license": "ISC",
"dependencies": {
"wrappy": "1"
}
@@ -13517,6 +12492,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
"integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
+ "license": "MIT",
"dependencies": {
"fn.name": "1.x.x"
}
@@ -13526,6 +12502,7 @@
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"mimic-fn": "^2.1.0"
},
@@ -13541,58 +12518,33 @@
"resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz",
"integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==",
"dev": true,
+ "license": "MIT",
"peer": true
},
"node_modules/optionator": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
- "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@aashutoshrathi/word-wrap": "^1.2.3",
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
"levn": "^0.4.1",
"prelude-ls": "^1.2.1",
- "type-check": "^0.4.0"
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
},
"engines": {
"node": ">= 0.8.0"
}
},
- "node_modules/os-homedir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
- "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/osenv": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
- "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
- "dev": true,
- "dependencies": {
- "os-homedir": "^1.0.0",
- "os-tmpdir": "^1.0.0"
- }
- },
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"yocto-queue": "^0.1.0"
},
@@ -13608,6 +12560,7 @@
"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"
},
@@ -13618,25 +12571,48 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/p-map": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz",
+ "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
},
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0"
+ },
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
- "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "license": "(MIT AND Zlib)"
},
"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"
},
@@ -13648,7 +12624,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
"integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"is-absolute": "^1.0.0",
"map-cache": "^0.2.0",
@@ -13663,6 +12639,7 @@
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
@@ -13680,7 +12657,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
"integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -13688,12 +12665,14 @@
"node_modules/parse-srcset": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
- "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q=="
+ "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==",
+ "license": "MIT"
},
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -13720,6 +12699,7 @@
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/passport-google-oauth2/-/passport-google-oauth2-0.2.0.tgz",
"integrity": "sha512-62EdPtbfVdc55nIXi0p1WOa/fFMM8v/M8uQGnbcXA4OexZWCnfsEi3wo2buag+Is5oqpuHzOtI64JpHk0Xi5RQ==",
+ "license": "MIT",
"dependencies": {
"passport-oauth2": "^1.1.2"
}
@@ -13728,6 +12708,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz",
"integrity": "sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==",
+ "license": "MIT",
"dependencies": {
"passport-oauth2": "1.x.x"
},
@@ -13747,12 +12728,13 @@
}
},
"node_modules/passport-oauth2": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.7.0.tgz",
- "integrity": "sha512-j2gf34szdTF2Onw3+76alNnaAExlUmHvkc7cL+cmaS5NzHzDP/BvFHJruueQ9XAeNOdpI+CH+PWid8RA7KCwAQ==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.8.0.tgz",
+ "integrity": "sha512-cjsQbOrXIDE4P8nNb3FQRCCmJJ/utnFKEz2NX209f7KOHPoX18gF7gBzBbLLsj2/je4KrgiwLLGjf0lm9rtTBA==",
+ "license": "MIT",
"dependencies": {
"base64url": "3.x.x",
- "oauth": "0.9.x",
+ "oauth": "0.10.x",
"passport-strategy": "1.x.x",
"uid2": "0.0.x",
"utils-merge": "1.x.x"
@@ -13777,6 +12759,7 @@
"version": "0.12.7",
"resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
"integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==",
+ "license": "MIT",
"dependencies": {
"process": "^0.11.1",
"util": "^0.10.3"
@@ -13787,6 +12770,7 @@
"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"
}
@@ -13795,6 +12779,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -13804,6 +12789,7 @@
"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"
}
@@ -13811,13 +12797,14 @@
"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=="
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "license": "MIT"
},
"node_modules/path-root": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
"integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"path-root-regex": "^0.1.0"
},
@@ -13829,11 +12816,38 @@
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
"integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
+ "node_modules/path-scurry": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
+ "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz",
+ "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
"node_modules/path-to-regexp": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
@@ -13845,6 +12859,7 @@
"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"
}
@@ -13855,22 +12870,22 @@
"integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg=="
},
"node_modules/pg": {
- "version": "8.14.1",
- "resolved": "https://registry.npmjs.org/pg/-/pg-8.14.1.tgz",
- "integrity": "sha512-0TdbqfjwIun9Fm/r89oB7RFQ0bLgduAhiIqIXOsyKoiC/L54DbuAAzIEN/9Op0f1Po9X7iCPXGoa/Ah+2aI8Xw==",
+ "version": "8.16.3",
+ "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz",
+ "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==",
"license": "MIT",
"dependencies": {
- "pg-connection-string": "^2.7.0",
- "pg-pool": "^3.8.0",
- "pg-protocol": "^1.8.0",
- "pg-types": "^2.1.0",
- "pgpass": "1.x"
+ "pg-connection-string": "^2.9.1",
+ "pg-pool": "^3.10.1",
+ "pg-protocol": "^1.10.3",
+ "pg-types": "2.2.0",
+ "pgpass": "1.0.5"
},
"engines": {
- "node": ">= 8.0.0"
+ "node": ">= 16.0.0"
},
"optionalDependencies": {
- "pg-cloudflare": "^1.1.1"
+ "pg-cloudflare": "^1.2.7"
},
"peerDependencies": {
"pg-native": ">=3.0.1"
@@ -13882,134 +12897,47 @@
}
},
"node_modules/pg-cloudflare": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz",
- "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==",
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz",
+ "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==",
+ "license": "MIT",
"optional": true
},
"node_modules/pg-connection-string": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.7.0.tgz",
- "integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==",
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz",
+ "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==",
"license": "MIT"
},
"node_modules/pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
+ "license": "ISC",
"engines": {
"node": ">=4.0.0"
}
},
- "node_modules/pg-native": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/pg-native/-/pg-native-3.3.0.tgz",
- "integrity": "sha512-8GHZOx20B/wceRebDG2KK2KZbmDmwkoLvWz4X7BQIF1fjRLCNp48oHsEHSk1lTw36GFGMksLiJ3qZcmSAgVdYA==",
- "license": "MIT",
- "dependencies": {
- "libpq": "1.8.14",
- "pg-types": "^2.1.0"
- }
- },
- "node_modules/pg-native/node_modules/pg-types": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
- "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
- "license": "MIT",
- "dependencies": {
- "pg-int8": "1.0.1",
- "postgres-array": "~2.0.0",
- "postgres-bytea": "~1.0.0",
- "postgres-date": "~1.0.4",
- "postgres-interval": "^1.1.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/pg-native/node_modules/postgres-array": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
- "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/pg-native/node_modules/postgres-bytea": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
- "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/pg-native/node_modules/postgres-date": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
- "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/pg-native/node_modules/postgres-interval": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
- "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
- "license": "MIT",
- "dependencies": {
- "xtend": "^4.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/pg-numeric": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz",
- "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==",
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/pg-pool": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.8.0.tgz",
- "integrity": "sha512-VBw3jiVm6ZOdLBTIcXLNdSotb6Iy3uOCwDGFAksZCXmi10nyRvnP2v3jl4d+IsLYRyXf6o9hIm/ZtUzlByNUdw==",
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz",
+ "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==",
"license": "MIT",
"peerDependencies": {
"pg": ">=8.0"
}
},
"node_modules/pg-protocol": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.8.0.tgz",
- "integrity": "sha512-jvuYlEkL03NRvOoyoRktBK7+qU5kOvlAwvmrH8sr3wbLrOdVWsRxQfz8mMy9sZFsqJ1hEWNfdWKI4SAmoL+j7g==",
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz",
+ "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==",
"license": "MIT"
},
"node_modules/pg-types": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.1.tgz",
- "integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==",
- "dependencies": {
- "pg-int8": "1.0.1",
- "pg-numeric": "1.0.2",
- "postgres-array": "~3.0.1",
- "postgres-bytea": "~3.0.0",
- "postgres-date": "~2.0.1",
- "postgres-interval": "^3.0.0",
- "postgres-range": "^1.1.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/pg/node_modules/pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
+ "license": "MIT",
"dependencies": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
@@ -14021,59 +12949,26 @@
"node": ">=4"
}
},
- "node_modules/pg/node_modules/postgres-array": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
- "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/pg/node_modules/postgres-bytea": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
- "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/pg/node_modules/postgres-date": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
- "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/pg/node_modules/postgres-interval": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
- "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
- "dependencies": {
- "xtend": "^4.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/pgpass": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
+ "license": "MIT",
"dependencies": {
"split2": "^4.1.0"
}
},
"node_modules/picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+ "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"
},
@@ -14081,20 +12976,12 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/pify": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
- "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/pirates": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
- "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
+ "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 6"
}
@@ -14104,6 +12991,7 @@
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"find-up": "^4.0.0"
},
@@ -14116,6 +13004,7 @@
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
@@ -14129,6 +13018,7 @@
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-locate": "^4.1.0"
},
@@ -14141,6 +13031,7 @@
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-try": "^2.0.0"
},
@@ -14156,6 +13047,7 @@
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-limit": "^2.2.0"
},
@@ -14164,9 +13056,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.31",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
- "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
"funding": [
{
"type": "opencollective",
@@ -14181,66 +13073,67 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "nanoid": "^3.3.6",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postgres-array": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz",
- "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
+ "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
+ "license": "MIT",
"engines": {
- "node": ">=12"
+ "node": ">=4"
}
},
"node_modules/postgres-bytea": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz",
- "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==",
- "dependencies": {
- "obuf": "~1.1.2"
- },
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
+ "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
+ "license": "MIT",
"engines": {
- "node": ">= 6"
+ "node": ">=0.10.0"
}
},
"node_modules/postgres-date": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.0.1.tgz",
- "integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
+ "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
+ "license": "MIT",
"engines": {
- "node": ">=12"
+ "node": ">=0.10.0"
}
},
"node_modules/postgres-interval": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz",
- "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
+ "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "^4.0.0"
+ },
"engines": {
- "node": ">=12"
+ "node": ">=0.10.0"
}
},
- "node_modules/postgres-range": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.3.tgz",
- "integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g=="
- },
"node_modules/prebuild-install": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
- "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
+ "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
+ "license": "MIT",
"dependencies": {
"detect-libc": "^2.0.0",
"expand-template": "^2.0.3",
"github-from-package": "0.0.0",
"minimist": "^1.2.3",
"mkdirp-classic": "^0.5.3",
- "napi-build-utils": "^1.0.1",
+ "napi-build-utils": "^2.0.0",
"node-abi": "^3.3.0",
"pump": "^3.0.0",
"rc": "^1.2.7",
@@ -14255,32 +13148,40 @@
"node": ">=10"
}
},
+ "node_modules/prebuild-install/node_modules/chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+ "license": "ISC"
+ },
+ "node_modules/prebuild-install/node_modules/tar-fs": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz",
+ "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==",
+ "license": "MIT",
+ "dependencies": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.1.4"
+ }
+ },
"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-bytes": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
- "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
- "dev": true,
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/pretty-format": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz",
"integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jest/schemas": "^28.1.3",
"ansi-regex": "^5.0.1",
@@ -14296,6 +13197,7 @@
"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"
},
@@ -14307,6 +13209,7 @@
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+ "license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
@@ -14314,12 +13217,14 @@
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
- "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "license": "MIT"
},
"node_modules/promise": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "license": "MIT",
"dependencies": {
"asap": "~2.0.3"
}
@@ -14329,6 +13234,7 @@
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
"integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"kleur": "^3.0.3",
"sisteransi": "^1.0.5"
@@ -14341,6 +13247,7 @@
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "license": "MIT",
"dependencies": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
@@ -14352,7 +13259,8 @@
"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=="
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
},
"node_modules/pug": {
"version": "3.0.3",
@@ -14407,6 +13315,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz",
"integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==",
+ "license": "MIT",
"dependencies": {
"constantinople": "^4.0.1",
"jstransformer": "1.0.0",
@@ -14419,6 +13328,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz",
"integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==",
+ "license": "MIT",
"dependencies": {
"character-parser": "^2.2.0",
"is-expression": "^4.0.0",
@@ -14429,6 +13339,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz",
"integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==",
+ "license": "MIT",
"dependencies": {
"pug-error": "^2.0.0",
"pug-walk": "^2.0.0"
@@ -14438,6 +13349,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz",
"integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==",
+ "license": "MIT",
"dependencies": {
"object-assign": "^4.1.1",
"pug-walk": "^2.0.0"
@@ -14447,6 +13359,7 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz",
"integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==",
+ "license": "MIT",
"dependencies": {
"pug-error": "^2.0.0",
"token-stream": "1.0.0"
@@ -14462,6 +13375,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz",
"integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==",
+ "license": "MIT",
"dependencies": {
"pug-error": "^2.0.0"
}
@@ -14469,22 +13383,25 @@
"node_modules/pug-walk": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz",
- "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ=="
+ "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==",
+ "license": "MIT"
},
"node_modules/pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
+ "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
+ "license": "MIT",
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"node_modules/punycode": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
- "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+ "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"
}
@@ -14522,17 +13439,14 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ]
- },
- "node_modules/queue-tick": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
- "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="
+ ],
+ "license": "MIT"
},
"node_modules/random-bytes": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
"integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -14561,19 +13475,11 @@
"node": ">= 0.8"
}
},
- "node_modules/raw-body/node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
"dependencies": {
"deep-extend": "^0.6.0",
"ini": "~1.3.0",
@@ -14588,20 +13494,23 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-is": {
- "version": "18.2.0",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
- "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
- "dev": true
+ "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/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@@ -14615,14 +13524,16 @@
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz",
"integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==",
+ "license": "Apache-2.0",
"dependencies": {
"minimatch": "^5.1.0"
}
},
"node_modules/readdir-glob/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
@@ -14631,6 +13542,7 @@
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
@@ -14643,6 +13555,7 @@
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"picomatch": "^2.2.1"
},
@@ -14654,7 +13567,7 @@
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz",
"integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"resolve": "^1.9.0"
},
@@ -14663,29 +13576,35 @@
}
},
"node_modules/redis": {
- "version": "4.6.7",
- "resolved": "https://registry.npmjs.org/redis/-/redis-4.6.7.tgz",
- "integrity": "sha512-KrkuNJNpCwRm5vFJh0tteMxW8SaUzkm5fBH7eL5hd/D0fAkzvapxbfGPP/r+4JAXdQuX7nebsBkBqA2RHB7Usw==",
+ "version": "4.7.1",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-4.7.1.tgz",
+ "integrity": "sha512-S1bJDnqLftzHXHP8JsT5II/CtHWQrASX5K96REjWjlmWKrviSOLWmM7QnRLstAWsu1VBBV1ffV6DzCvxNP0UJQ==",
+ "license": "MIT",
+ "workspaces": [
+ "./packages/*"
+ ],
"dependencies": {
"@redis/bloom": "1.2.0",
- "@redis/client": "1.5.8",
- "@redis/graph": "1.1.0",
- "@redis/json": "1.0.4",
- "@redis/search": "1.1.3",
- "@redis/time-series": "1.0.4"
+ "@redis/client": "1.6.1",
+ "@redis/graph": "1.1.1",
+ "@redis/json": "1.0.7",
+ "@redis/search": "1.2.0",
+ "@redis/time-series": "1.1.0"
}
},
"node_modules/regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
"integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/regenerate-unicode-properties": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz",
- "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==",
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz",
+ "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"regenerate": "^1.4.2"
},
@@ -14693,40 +13612,27 @@
"node": ">=4"
}
},
- "node_modules/regenerator-runtime": {
- "version": "0.13.11",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
- "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
- "dev": true
- },
- "node_modules/regenerator-transform": {
- "version": "0.15.1",
- "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz",
- "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==",
- "dev": true,
- "dependencies": {
- "@babel/runtime": "^7.8.4"
- }
- },
"node_modules/regexp-tree": {
"version": "0.1.27",
"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz",
"integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==",
"dev": true,
+ "license": "MIT",
"bin": {
"regexp-tree": "bin/regexp-tree"
}
},
"node_modules/regexpu-core": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz",
- "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==",
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
+ "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/regjsgen": "^0.8.0",
"regenerate": "^1.4.2",
- "regenerate-unicode-properties": "^10.1.0",
- "regjsparser": "^0.9.1",
+ "regenerate-unicode-properties": "^10.2.0",
+ "regjsgen": "^0.8.0",
+ "regjsparser": "^0.12.0",
"unicode-match-property-ecmascript": "^2.0.0",
"unicode-match-property-value-ecmascript": "^2.1.0"
},
@@ -14734,25 +13640,37 @@
"node": ">=4"
}
},
- "node_modules/regjsparser": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
- "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==",
+ "node_modules/regjsgen": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz",
+ "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
"dev": true,
+ "license": "MIT"
+ },
+ "node_modules/regjsparser": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz",
+ "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
- "jsesc": "~0.5.0"
+ "jsesc": "~3.0.2"
},
"bin": {
"regjsparser": "bin/parser"
}
},
"node_modules/regjsparser/node_modules/jsesc": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
- "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+ "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
"dev": true,
+ "license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
}
},
"node_modules/require-directory": {
@@ -14760,22 +13678,27 @@
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/resolve": {
- "version": "1.22.2",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
- "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "license": "MIT",
"dependencies": {
- "is-core-module": "^2.11.0",
+ "is-core-module": "^2.16.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -14785,6 +13708,7 @@
"resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
"integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"resolve-from": "^5.0.0"
},
@@ -14797,6 +13721,7 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -14805,7 +13730,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
"integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
- "dev": true,
+ "license": "MIT",
"dependencies": {
"expand-tilde": "^2.0.0",
"global-modules": "^1.0.0"
@@ -14819,6 +13744,7 @@
"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"
}
@@ -14828,29 +13754,37 @@
"resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz",
"integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "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==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz",
+ "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==",
+ "dev": true,
+ "license": "ISC",
"dependencies": {
- "glob": "^7.1.3"
+ "glob": "^11.0.0",
+ "package-json-from-dist": "^1.0.0"
},
"bin": {
- "rimraf": "bin.js"
+ "rimraf": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -14859,7 +13793,8 @@
"node_modules/rndm": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/rndm/-/rndm-1.2.0.tgz",
- "integrity": "sha512-fJhQQI5tLrQvYIYFpOnFinzv9dwmR7hRnUz1XqP3OJ1jIweTNOd6aTO4jwQSgcBSFUB+/KHJxuGneime+FdzOw=="
+ "integrity": "sha512-fJhQQI5tLrQvYIYFpOnFinzv9dwmR7hRnUz1XqP3OJ1jIweTNOd6aTO4jwQSgcBSFUB+/KHJxuGneime+FdzOw==",
+ "license": "MIT"
},
"node_modules/run-parallel": {
"version": "1.2.0",
@@ -14880,34 +13815,56 @@
"url": "https://feross.org/support"
}
],
+ "license": "MIT",
"dependencies": {
"queue-microtask": "^1.2.2"
}
},
- "node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ "node_modules/rxjs": {
+ "version": "7.8.2",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
+ "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
},
- "node_modules/safe-json-parse": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz",
- "integrity": "sha512-o0JmTu17WGUaUOHa1l0FPGXKBfijbxK6qoHzlkihsDXxzBHvJcA7zgviKR92Xs841rX9pK16unfphLq0/KqX7A==",
- "dev": true
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
},
"node_modules/safe-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz",
"integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"regexp-tree": "~0.1.1"
}
},
"node_modules/safe-stable-stringify": {
- "version": "2.4.3",
- "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz",
- "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
+ "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
+ "license": "MIT",
"engines": {
"node": ">=10"
}
@@ -14915,12 +13872,13 @@
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
},
"node_modules/sanitize-html": {
- "version": "2.14.0",
- "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.14.0.tgz",
- "integrity": "sha512-CafX+IUPxZshXqqRaG9ZClSlfPVjSxI0td7n07hk8QO2oO+9JDnlcL8iM8TWeOXOIBFgIOx6zioTzM53AOMn3g==",
+ "version": "2.17.0",
+ "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.17.0.tgz",
+ "integrity": "sha512-dLAADUSS8rBwhaevT12yCezvioCA+bmUTPH/u57xKPT8d++voeYE6HeluA/bPbQ15TwDBG2ii+QZIEmYx8VdxA==",
"license": "MIT",
"dependencies": {
"deepmerge": "^4.2.2",
@@ -14931,21 +13889,11 @@
"postcss": "^8.3.11"
}
},
- "node_modules/sanitize-html/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==",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/sanitize-html/node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -14954,6 +13902,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
"integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
+ "license": "ISC",
"dependencies": {
"xmlchars": "^2.2.0"
},
@@ -14966,6 +13915,7 @@
"resolved": "https://registry.npmjs.org/segfault-handler/-/segfault-handler-1.3.0.tgz",
"integrity": "sha512-p7kVHo+4uoYkr0jmIiTBthwV5L2qmWtben/KDunDZ834mbos+tY+iO0//HpAJpOFSQZZ+wxKWuRo4DxV02B7Lg==",
"hasInstallScript": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"bindings": "^1.2.1",
"nan": "^2.14.0"
@@ -14975,6 +13925,7 @@
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
@@ -15027,12 +13978,6 @@
"node": ">= 0.8"
}
},
- "node_modules/send/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/serve-static": {
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
@@ -15051,23 +13996,27 @@
"node_modules/set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
- "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
+ "license": "ISC"
},
"node_modules/setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
- "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+ "license": "MIT"
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "license": "ISC"
},
"node_modules/sharp": {
"version": "0.32.6",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz",
"integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==",
"hasInstallScript": true,
+ "license": "Apache-2.0",
"dependencies": {
"color": "^4.2.3",
"detect-libc": "^2.0.2",
@@ -15085,29 +14034,17 @@
"url": "https://opencollective.com/libvips"
}
},
- "node_modules/sharp/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/sharp/node_modules/node-addon-api": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
- "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA=="
+ "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==",
+ "license": "MIT"
},
"node_modules/sharp/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -15115,36 +14052,12 @@
"node": ">=10"
}
},
- "node_modules/sharp/node_modules/tar-fs": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz",
- "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==",
- "dependencies": {
- "mkdirp-classic": "^0.5.2",
- "pump": "^3.0.0",
- "tar-stream": "^3.1.5"
- }
- },
- "node_modules/sharp/node_modules/tar-stream": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz",
- "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==",
- "dependencies": {
- "b4a": "^1.6.4",
- "fast-fifo": "^1.2.0",
- "streamx": "^2.15.0"
- }
- },
- "node_modules/sharp/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
- },
"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"
},
@@ -15157,10 +14070,24 @@
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
+ "node_modules/shell-quote": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz",
+ "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
@@ -15234,9 +14161,17 @@
}
},
"node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+ "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/simple-concat": {
"version": "1.0.1",
@@ -15255,7 +14190,8 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ]
+ ],
+ "license": "MIT"
},
"node_modules/simple-get": {
"version": "4.0.1",
@@ -15275,6 +14211,7 @@
"url": "https://feross.org/support"
}
],
+ "license": "MIT",
"dependencies": {
"decompress-response": "^6.0.0",
"once": "^1.3.1",
@@ -15285,6 +14222,7 @@
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+ "license": "MIT",
"dependencies": {
"is-arrayish": "^0.3.1"
}
@@ -15292,19 +14230,22 @@
"node_modules/simple-swizzle/node_modules/is-arrayish": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
- "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+ "license": "MIT"
},
"node_modules/sisteransi": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
"integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"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"
}
@@ -15313,6 +14254,7 @@
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
"integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==",
+ "license": "MIT",
"engines": {
"node": ">=8.0.0"
}
@@ -15345,10 +14287,28 @@
"ws": "~8.17.1"
}
},
+ "node_modules/socket.io-adapter/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
"node_modules/socket.io-parser": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
+ "license": "MIT",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
@@ -15357,19 +14317,55 @@
"node": ">=10.0.0"
}
},
+ "node_modules/socket.io-parser/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socket.io/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
@@ -15379,6 +14375,7 @@
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
"integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
@@ -15388,20 +14385,23 @@
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "license": "ISC",
"engines": {
"node": ">= 10.x"
}
},
"node_modules/sprintf-js": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
- "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
- "dev": true
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true,
+ "license": "BSD-3-Clause"
},
"node_modules/stack-trace": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
"integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
+ "license": "MIT",
"engines": {
"node": "*"
}
@@ -15411,6 +14411,7 @@
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
"integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"escape-string-regexp": "^2.0.0"
},
@@ -15423,6 +14424,7 @@
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -15431,60 +14433,39 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
- "node_modules/stream-buffers": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz",
- "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==",
- "dev": true,
- "engines": {
- "node": ">= 0.10.0"
- }
- },
"node_modules/streamx": {
- "version": "2.15.5",
- "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.5.tgz",
- "integrity": "sha512-9thPGMkKC2GctCzyCUjME3yR03x2xNo0GPKGkRw2UMYN+gqWa9uqpyNWhmsNCutU5zHmkUum0LsCRQTXUgUCAg==",
+ "version": "2.22.1",
+ "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz",
+ "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==",
+ "license": "MIT",
"dependencies": {
- "fast-fifo": "^1.1.0",
- "queue-tick": "^1.0.1"
+ "fast-fifo": "^1.3.2",
+ "text-decoder": "^1.1.0"
+ },
+ "optionalDependencies": {
+ "bare-events": "^2.2.0"
}
},
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "license": "MIT",
"dependencies": {
"safe-buffer": "~5.2.0"
}
},
- "node_modules/string_decoder/node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
"node_modules/string-length": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
"integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"char-regex": "^1.0.2",
"strip-ansi": "^6.0.0"
@@ -15493,16 +14474,31 @@
"node": ">=10"
}
},
- "node_modules/string-template": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz",
- "integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==",
- "dev": true
- },
"node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@@ -15512,10 +14508,61 @@
"node": ">=8"
}
},
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-width/node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/string-width/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
@@ -15528,6 +14575,7 @@
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
"integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -15537,6 +14585,7 @@
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -15546,6 +14595,7 @@
"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"
},
@@ -15554,20 +14604,41 @@
}
},
"node_modules/strnum": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
- "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz",
+ "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/subarg": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
+ "integrity": "sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.1.0"
+ }
},
"node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "has-flag": "^3.0.0"
+ "has-flag": "^4.0.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/supports-hyperlinks": {
@@ -15575,6 +14646,7 @@
"resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
"integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-flag": "^4.0.0",
"supports-color": "^7.0.0"
@@ -15583,20 +14655,12 @@
"node": ">=8"
}
},
- "node_modules/supports-hyperlinks/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/supports-hyperlinks/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -15608,6 +14672,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -15620,6 +14685,7 @@
"resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.8.tgz",
"integrity": "sha512-VPvil1+JRpmJ55CgAtn8DIcpBs0bL5L3q5bVQvF4tAW/k/9JYSj7dCpaYCAv5rufe0vcCbBRQXGvzpkWjvLklQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"commander": "6.2.0",
"doctrine": "3.0.0",
@@ -15639,7 +14705,9 @@
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
"dev": true,
+ "license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -15655,11 +14723,25 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/swagger-jsdoc/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/swagger-parser": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-10.0.3.tgz",
"integrity": "sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@apidevtools/swagger-parser": "10.0.3"
},
@@ -15685,25 +14767,35 @@
}
},
"node_modules/tar-fs": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
- "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz",
+ "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==",
+ "license": "MIT",
"dependencies": {
- "chownr": "^1.1.1",
- "mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
- "tar-stream": "^2.1.4"
+ "tar-stream": "^3.1.5"
+ },
+ "optionalDependencies": {
+ "bare-fs": "^4.0.1",
+ "bare-path": "^3.0.0"
}
},
- "node_modules/tar-fs/node_modules/chownr": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
- "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+ "node_modules/tar-fs/node_modules/tar-stream": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz",
+ "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==",
+ "license": "MIT",
+ "dependencies": {
+ "b4a": "^1.6.4",
+ "fast-fifo": "^1.2.0",
+ "streamx": "^2.15.0"
+ }
},
"node_modules/tar-stream": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "license": "MIT",
"dependencies": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
@@ -15715,16 +14807,27 @@
"node": ">=6"
}
},
+ "node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/tar/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "license": "ISC"
},
"node_modules/terminal-link": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
"integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ansi-escapes": "^4.2.1",
"supports-hyperlinks": "^2.0.0"
@@ -15736,11 +14839,49 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/terser": {
+ "version": "5.43.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz",
+ "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.14.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/terser/node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
"node_modules/test-exclude": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
"integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"@istanbuljs/schema": "^0.1.2",
"glob": "^7.1.4",
@@ -15750,70 +14891,89 @@
"node": ">=8"
}
},
+ "node_modules/test-exclude/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "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/test-exclude/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/text-decoder": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz",
+ "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "b4a": "^1.6.4"
+ }
+ },
"node_modules/text-hex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
- "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
+ "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==",
+ "license": "MIT"
},
"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
- },
- "node_modules/tiny-lr": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz",
- "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==",
"dev": true,
- "dependencies": {
- "body": "^5.1.0",
- "debug": "^3.1.0",
- "faye-websocket": "~0.10.0",
- "livereload-js": "^2.3.0",
- "object-assign": "^4.1.0",
- "qs": "^6.4.0"
- }
+ "license": "MIT"
},
- "node_modules/tiny-lr/node_modules/debug": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
- "dev": true,
- "dependencies": {
- "ms": "^2.1.1"
- }
+ "node_modules/tinymce": {
+ "version": "7.9.1",
+ "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-7.9.1.tgz",
+ "integrity": "sha512-zaOHwmiP1EqTeLRXAvVriDb00JYnfEjWGPdKEuac7MiZJ5aiDMZ4Unc98Gmajn+PBljOmO1GKV6G0KwWn3+k8A==",
+ "license": "GPL-2.0-or-later"
},
"node_modules/tmp": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
- "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
- "dependencies": {
- "rimraf": "^3.0.0"
- },
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
+ "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==",
+ "license": "MIT",
"engines": {
- "node": ">=8.17.0"
+ "node": ">=14.14"
}
},
"node_modules/tmpl": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
"integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
- "dev": true
- },
- "node_modules/to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
- "engines": {
- "node": ">=4"
- }
+ "dev": true,
+ "license": "BSD-3-Clause"
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
@@ -15826,6 +14986,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "license": "MIT",
"engines": {
"node": ">=0.6"
}
@@ -15833,25 +14994,39 @@
"node_modules/token-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz",
- "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg=="
+ "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==",
+ "license": "MIT"
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT"
},
"node_modules/traverse": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
"integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==",
+ "license": "MIT/X11",
"engines": {
"node": "*"
}
},
+ "node_modules/tree-kill": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "tree-kill": "cli.js"
+ }
+ },
"node_modules/triple-beam": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
"integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==",
+ "license": "MIT",
"engines": {
"node": ">= 14.0.0"
}
@@ -15861,6 +15036,7 @@
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz",
"integrity": "sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"bs-logger": "0.x",
"fast-json-stable-stringify": "2.x",
@@ -15899,26 +15075,12 @@
}
}
},
- "node_modules/ts-jest/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/ts-jest/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
+ "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -15926,17 +15088,12 @@
"node": ">=10"
}
},
- "node_modules/ts-jest/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"node_modules/ts-node": {
- "version": "10.9.1",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
- "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
+ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
@@ -15987,6 +15144,7 @@
"integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
"deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"@babel/code-frame": "^7.0.0",
"builtin-modules": "^1.1.1",
@@ -16012,26 +15170,116 @@
"typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev"
}
},
+ "node_modules/tslint/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/tslint/node_modules/argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"sprintf-js": "~1.0.2"
}
},
+ "node_modules/tslint/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/tslint/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/tslint/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/tslint/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tslint/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/tslint/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/tslint/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
},
"node_modules/tslint/node_modules/js-yaml": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
@@ -16040,11 +15288,25 @@
"js-yaml": "bin/js-yaml.js"
}
},
+ "node_modules/tslint/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/tslint/node_modules/mkdirp": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"minimist": "^1.2.6"
},
@@ -16057,27 +15319,37 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true,
+ "license": "ISC",
"bin": {
"semver": "bin/semver"
}
},
- "node_modules/tslint/node_modules/sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
- "dev": true
+ "node_modules/tslint/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
},
"node_modules/tslint/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
+ "dev": true,
+ "license": "0BSD"
},
"node_modules/tslint/node_modules/tsutils": {
"version": "2.29.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
"integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"tslib": "^1.8.1"
},
@@ -16089,6 +15361,7 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz",
"integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==",
+ "license": "MIT",
"engines": {
"node": ">=0.6.x"
}
@@ -16098,6 +15371,7 @@
"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"
},
@@ -16112,12 +15386,14 @@
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "dev": true
+ "dev": true,
+ "license": "0BSD"
},
"node_modules/tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "license": "Apache-2.0",
"dependencies": {
"safe-buffer": "^5.0.1"
},
@@ -16130,6 +15406,7 @@
"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"
},
@@ -16142,6 +15419,7 @@
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -16151,6 +15429,7 @@
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
"dev": true,
+ "license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=10"
},
@@ -16162,6 +15441,7 @@
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "license": "MIT",
"dependencies": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
@@ -16175,6 +15455,7 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"dev": true,
+ "license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -16184,9 +15465,10 @@
}
},
"node_modules/uglify-js": {
- "version": "3.17.4",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
- "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
+ "version": "3.19.3",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
+ "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==",
+ "license": "BSD-2-Clause",
"bin": {
"uglifyjs": "bin/uglifyjs"
},
@@ -16198,6 +15480,7 @@
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
"integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
+ "license": "MIT",
"dependencies": {
"random-bytes": "~1.0.0"
},
@@ -16208,35 +15491,30 @@
"node_modules/uid2": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz",
- "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA=="
+ "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==",
+ "license": "MIT"
},
"node_modules/unc-path-regex": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
"integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==",
- "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/underscore.string": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz",
- "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==",
- "dev": true,
- "dependencies": {
- "sprintf-js": "^1.1.1",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": "*"
- }
+ "node_modules/undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+ "license": "MIT"
},
"node_modules/unicode-canonical-property-names-ecmascript": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
- "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
+ "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -16246,6 +15524,7 @@
"resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
"integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"unicode-canonical-property-names-ecmascript": "^2.0.0",
"unicode-property-aliases-ecmascript": "^2.0.0"
@@ -16255,10 +15534,11 @@
}
},
"node_modules/unicode-match-property-value-ecmascript": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz",
- "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz",
+ "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -16268,15 +15548,17 @@
"resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
"integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/universalify": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
- "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 10.0.0"
}
@@ -16294,6 +15576,7 @@
"version": "0.10.14",
"resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz",
"integrity": "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==",
+ "license": "MIT",
"dependencies": {
"big-integer": "^1.6.17",
"binary": "~0.3.0",
@@ -16310,12 +15593,14 @@
"node_modules/unzipper/node_modules/bluebird": {
"version": "3.4.7",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz",
- "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA=="
+ "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==",
+ "license": "MIT"
},
"node_modules/unzipper/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
@@ -16326,18 +15611,25 @@
"util-deprecate": "~1.0.1"
}
},
+ "node_modules/unzipper/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
"node_modules/unzipper/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/update-browserslist-db": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
- "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
+ "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": [
{
@@ -16353,9 +15645,10 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
},
"bin": {
"update-browserslist-db": "cli.js"
@@ -16369,23 +15662,16 @@
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
}
},
- "node_modules/uri-path": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz",
- "integrity": "sha512-8pMuAn4KacYdGMkFaoQARicp4HSw24/DHOVKWqVRJ8LhhAwPPFpdGvdL9184JVmUwe7vz7Z9n6IqI6t5n2ELdg==",
- "dev": true,
- "engines": {
- "node": ">= 0.10"
- }
- },
"node_modules/util": {
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
"integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+ "license": "MIT",
"dependencies": {
"inherits": "2.0.3"
}
@@ -16393,25 +15679,33 @@
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
},
"node_modules/util/node_modules/inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw=="
+ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+ "license": "ISC"
},
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/uuid": {
- "version": "8.3.2",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
- "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+ "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "license": "MIT",
"bin": {
"uuid": "dist/bin/uuid"
}
@@ -16420,38 +15714,38 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/v8-to-istanbul": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz",
- "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==",
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
+ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.12",
"@types/istanbul-lib-coverage": "^2.0.1",
- "convert-source-map": "^1.6.0"
+ "convert-source-map": "^2.0.0"
},
"engines": {
"node": ">=10.12.0"
}
},
"node_modules/v8flags": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz",
- "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==",
- "dev": true,
- "dependencies": {
- "homedir-polyfill": "^1.0.1"
- },
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz",
+ "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==",
+ "license": "MIT",
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
}
},
"node_modules/validator": {
- "version": "13.9.0",
- "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz",
- "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==",
+ "version": "13.15.15",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.15.tgz",
+ "integrity": "sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==",
+ "license": "MIT",
"engines": {
"node": ">= 0.10"
}
@@ -16460,6 +15754,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "license": "MIT",
"engines": {
"node": ">= 0.8"
}
@@ -16478,6 +15773,7 @@
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
"integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
"makeerror": "1.0.12"
}
@@ -16485,35 +15781,14 @@
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
- },
- "node_modules/websocket-driver": {
- "version": "0.7.4",
- "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
- "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
- "dev": true,
- "dependencies": {
- "http-parser-js": ">=0.5.1",
- "safe-buffer": ">=5.1.0",
- "websocket-extensions": ">=0.1.1"
- },
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/websocket-extensions": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
- "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
- "dev": true,
- "engines": {
- "node": ">=0.8.0"
- }
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
@@ -16524,6 +15799,7 @@
"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"
},
@@ -16538,42 +15814,65 @@
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
+ "license": "ISC",
"dependencies": {
"string-width": "^1.0.2 || 2 || 3 || 4"
}
},
- "node_modules/winston": {
- "version": "3.10.0",
- "resolved": "https://registry.npmjs.org/winston/-/winston-3.10.0.tgz",
- "integrity": "sha512-nT6SIDaE9B7ZRO0u3UvdrimG0HkB7dSTAgInQnNR2SOPJ4bvq5q79+pXLftKmP52lJGW15+H5MCK0nM9D3KB/g==",
+ "node_modules/wide-align/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
+ "node_modules/wide-align/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
"dependencies": {
- "@colors/colors": "1.5.0",
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/winston": {
+ "version": "3.17.0",
+ "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz",
+ "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==",
+ "license": "MIT",
+ "dependencies": {
+ "@colors/colors": "^1.6.0",
"@dabh/diagnostics": "^2.0.2",
"async": "^3.2.3",
"is-stream": "^2.0.0",
- "logform": "^2.4.0",
+ "logform": "^2.7.0",
"one-time": "^1.0.0",
"readable-stream": "^3.4.0",
"safe-stable-stringify": "^2.3.1",
"stack-trace": "0.0.x",
"triple-beam": "^1.3.0",
- "winston-transport": "^4.5.0"
+ "winston-transport": "^4.9.0"
},
"engines": {
"node": ">= 12.0.0"
}
},
"node_modules/winston-transport": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz",
- "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==",
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz",
+ "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==",
+ "license": "MIT",
"dependencies": {
- "logform": "^2.3.2",
- "readable-stream": "^3.6.0",
+ "logform": "^2.7.0",
+ "readable-stream": "^3.6.2",
"triple-beam": "^1.3.0"
},
"engines": {
- "node": ">= 6.4.0"
+ "node": ">= 12.0.0"
}
},
"node_modules/with": {
@@ -16591,11 +15890,45 @@
"node": ">= 10.0.0"
}
},
+ "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/worklenz-backend": {
+ "resolved": "",
+ "link": true
+ },
"node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
@@ -16608,49 +15941,82 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
- "node_modules/wrap-ansi/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==",
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "color-convert": "^2.0.1"
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/wrap-ansi/node_modules/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==",
+ "node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "color-name": "~1.1.4"
+ "ansi-regex": "^6.0.1"
},
"engines": {
- "node": ">=7.0.0"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
- "node_modules/wrap-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
"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=="
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "license": "ISC"
},
"node_modules/write-file-atomic": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
"integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"imurmurhash": "^0.1.4",
"signal-exit": "^3.0.7"
@@ -16659,6 +16025,13 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
+ "node_modules/write-file-atomic/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
@@ -16684,12 +16057,14 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
"integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/xmlchars": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
- "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "license": "MIT"
},
"node_modules/xss-filters": {
"version": "1.2.7",
@@ -16700,6 +16075,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "license": "MIT",
"engines": {
"node": ">=0.4"
}
@@ -16709,6 +16085,7 @@
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true,
+ "license": "ISC",
"engines": {
"node": ">=10"
}
@@ -16717,13 +16094,15 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true
+ "dev": true,
+ "license": "ISC"
},
"node_modules/yaml": {
"version": "2.0.0-1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz",
"integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==",
"dev": true,
+ "license": "ISC",
"engines": {
"node": ">= 6"
}
@@ -16733,6 +16112,7 @@
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"cliui": "^8.0.1",
"escalade": "^3.1.1",
@@ -16751,15 +16131,39 @@
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"dev": true,
+ "license": "ISC",
"engines": {
"node": ">=12"
}
},
+ "node_modules/yargs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -16769,6 +16173,7 @@
"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"
},
@@ -16781,6 +16186,7 @@
"resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz",
"integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"lodash.get": "^4.4.2",
"lodash.isequal": "^4.5.0",
@@ -16801,23 +16207,79 @@
"resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
"integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
"dev": true,
+ "license": "MIT",
"optional": true,
"engines": {
"node": "^12.20.0 || >=14"
}
},
"node_modules/zip-stream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz",
- "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz",
+ "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==",
+ "license": "MIT",
"dependencies": {
- "archiver-utils": "^2.1.0",
- "compress-commons": "^4.1.0",
+ "archiver-utils": "^3.0.4",
+ "compress-commons": "^4.1.2",
"readable-stream": "^3.6.0"
},
"engines": {
"node": ">= 10"
}
+ },
+ "node_modules/zip-stream/node_modules/archiver-utils": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz",
+ "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==",
+ "license": "MIT",
+ "dependencies": {
+ "glob": "^7.2.3",
+ "graceful-fs": "^4.2.0",
+ "lazystream": "^1.0.0",
+ "lodash.defaults": "^4.2.0",
+ "lodash.difference": "^4.5.0",
+ "lodash.flatten": "^4.4.0",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.union": "^4.6.0",
+ "normalize-path": "^3.0.0",
+ "readable-stream": "^3.6.0"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/zip-stream/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/zip-stream/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
}
}
}
diff --git a/worklenz-backend/package.json b/worklenz-backend/package.json
index f3faaaec..d4e07de2 100644
--- a/worklenz-backend/package.json
+++ b/worklenz-backend/package.json
@@ -4,23 +4,37 @@
"private": true,
"engines": {
"npm": ">=8.11.0",
- "node": ">=16.13.0",
+ "node": ">=20.0.0",
"yarn": "WARNING: Please use npm package manager instead of yarn"
},
"main": "build/bin/www",
"repository": "GITHUB_REPO_HERE",
"author": "worklenz.com",
"scripts": {
- "start": "node ./build/bin/www",
- "tcs": "grunt build:tsc",
- "build": "grunt build",
- "watch": "grunt watch",
- "dev": "grunt dev",
- "es": "esbuild `find src -type f -name '*.ts'` --platform=node --minify=true --watch=true --target=esnext --format=cjs --tsconfig=tsconfig.prod.json --outdir=dist",
- "copy": "grunt copy",
+ "test": "jest",
+ "start": "node build/bin/www.js",
+ "dev": "npm run build:dev && npm run watch",
+ "build": "npm run clean && npm run compile && npm run copy && npm run compress",
+ "build:dev": "npm run clean && npm run compile:dev && npm run copy",
+ "build:prod": "npm run clean && npm run compile:prod && npm run copy && npm run minify && npm run compress",
+ "clean": "rimraf build",
+ "compile": "tsc --build tsconfig.prod.json",
+ "compile:dev": "tsc --build tsconfig.json",
+ "compile:prod": "tsc --build tsconfig.prod.json",
+ "copy": "npm run copy:assets && npm run copy:views && npm run copy:config && npm run copy:shared",
+ "copy:assets": "npx cpx2 \"src/public/**\" build/public",
+ "copy:views": "npx cpx2 \"src/views/**\" build/views",
+ "copy:config": "npx cpx2 \".env\" build && npx cpx2 \"package.json\" build",
+ "copy:shared": "npx cpx2 \"src/shared/postgresql-error-codes.json\" build/shared && npx cpx2 \"src/shared/sample-data.json\" build/shared && npx cpx2 \"src/shared/templates/**\" build/shared/templates",
+ "watch": "concurrently \"npm run watch:ts\" \"npm run watch:assets\"",
+ "watch:ts": "tsc --build tsconfig.json --watch",
+ "watch:assets": "npx cpx2 \"src/{public,views}/**\" build --watch",
+ "minify": "terser build/**/*.js --compress --mangle --output-dir build",
+ "compress": "node scripts/compress.js",
+ "swagger": "node ./cli/swagger",
+ "inline-queries": "node ./cli/inline-queries",
"sonar": "sonar-scanner -Dproject.settings=sonar-project-dev.properties",
"tsc": "tsc",
- "test": "jest --setupFiles dotenv/config",
"test:watch": "jest --watch --setupFiles dotenv/config"
},
"jestSonar": {
@@ -45,6 +59,7 @@
"cors": "^2.8.5",
"cron": "^2.4.0",
"crypto-js": "^4.1.1",
+ "csrf-sync": "^4.2.1",
"csurf": "^1.11.0",
"debug": "^4.3.4",
"dotenv": "^16.3.1",
@@ -70,7 +85,6 @@
"passport-local": "^1.0.0",
"path": "^0.12.7",
"pg": "^8.14.1",
- "pg-native": "^3.3.0",
"pug": "^3.0.2",
"redis": "^4.6.7",
"sanitize-html": "^2.11.0",
@@ -78,8 +92,10 @@
"sharp": "^0.32.6",
"slugify": "^1.6.6",
"socket.io": "^4.7.1",
+ "tinymce": "^7.8.0",
"uglify-js": "^3.17.4",
"winston": "^3.10.0",
+ "worklenz-backend": "file:",
"xss-filters": "^1.2.7"
},
"devDependencies": {
@@ -87,15 +103,17 @@
"@babel/preset-typescript": "^7.22.5",
"@types/bcrypt": "^5.0.0",
"@types/bluebird": "^3.5.38",
+ "@types/body-parser": "^1.19.2",
"@types/compression": "^1.7.2",
"@types/connect-flash": "^0.0.37",
"@types/cookie-parser": "^1.4.3",
"@types/cron": "^2.0.1",
"@types/crypto-js": "^4.2.2",
"@types/csurf": "^1.11.2",
- "@types/express": "^4.17.17",
+ "@types/express": "^4.17.21",
"@types/express-brute": "^1.0.2",
"@types/express-brute-redis": "^0.0.4",
+ "@types/express-serve-static-core": "^4.17.34",
"@types/express-session": "^1.17.7",
"@types/fs-extra": "^9.0.13",
"@types/hpp": "^0.2.2",
@@ -120,26 +138,22 @@
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"chokidar": "^3.5.3",
+ "concurrently": "^9.1.2",
+ "cpx2": "^8.0.0",
"esbuild": "^0.17.19",
"esbuild-envfile-plugin": "^1.0.5",
"esbuild-node-externals": "^1.8.0",
"eslint": "^8.45.0",
"eslint-plugin-security": "^1.7.1",
"fs-extra": "^10.1.0",
- "grunt": "^1.6.1",
- "grunt-contrib-clean": "^2.0.1",
- "grunt-contrib-compress": "^2.0.0",
- "grunt-contrib-copy": "^1.0.0",
- "grunt-contrib-uglify": "^5.2.2",
- "grunt-contrib-watch": "^1.1.0",
- "grunt-shell": "^4.0.0",
- "grunt-sync": "^0.8.2",
"highcharts": "^11.1.0",
"jest": "^28.1.3",
"jest-sonar-reporter": "^2.0.0",
"ncp": "^2.0.0",
"nodeman": "^1.1.2",
+ "rimraf": "^6.0.1",
"swagger-jsdoc": "^6.2.8",
+ "terser": "^5.40.0",
"ts-jest": "^28.0.8",
"ts-node": "^10.9.1",
"tslint": "^6.1.3",
diff --git a/worklenz-backend/scripts/compress.js b/worklenz-backend/scripts/compress.js
new file mode 100644
index 00000000..6a946163
--- /dev/null
+++ b/worklenz-backend/scripts/compress.js
@@ -0,0 +1,53 @@
+const fs = require('fs');
+const path = require('path');
+const { createGzip } = require('zlib');
+const { pipeline } = require('stream');
+
+async function compressFile(inputPath, outputPath) {
+ return new Promise((resolve, reject) => {
+ const gzip = createGzip();
+ const source = fs.createReadStream(inputPath);
+ const destination = fs.createWriteStream(outputPath);
+
+ pipeline(source, gzip, destination, (err) => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ });
+ });
+}
+
+async function compressDirectory(dir) {
+ const files = fs.readdirSync(dir, { withFileTypes: true });
+
+ for (const file of files) {
+ const fullPath = path.join(dir, file.name);
+
+ if (file.isDirectory()) {
+ await compressDirectory(fullPath);
+ } else if (file.name.endsWith('.js') || file.name.endsWith('.css')) {
+ const gzPath = fullPath + '.gz';
+ await compressFile(fullPath, gzPath);
+ console.log(`Compressed: ${fullPath} -> ${gzPath}`);
+ }
+ }
+}
+
+async function main() {
+ try {
+ const buildDir = path.join(__dirname, '../build');
+ if (fs.existsSync(buildDir)) {
+ await compressDirectory(buildDir);
+ console.log('Compression complete!');
+ } else {
+ console.log('Build directory not found. Run build first.');
+ }
+ } catch (error) {
+ console.error('Compression failed:', error);
+ process.exit(1);
+ }
+}
+
+main();
\ No newline at end of file
diff --git a/worklenz-backend/src/app.ts b/worklenz-backend/src/app.ts
index 4da00a0e..68f18af3 100644
--- a/worklenz-backend/src/app.ts
+++ b/worklenz-backend/src/app.ts
@@ -6,7 +6,7 @@ import logger from "morgan";
import helmet from "helmet";
import compression from "compression";
import passport from "passport";
-import csurf from "csurf";
+import { csrfSync } from "csrf-sync";
import rateLimit from "express-rate-limit";
import cors from "cors";
import flash from "connect-flash";
@@ -112,17 +112,13 @@ function isLoggedIn(req: Request, _res: Response, next: NextFunction) {
return req.user ? next() : next(createError(401));
}
-// CSRF configuration
-const csrfProtection = csurf({
- cookie: {
- key: "XSRF-TOKEN",
- path: "/",
- httpOnly: false,
- secure: isProduction(), // Only secure in production
- sameSite: isProduction() ? "none" : "lax", // Different settings for dev vs prod
- domain: isProduction() ? ".worklenz.com" : undefined // Only set domain in production
- },
- ignoreMethods: ["HEAD", "OPTIONS"]
+// CSRF configuration using csrf-sync for session-based authentication
+const {
+ invalidCsrfTokenError,
+ generateToken,
+ csrfSynchronisedProtection,
+} = csrfSync({
+ getTokenFromRequest: (req: Request) => req.headers["x-csrf-token"] as string || (req.body && req.body["_csrf"])
});
// Apply CSRF selectively (exclude webhooks and public routes)
@@ -135,38 +131,25 @@ app.use((req, res, next) => {
) {
next();
} else {
- csrfProtection(req, res, next);
+ csrfSynchronisedProtection(req, res, next);
}
});
-// Set CSRF token cookie
+// Set CSRF token method on request object for compatibility
app.use((req: Request, res: Response, next: NextFunction) => {
- if (req.csrfToken) {
- const token = req.csrfToken();
- res.cookie("XSRF-TOKEN", token, {
- httpOnly: false,
- secure: isProduction(),
- sameSite: isProduction() ? "none" : "lax",
- domain: isProduction() ? ".worklenz.com" : undefined,
- path: "/"
- });
+ // Add csrfToken method to request object for compatibility
+ if (!req.csrfToken && generateToken) {
+ req.csrfToken = (overwrite?: boolean) => generateToken(req, overwrite);
}
next();
});
// CSRF token refresh endpoint
app.get("/csrf-token", (req: Request, res: Response) => {
- if (req.csrfToken) {
- const token = req.csrfToken();
- res.cookie("XSRF-TOKEN", token, {
- httpOnly: false,
- secure: isProduction(),
- sameSite: isProduction() ? "none" : "lax",
- domain: isProduction() ? ".worklenz.com" : undefined,
- path: "/"
- });
- res.status(200).json({ done: true, message: "CSRF token refreshed" });
- } else {
+ try {
+ const token = generateToken(req);
+ res.status(200).json({ done: true, message: "CSRF token refreshed", token });
+ } catch (error) {
res.status(500).json({ done: false, message: "Failed to generate CSRF token" });
}
});
@@ -219,7 +202,7 @@ if (isInternalServer()) {
// CSRF error handler
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
- if (err.code === "EBADCSRFTOKEN") {
+ if (err === invalidCsrfTokenError) {
return res.status(403).json({
done: false,
message: "Invalid CSRF token",
diff --git a/worklenz-backend/src/controllers/admin-center-controller.ts b/worklenz-backend/src/controllers/admin-center-controller.ts
index 3c50c858..be334aff 100644
--- a/worklenz-backend/src/controllers/admin-center-controller.ts
+++ b/worklenz-backend/src/controllers/admin-center-controller.ts
@@ -5,7 +5,7 @@ import db from "../config/db";
import {ServerResponse} from "../models/server-response";
import WorklenzControllerBase from "./worklenz-controller-base";
import HandleExceptions from "../decorators/handle-exceptions";
-import {calculateMonthDays, getColor, megabytesToBytes} from "../shared/utils";
+import {calculateMonthDays, getColor, log_error, megabytesToBytes} from "../shared/utils";
import moment from "moment";
import {calculateStorage} from "../shared/s3";
import {checkTeamSubscriptionStatus, getActiveTeamMemberCount, getCurrentProjectsCount, getFreePlanSettings, getOwnerIdByTeam, getTeamMemberCount, getUsedStorage} from "../shared/paddle-utils";
@@ -232,7 +232,11 @@ export default class AdminCenterController extends WorklenzControllerBase {
FROM team_member_info_view
WHERE team_member_info_view.team_member_id = tm.id),
role_id,
- r.name AS role_name
+ r.name AS role_name,
+ EXISTS(SELECT email
+ FROM email_invitations
+ WHERE team_member_id = tm.id
+ AND email_invitations.team_id = tm.team_id) AS pending_invitation
FROM team_members tm
LEFT JOIN users u on tm.user_id = u.id
LEFT JOIN roles r on tm.role_id = r.id
@@ -255,22 +259,33 @@ export default class AdminCenterController extends WorklenzControllerBase {
const {id} = req.params;
const {name, teamMembers} = req.body;
- const updateNameQuery = `UPDATE teams
- SET name = $1
- WHERE id = $2;`;
- await db.query(updateNameQuery, [name, id]);
+ try {
+ // Update team name
+ const updateNameQuery = `UPDATE teams SET name = $1 WHERE id = $2 RETURNING id;`;
+ const nameResult = await db.query(updateNameQuery, [name, id]);
+
+ if (!nameResult.rows.length) {
+ return res.status(404).send(new ServerResponse(false, null, "Team not found"));
+ }
- if (teamMembers.length) {
- teamMembers.forEach(async (element: { role_name: string; user_id: string; }) => {
- const q = `UPDATE team_members
- SET role_id = (SELECT id FROM roles WHERE roles.team_id = $1 AND name = $2)
- WHERE user_id = $3
- AND team_id = $1;`;
- await db.query(q, [id, element.role_name, element.user_id]);
- });
+ // Update team member roles if provided
+ if (teamMembers?.length) {
+ // Use Promise.all to handle all role updates concurrently
+ await Promise.all(teamMembers.map(async (member: { role_name: string; user_id: string; }) => {
+ const roleQuery = `
+ UPDATE team_members
+ SET role_id = (SELECT id FROM roles WHERE roles.team_id = $1 AND name = $2)
+ WHERE user_id = $3 AND team_id = $1
+ RETURNING id;`;
+ await db.query(roleQuery, [id, member.role_name, member.user_id]);
+ }));
+ }
+
+ return res.status(200).send(new ServerResponse(true, null, "Team updated successfully"));
+ } catch (error) {
+ log_error("Error updating team:", error);
+ return res.status(500).send(new ServerResponse(false, null, "Failed to update team"));
}
-
- return res.status(200).send(new ServerResponse(true, [], "Team updated successfully"));
}
@HandleExceptions()
diff --git a/worklenz-backend/src/controllers/auth-controller.ts b/worklenz-backend/src/controllers/auth-controller.ts
index 8364d59c..4fea4f59 100644
--- a/worklenz-backend/src/controllers/auth-controller.ts
+++ b/worklenz-backend/src/controllers/auth-controller.ts
@@ -35,8 +35,18 @@ export default class AuthController extends WorklenzControllerBase {
const auth_error = errors.length > 0 ? errors[0] : null;
const message = messages.length > 0 ? messages[0] : null;
- const midTitle = req.query.strategy === "login" ? "Login Failed!" : "Signup Failed!";
- const title = req.query.strategy ? midTitle : null;
+ // Determine title based on authentication status and strategy
+ let title = null;
+ if (req.query.strategy) {
+ if (auth_error) {
+ // Show failure title only when there's an actual error
+ title = req.query.strategy === "login" ? "Login Failed!" : "Signup Failed!";
+ } else if (req.isAuthenticated() && message) {
+ // Show success title when authenticated and there's a success message
+ title = req.query.strategy === "login" ? "Login Successful!" : "Signup Successful!";
+ }
+ // If no error and not authenticated, don't show any title (this might be a redirect without completion)
+ }
if (req.user)
req.user.build_v = FileConstants.getRelease();
diff --git a/worklenz-backend/src/controllers/home-page-controller.ts b/worklenz-backend/src/controllers/home-page-controller.ts
index be290eb9..5a0d87f4 100644
--- a/worklenz-backend/src/controllers/home-page-controller.ts
+++ b/worklenz-backend/src/controllers/home-page-controller.ts
@@ -137,6 +137,10 @@ export default class HomePageController extends WorklenzControllerBase {
WHERE category_id NOT IN (SELECT id
FROM sys_task_status_categories
WHERE is_done IS FALSE))
+ AND NOT EXISTS(SELECT project_id
+ FROM archived_projects
+ WHERE project_id = p.id
+ AND user_id = $2)
${groupByClosure}
ORDER BY t.end_date ASC`;
@@ -158,9 +162,13 @@ export default class HomePageController extends WorklenzControllerBase {
WHERE category_id NOT IN (SELECT id
FROM sys_task_status_categories
WHERE is_done IS FALSE))
+ AND NOT EXISTS(SELECT project_id
+ FROM archived_projects
+ WHERE project_id = p.id
+ AND user_id = $3)
${groupByClosure}`;
- const result = await db.query(q, [teamId, userId]);
+ const result = await db.query(q, [teamId, userId, userId]);
const [row] = result.rows;
return row;
}
diff --git a/worklenz-backend/src/controllers/project-insights-controller.ts b/worklenz-backend/src/controllers/project-insights-controller.ts
index aeb3707d..6e8413dc 100644
--- a/worklenz-backend/src/controllers/project-insights-controller.ts
+++ b/worklenz-backend/src/controllers/project-insights-controller.ts
@@ -322,7 +322,7 @@ export default class ProjectInsightsController extends WorklenzControllerBase {
(SELECT get_task_assignees(tasks.id)) AS assignees
FROM tasks
JOIN work_log ON work_log.task_id = tasks.id
- WHERE project_id = $1
+ WHERE project_id = $1 AND total_minutes <> 0 AND (total_minutes * 60) <> work_log.total_time_spent
AND CASE
WHEN ($2 IS TRUE) THEN project_id IS NOT NULL
ELSE archived IS FALSE END
diff --git a/worklenz-backend/src/controllers/projects-controller.ts b/worklenz-backend/src/controllers/projects-controller.ts
index e739bfb1..a350675e 100644
--- a/worklenz-backend/src/controllers/projects-controller.ts
+++ b/worklenz-backend/src/controllers/projects-controller.ts
@@ -408,6 +408,9 @@ export default class ProjectsController extends WorklenzControllerBase {
sps.color_code AS status_color,
sps.icon AS status_icon,
(SELECT name FROM clients WHERE id = projects.client_id) AS client_name,
+ projects.use_manual_progress,
+ projects.use_weighted_progress,
+ projects.use_time_progress,
(SELECT COALESCE(ROW_TO_JSON(pm), '{}'::JSON)
FROM (SELECT team_member_id AS id,
@@ -753,4 +756,186 @@ export default class ProjectsController extends WorklenzControllerBase {
}
+ @HandleExceptions()
+ public static async getGrouped(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise {
+ // Use qualified field name for projects to avoid ambiguity
+ const {searchQuery, sortField, sortOrder, size, offset} = this.toPaginationOptions(req.query, ["projects.name"]);
+ const groupBy = req.query.groupBy as string || "category";
+
+ const filterByMember = !req.user?.owner && !req.user?.is_admin ?
+ ` AND is_member_of_project(projects.id, '${req.user?.id}', $1) ` : "";
+
+ const isFavorites = req.query.filter === "1" ? ` AND EXISTS(SELECT user_id FROM favorite_projects WHERE user_id = '${req.user?.id}' AND project_id = projects.id)` : "";
+ const isArchived = req.query.filter === "2"
+ ? ` AND EXISTS(SELECT user_id FROM archived_projects WHERE user_id = '${req.user?.id}' AND project_id = projects.id)`
+ : ` AND NOT EXISTS(SELECT user_id FROM archived_projects WHERE user_id = '${req.user?.id}' AND project_id = projects.id)`;
+ const categories = this.getFilterByCategoryWhereClosure(req.query.categories as string);
+ const statuses = this.getFilterByStatusWhereClosure(req.query.statuses as string);
+
+ // Determine grouping field and join based on groupBy parameter
+ let groupField = "";
+ let groupName = "";
+ let groupColor = "";
+ let groupJoin = "";
+ let groupByFields = "";
+ let groupOrderBy = "";
+
+ switch (groupBy) {
+ case "client":
+ groupField = "COALESCE(projects.client_id::text, 'no-client')";
+ groupName = "COALESCE(clients.name, 'No Client')";
+ groupColor = "'#688'";
+ groupJoin = "LEFT JOIN clients ON projects.client_id = clients.id";
+ groupByFields = "projects.client_id, clients.name";
+ groupOrderBy = "COALESCE(clients.name, 'No Client')";
+ break;
+ case "status":
+ groupField = "COALESCE(projects.status_id::text, 'no-status')";
+ groupName = "COALESCE(sys_project_statuses.name, 'No Status')";
+ groupColor = "COALESCE(sys_project_statuses.color_code, '#888')";
+ groupJoin = "LEFT JOIN sys_project_statuses ON projects.status_id = sys_project_statuses.id";
+ groupByFields = "projects.status_id, sys_project_statuses.name, sys_project_statuses.color_code";
+ groupOrderBy = "COALESCE(sys_project_statuses.name, 'No Status')";
+ break;
+ case "category":
+ default:
+ groupField = "COALESCE(projects.category_id::text, 'uncategorized')";
+ groupName = "COALESCE(project_categories.name, 'Uncategorized')";
+ groupColor = "COALESCE(project_categories.color_code, '#888')";
+ groupJoin = "LEFT JOIN project_categories ON projects.category_id = project_categories.id";
+ groupByFields = "projects.category_id, project_categories.name, project_categories.color_code";
+ groupOrderBy = "COALESCE(project_categories.name, 'Uncategorized')";
+ }
+
+ // Ensure sortField is properly qualified for the inner project query
+ let qualifiedSortField = sortField;
+ if (Array.isArray(sortField)) {
+ qualifiedSortField = sortField[0]; // Take the first field if it's an array
+ }
+ // Replace "projects." with "p2." for the inner query
+ const innerSortField = qualifiedSortField.replace("projects.", "p2.");
+
+ const q = `
+ SELECT ROW_TO_JSON(rec) AS groups
+ FROM (
+ SELECT COUNT(DISTINCT ${groupField}) AS total_groups,
+ (SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(group_data))), '[]'::JSON)
+ FROM (
+ SELECT ${groupField} AS group_key,
+ ${groupName} AS group_name,
+ ${groupColor} AS group_color,
+ COUNT(*) AS project_count,
+ (SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(project_data))), '[]'::JSON)
+ FROM (
+ SELECT p2.id,
+ p2.name,
+ (SELECT sys_project_statuses.name FROM sys_project_statuses WHERE sys_project_statuses.id = p2.status_id) AS status,
+ (SELECT sys_project_statuses.color_code FROM sys_project_statuses WHERE sys_project_statuses.id = p2.status_id) AS status_color,
+ (SELECT sys_project_statuses.icon FROM sys_project_statuses WHERE sys_project_statuses.id = p2.status_id) AS status_icon,
+ EXISTS(SELECT user_id
+ FROM favorite_projects
+ WHERE user_id = '${req.user?.id}'
+ AND project_id = p2.id) AS favorite,
+ EXISTS(SELECT user_id
+ FROM archived_projects
+ WHERE user_id = '${req.user?.id}'
+ AND project_id = p2.id) AS archived,
+ p2.color_code,
+ p2.start_date,
+ p2.end_date,
+ p2.category_id,
+ (SELECT COUNT(*)
+ FROM tasks
+ WHERE archived IS FALSE
+ AND project_id = p2.id) AS all_tasks_count,
+ (SELECT COUNT(*)
+ FROM tasks
+ WHERE archived IS FALSE
+ AND project_id = p2.id
+ AND status_id IN (SELECT task_statuses.id
+ FROM task_statuses
+ WHERE task_statuses.project_id = p2.id
+ AND task_statuses.category_id IN
+ (SELECT sys_task_status_categories.id FROM sys_task_status_categories WHERE sys_task_status_categories.is_done IS TRUE))) AS completed_tasks_count,
+ (SELECT COUNT(*)
+ FROM project_members
+ WHERE project_members.project_id = p2.id) AS members_count,
+ (SELECT get_project_members(p2.id)) AS names,
+ (SELECT clients.name FROM clients WHERE clients.id = p2.client_id) AS client_name,
+ (SELECT users.name FROM users WHERE users.id = p2.owner_id) AS project_owner,
+ (SELECT project_categories.name FROM project_categories WHERE project_categories.id = p2.category_id) AS category_name,
+ (SELECT project_categories.color_code
+ FROM project_categories
+ WHERE project_categories.id = p2.category_id) AS category_color,
+ ((SELECT project_members.team_member_id as team_member_id
+ FROM project_members
+ WHERE project_members.project_id = p2.id
+ AND project_members.project_access_level_id = (SELECT project_access_levels.id FROM project_access_levels WHERE project_access_levels.key = 'PROJECT_MANAGER'))) AS project_manager_team_member_id,
+ (SELECT project_members.default_view
+ FROM project_members
+ WHERE project_members.project_id = p2.id
+ AND project_members.team_member_id = '${req.user?.team_member_id}') AS team_member_default_view,
+ (SELECT CASE
+ WHEN ((SELECT MAX(tasks.updated_at)
+ FROM tasks
+ WHERE tasks.archived IS FALSE
+ AND tasks.project_id = p2.id) >
+ p2.updated_at)
+ THEN (SELECT MAX(tasks.updated_at)
+ FROM tasks
+ WHERE tasks.archived IS FALSE
+ AND tasks.project_id = p2.id)
+ ELSE p2.updated_at END) AS updated_at
+ FROM projects p2
+ ${groupJoin.replace("projects.", "p2.")}
+ WHERE p2.team_id = $1
+ AND ${groupField.replace("projects.", "p2.")} = ${groupField}
+ ${categories.replace("projects.", "p2.")}
+ ${statuses.replace("projects.", "p2.")}
+ ${isArchived.replace("projects.", "p2.")}
+ ${isFavorites.replace("projects.", "p2.")}
+ ${filterByMember.replace("projects.", "p2.")}
+ ${searchQuery.replace("projects.", "p2.")}
+ ORDER BY ${innerSortField} ${sortOrder}
+ ) project_data
+ ) AS projects
+ FROM projects
+ ${groupJoin}
+ WHERE projects.team_id = $1 ${categories} ${statuses} ${isArchived} ${isFavorites} ${filterByMember} ${searchQuery}
+ GROUP BY ${groupByFields}
+ ORDER BY ${groupOrderBy}
+ LIMIT $2 OFFSET $3
+ ) group_data
+ ) AS data
+ FROM projects
+ ${groupJoin}
+ WHERE projects.team_id = $1 ${categories} ${statuses} ${isArchived} ${isFavorites} ${filterByMember} ${searchQuery}
+ ) rec;
+ `;
+
+ const result = await db.query(q, [req.user?.team_id || null, size, offset]);
+ const [data] = result.rows;
+
+ // Process the grouped data
+ for (const group of data?.groups.data || []) {
+ for (const project of group.projects || []) {
+ project.progress = project.all_tasks_count > 0
+ ? ((project.completed_tasks_count / project.all_tasks_count) * 100).toFixed(0) : 0;
+
+ project.updated_at_string = moment(project.updated_at).fromNow();
+
+ project.names = this.createTagList(project?.names);
+ project.names.map((a: any) => a.color_code = getColor(a.name));
+
+ if (project.project_manager_team_member_id) {
+ project.project_manager = {
+ id: project.project_manager_team_member_id
+ };
+ }
+ }
+ }
+
+ return res.status(200).send(new ServerResponse(true, data?.groups || { total_groups: 0, data: [] }));
+ }
+
}
diff --git a/worklenz-backend/src/controllers/reporting/reporting-allocation-controller.ts b/worklenz-backend/src/controllers/reporting/reporting-allocation-controller.ts
index be79c4b8..4db8e3d5 100644
--- a/worklenz-backend/src/controllers/reporting/reporting-allocation-controller.ts
+++ b/worklenz-backend/src/controllers/reporting/reporting-allocation-controller.ts
@@ -408,6 +408,65 @@ export default class ReportingAllocationController extends ReportingControllerBa
const { duration, date_range } = req.body;
+ // Calculate the date range (start and end)
+ let startDate: moment.Moment;
+ let endDate: moment.Moment;
+ if (date_range && date_range.length === 2) {
+ startDate = moment(date_range[0]);
+ endDate = moment(date_range[1]);
+ } else if (duration === DATE_RANGES.ALL_TIME) {
+ // Fetch the earliest start_date (or created_at if null) from selected projects
+ const minDateQuery = `SELECT MIN(COALESCE(start_date, created_at)) as min_date FROM projects WHERE id IN (${projectIds})`;
+ const minDateResult = await db.query(minDateQuery, []);
+ const minDate = minDateResult.rows[0]?.min_date;
+ startDate = minDate ? moment(minDate) : moment('2000-01-01');
+ endDate = moment();
+ } else {
+ switch (duration) {
+ case DATE_RANGES.YESTERDAY:
+ startDate = moment().subtract(1, "day");
+ endDate = moment().subtract(1, "day");
+ break;
+ case DATE_RANGES.LAST_WEEK:
+ startDate = moment().subtract(1, "week").startOf("isoWeek");
+ endDate = moment().subtract(1, "week").endOf("isoWeek");
+ break;
+ case DATE_RANGES.LAST_MONTH:
+ startDate = moment().subtract(1, "month").startOf("month");
+ endDate = moment().subtract(1, "month").endOf("month");
+ break;
+ case DATE_RANGES.LAST_QUARTER:
+ startDate = moment().subtract(3, "months").startOf("quarter");
+ endDate = moment().subtract(1, "quarter").endOf("quarter");
+ break;
+ default:
+ startDate = moment().startOf("day");
+ endDate = moment().endOf("day");
+ }
+ }
+
+ // Count only weekdays (Mon-Fri) in the period
+ let workingDays = 0;
+ let current = startDate.clone();
+ while (current.isSameOrBefore(endDate, 'day')) {
+ const day = current.isoWeekday();
+ if (day >= 1 && day <= 5) workingDays++;
+ current.add(1, 'day');
+ }
+
+ // Get hours_per_day for all selected projects
+ const projectHoursQuery = `SELECT id, hours_per_day FROM projects WHERE id IN (${projectIds})`;
+ const projectHoursResult = await db.query(projectHoursQuery, []);
+ const projectHoursMap: Record = {};
+ for (const row of projectHoursResult.rows) {
+ projectHoursMap[row.id] = row.hours_per_day || 8;
+ }
+ // Sum total working hours for all selected projects
+ let totalWorkingHours = 0;
+ for (const pid of Object.keys(projectHoursMap)) {
+ totalWorkingHours += workingDays * projectHoursMap[pid];
+ }
+
const durationClause = this.getDateRangeClause(duration || DATE_RANGES.LAST_WEEK, date_range);
const archivedClause = archived
? ""
@@ -430,6 +489,12 @@ export default class ReportingAllocationController extends ReportingControllerBa
for (const member of result.rows) {
member.value = member.logged_time ? parseFloat(moment.duration(member.logged_time, "seconds").asHours().toFixed(2)) : 0;
member.color_code = getColor(member.name);
+ member.total_working_hours = totalWorkingHours;
+ member.utilization_percent = (totalWorkingHours > 0 && member.logged_time) ? ((parseFloat(member.logged_time) / (totalWorkingHours * 3600)) * 100).toFixed(2) : '0.00';
+ member.utilized_hours = member.logged_time ? (parseFloat(member.logged_time) / 3600).toFixed(2) : '0.00';
+ // Over/under utilized hours: utilized_hours - total_working_hours
+ const overUnder = member.utilized_hours && member.total_working_hours ? (parseFloat(member.utilized_hours) - member.total_working_hours) : 0;
+ member.over_under_utilized_hours = overUnder.toFixed(2);
}
return res.status(200).send(new ServerResponse(true, result.rows));
diff --git a/worklenz-backend/src/controllers/task-phases-controller.ts b/worklenz-backend/src/controllers/task-phases-controller.ts
index e72fbbab..163ff250 100644
--- a/worklenz-backend/src/controllers/task-phases-controller.ts
+++ b/worklenz-backend/src/controllers/task-phases-controller.ts
@@ -16,19 +16,23 @@ export default class TaskPhasesController extends WorklenzControllerBase {
if (!req.query.id)
return res.status(400).send(new ServerResponse(false, null, "Invalid request"));
+ // Use custom name if provided, otherwise use default naming pattern
+ const phaseName = req.body.name?.trim() ||
+ `Untitled Phase (${(await db.query("SELECT COUNT(*) FROM project_phases WHERE project_id = $1", [req.query.id])).rows[0].count + 1})`;
+
const q = `
INSERT INTO project_phases (name, color_code, project_id, sort_index)
VALUES (
- CONCAT('Untitled Phase (', (SELECT COUNT(*) FROM project_phases WHERE project_id = $2) + 1, ')'),
$1,
$2,
- (SELECT COUNT(*) FROM project_phases WHERE project_id = $2) + 1)
+ $3,
+ (SELECT COUNT(*) FROM project_phases WHERE project_id = $3) + 1)
RETURNING id, name, color_code, sort_index;
`;
req.body.color_code = this.DEFAULT_PHASE_COLOR;
- const result = await db.query(q, [req.body.color_code, req.query.id]);
+ const result = await db.query(q, [phaseName, req.body.color_code, req.query.id]);
const [data] = result.rows;
data.color_code = getColor(data.name) + TASK_STATUS_COLOR_ALPHA;
diff --git a/worklenz-backend/src/controllers/task-statuses-controller.ts b/worklenz-backend/src/controllers/task-statuses-controller.ts
index dbefe0dd..a20e0d7a 100644
--- a/worklenz-backend/src/controllers/task-statuses-controller.ts
+++ b/worklenz-backend/src/controllers/task-statuses-controller.ts
@@ -134,6 +134,25 @@ export default class TaskStatusesController extends WorklenzControllerBase {
return res.status(200).send(new ServerResponse(true, data));
}
+ @HandleExceptions()
+ public static async updateCategory(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise {
+ const hasMoreCategories = await TaskStatusesController.hasMoreCategories(req.params.id, req.query.current_project_id as string);
+
+ if (!hasMoreCategories)
+ return res.status(200).send(new ServerResponse(false, null, existsErrorMessage).withTitle("Status category update failed!"));
+
+ const q = `
+ UPDATE task_statuses
+ SET category_id = $2
+ WHERE id = $1
+ AND project_id = $3
+ RETURNING (SELECT color_code FROM sys_task_status_categories WHERE id = task_statuses.category_id), (SELECT color_code_dark FROM sys_task_status_categories WHERE id = task_statuses.category_id);
+ `;
+ const result = await db.query(q, [req.params.id, req.body.category_id, req.query.current_project_id]);
+ const [data] = result.rows;
+ return res.status(200).send(new ServerResponse(true, data));
+ }
+
@HandleExceptions()
public static async updateStatusOrder(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise {
const q = `SELECT update_status_order($1);`;
diff --git a/worklenz-backend/src/controllers/tasks-controller-base.ts b/worklenz-backend/src/controllers/tasks-controller-base.ts
index 293ae3d8..58558c1e 100644
--- a/worklenz-backend/src/controllers/tasks-controller-base.ts
+++ b/worklenz-backend/src/controllers/tasks-controller-base.ts
@@ -1,6 +1,6 @@
import WorklenzControllerBase from "./worklenz-controller-base";
-import {getColor} from "../shared/utils";
-import {PriorityColorCodes, TASK_PRIORITY_COLOR_ALPHA, TASK_STATUS_COLOR_ALPHA} from "../shared/constants";
+import { getColor } from "../shared/utils";
+import { PriorityColorCodes, TASK_PRIORITY_COLOR_ALPHA, TASK_STATUS_COLOR_ALPHA } from "../shared/constants";
import moment from "moment/moment";
export const GroupBy = {
@@ -32,10 +32,46 @@ export default class TasksControllerBase extends WorklenzControllerBase {
}
public static updateTaskViewModel(task: any) {
- task.progress = ~~(task.total_minutes_spent / task.total_minutes * 100);
+ // For parent tasks (with subtasks), always use calculated progress from subtasks
+ if (task.sub_tasks_count > 0) {
+ // Ensure progress matches complete_ratio for consistency
+ task.progress = task.complete_ratio || 0;
+
+ // Important: Parent tasks should not have manual progress
+ // If they somehow do, reset it
+ if (task.manual_progress) {
+ task.manual_progress = false;
+ task.progress_value = null;
+ }
+ }
+ // For tasks without subtasks, respect manual progress if set
+ else if (task.manual_progress === true && task.progress_value !== null && task.progress_value !== undefined) {
+ // For manually set progress, use that value directly
+ task.progress = parseInt(task.progress_value);
+ task.complete_ratio = parseInt(task.progress_value);
+ }
+ // For tasks with no subtasks and no manual progress
+ else {
+ // Only calculate progress based on time if time-based progress is enabled for the project
+ if (task.project_use_time_progress && task.total_minutes_spent && task.total_minutes) {
+ // Cap the progress at 100% to prevent showing more than 100% progress
+ task.progress = Math.min(~~(task.total_minutes_spent / task.total_minutes * 100), 100);
+ } else {
+ // Default to 0% progress when time-based calculation is not enabled
+ task.progress = 0;
+ }
+
+ // Set complete_ratio to match progress
+ task.complete_ratio = task.progress;
+ }
+
+ // Ensure numeric values
+ task.progress = parseInt(task.progress) || 0;
+ task.complete_ratio = parseInt(task.complete_ratio) || 0;
+
task.overdue = task.total_minutes < task.total_minutes_spent;
- task.time_spent = {hours: ~~(task.total_minutes_spent / 60), minutes: task.total_minutes_spent % 60};
+ task.time_spent = { hours: ~~(task.total_minutes_spent / 60), minutes: task.total_minutes_spent % 60 };
task.comments_count = Number(task.comments_count) ? +task.comments_count : 0;
task.attachments_count = Number(task.attachments_count) ? +task.attachments_count : 0;
@@ -73,9 +109,9 @@ export default class TasksControllerBase extends WorklenzControllerBase {
if (task.timer_start_time)
task.timer_start_time = moment(task.timer_start_time).valueOf();
+ // Set completed_count and total_tasks_count regardless of progress calculation method
const totalCompleted = (+task.completed_sub_tasks + +task.parent_task_completed) || 0;
- const totalTasks = +task.sub_tasks_count || 0; // if needed add +1 for parent
- task.complete_ratio = TasksControllerBase.calculateTaskCompleteRatio(totalCompleted, totalTasks);
+ const totalTasks = +task.sub_tasks_count || 0;
task.completed_count = totalCompleted;
task.total_tasks_count = totalTasks;
diff --git a/worklenz-backend/src/controllers/tasks-controller-v2.ts b/worklenz-backend/src/controllers/tasks-controller-v2.ts
index 3e1290f1..d941f824 100644
--- a/worklenz-backend/src/controllers/tasks-controller-v2.ts
+++ b/worklenz-backend/src/controllers/tasks-controller-v2.ts
@@ -97,15 +97,19 @@ export default class TasksControllerV2 extends TasksControllerBase {
try {
const result = await db.query("SELECT get_task_complete_ratio($1) AS info;", [taskId]);
const [data] = result.rows;
- data.info.ratio = +data.info.ratio.toFixed();
- return data.info;
+ if (data && data.info && data.info.ratio !== undefined) {
+ data.info.ratio = +((data.info.ratio || 0).toFixed());
+ return data.info;
+ }
+ return null;
} catch (error) {
+ log_error(`Error in getTaskCompleteRatio: ${error}`);
return null;
}
}
private static getQuery(userId: string, options: ParsedQs) {
- const searchField = options.search ? "t.name" : "sort_order";
+ const searchField = options.search ? ["t.name", "CONCAT((SELECT key FROM projects WHERE id = t.project_id), '-', task_no)"] : "sort_order";
const { searchQuery, sortField } = TasksControllerV2.toPaginationOptions(options, searchField);
const isSubTasks = !!options.parent_task;
@@ -126,20 +130,20 @@ export default class TasksControllerV2 extends TasksControllerBase {
const filterByAssignee = TasksControllerV2.getFilterByAssignee(options.filterBy as string);
// Returns statuses of each task as a json array if filterBy === "member"
const statusesQuery = TasksControllerV2.getStatusesQuery(options.filterBy as string);
-
+
// Custom columns data query
- const customColumnsQuery = options.customColumns
+ const customColumnsQuery = options.customColumns
? `, (SELECT COALESCE(
jsonb_object_agg(
- custom_cols.key,
+ custom_cols.key,
custom_cols.value
- ),
+ ),
'{}'::JSONB
)
FROM (
- SELECT
+ SELECT
cc.key,
- CASE
+ CASE
WHEN ccv.text_value IS NOT NULL THEN to_jsonb(ccv.text_value)
WHEN ccv.number_value IS NOT NULL THEN to_jsonb(ccv.number_value)
WHEN ccv.boolean_value IS NOT NULL THEN to_jsonb(ccv.boolean_value)
@@ -192,6 +196,13 @@ export default class TasksControllerV2 extends TasksControllerBase {
t.archived,
t.description,
t.sort_order,
+ t.progress_value,
+ t.manual_progress,
+ t.weight,
+ (SELECT use_manual_progress FROM projects WHERE id = t.project_id) AS project_use_manual_progress,
+ (SELECT use_weighted_progress FROM projects WHERE id = t.project_id) AS project_use_weighted_progress,
+ (SELECT use_time_progress FROM projects WHERE id = t.project_id) AS project_use_time_progress,
+ (SELECT get_task_complete_ratio(t.id)->>'ratio') AS complete_ratio,
(SELECT phase_id FROM task_phase WHERE task_id = t.id) AS phase_id,
(SELECT name
@@ -315,9 +326,23 @@ export default class TasksControllerV2 extends TasksControllerBase {
@HandleExceptions()
public static async getList(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise {
+ const startTime = performance.now();
+ console.log(`[PERFORMANCE] getList method called for project ${req.params.id} - THIS METHOD IS DEPRECATED, USE getTasksV3 INSTEAD`);
+
+ // PERFORMANCE OPTIMIZATION: Skip expensive progress calculation by default
+ // Progress values are already calculated and stored in the database
+ // Only refresh if explicitly requested via refresh_progress=true query parameter
+ if (req.query.refresh_progress === "true" && req.params.id) {
+ console.log(`[PERFORMANCE] Starting progress refresh for project ${req.params.id} (getList)`);
+ const progressStartTime = performance.now();
+ await this.refreshProjectTaskProgressValues(req.params.id);
+ const progressEndTime = performance.now();
+ console.log(`[PERFORMANCE] Progress refresh completed in ${(progressEndTime - progressStartTime).toFixed(2)}ms`);
+ }
+
const isSubTasks = !!req.query.parent_task;
const groupBy = (req.query.group || GroupBy.STATUS) as string;
-
+
// Add customColumns flag to query params
req.query.customColumns = "true";
@@ -334,7 +359,7 @@ export default class TasksControllerV2 extends TasksControllerBase {
return g;
}, {});
- this.updateMapByGroup(tasks, groupBy, map);
+ await this.updateMapByGroup(tasks, groupBy, map);
const updatedGroups = Object.keys(map).map(key => {
const group = map[key];
@@ -350,15 +375,31 @@ export default class TasksControllerV2 extends TasksControllerBase {
};
});
+ const endTime = performance.now();
+ const totalTime = endTime - startTime;
+ console.log(`[PERFORMANCE] getList method completed in ${totalTime.toFixed(2)}ms for project ${req.params.id} with ${tasks.length} tasks`);
+
+ // Log warning if this deprecated method is taking too long
+ if (totalTime > 1000) {
+ console.warn(`[PERFORMANCE WARNING] DEPRECATED getList method taking ${totalTime.toFixed(2)}ms - Frontend should use getTasksV3 instead!`);
+ }
+
return res.status(200).send(new ServerResponse(true, updatedGroups));
}
- public static updateMapByGroup(tasks: any[], groupBy: string, map: { [p: string]: ITaskGroup }) {
+ public static async updateMapByGroup(tasks: any[], groupBy: string, map: { [p: string]: ITaskGroup }) {
let index = 0;
const unmapped = [];
+
+ // PERFORMANCE OPTIMIZATION: Remove expensive individual DB calls for each task
+ // Progress values are already calculated and included in the main query
+ // No need to make additional database calls here
+
+ // Process tasks with their already-calculated progress values
for (const task of tasks) {
task.index = index++;
TasksControllerV2.updateTaskViewModel(task);
+
if (groupBy === GroupBy.STATUS) {
map[task.status]?.tasks.push(task);
} else if (groupBy === GroupBy.PRIORITY) {
@@ -394,11 +435,25 @@ export default class TasksControllerV2 extends TasksControllerBase {
@HandleExceptions()
public static async getTasksOnly(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise {
+ const startTime = performance.now();
+ console.log(`[PERFORMANCE] getTasksOnly method called for project ${req.params.id} - Consider using getTasksV3 for better performance`);
+
+ // PERFORMANCE OPTIMIZATION: Skip expensive progress calculation by default
+ // Progress values are already calculated and stored in the database
+ // Only refresh if explicitly requested via refresh_progress=true query parameter
+ if (req.query.refresh_progress === "true" && req.params.id) {
+ console.log(`[PERFORMANCE] Starting progress refresh for project ${req.params.id} (getTasksOnly)`);
+ const progressStartTime = performance.now();
+ await this.refreshProjectTaskProgressValues(req.params.id);
+ const progressEndTime = performance.now();
+ console.log(`[PERFORMANCE] Progress refresh completed in ${(progressEndTime - progressStartTime).toFixed(2)}ms`);
+ }
+
const isSubTasks = !!req.query.parent_task;
-
+
// Add customColumns flag to query params
req.query.customColumns = "true";
-
+
const q = TasksControllerV2.getQuery(req.user?.id as string, req.query);
const params = isSubTasks ? [req.params.id || null, req.query.parent_task] : [req.params.id || null];
const result = await db.query(q, params);
@@ -410,11 +465,25 @@ export default class TasksControllerV2 extends TasksControllerBase {
[data] = result.rows;
} else { // else we return a flat list of tasks
data = [...result.rows];
+
+ // PERFORMANCE OPTIMIZATION: Remove expensive individual DB calls for each task
+ // Progress values are already calculated and included in the main query via get_task_complete_ratio
+ // The database query already includes complete_ratio, so no need for additional calls
+
for (const task of data) {
TasksControllerV2.updateTaskViewModel(task);
}
}
+ const endTime = performance.now();
+ const totalTime = endTime - startTime;
+ console.log(`[PERFORMANCE] getTasksOnly method completed in ${totalTime.toFixed(2)}ms for project ${req.params.id} with ${data.length} tasks`);
+
+ // Log warning if this method is taking too long
+ if (totalTime > 1000) {
+ console.warn(`[PERFORMANCE WARNING] getTasksOnly method taking ${totalTime.toFixed(2)}ms - Consider using getTasksV3 for better performance!`);
+ }
+
return res.status(200).send(new ServerResponse(true, data));
}
@@ -443,6 +512,53 @@ export default class TasksControllerV2 extends TasksControllerBase {
return res.status(200).send(new ServerResponse(true, task));
}
+ @HandleExceptions()
+ public static async resetParentTaskManualProgress(parentTaskId: string): Promise {
+ try {
+ // Check if this task has subtasks
+ const subTasksResult = await db.query(
+ "SELECT COUNT(*) as subtask_count FROM tasks WHERE parent_task_id = $1 AND archived IS FALSE",
+ [parentTaskId]
+ );
+
+ const subtaskCount = parseInt(subTasksResult.rows[0]?.subtask_count || "0");
+
+ // If it has subtasks, reset the manual_progress flag to false
+ if (subtaskCount > 0) {
+ await db.query(
+ "UPDATE tasks SET manual_progress = false WHERE id = $1",
+ [parentTaskId]
+ );
+ console.log(`Reset manual progress for parent task ${parentTaskId} with ${subtaskCount} subtasks`);
+
+ // Get the project settings to determine which calculation method to use
+ const projectResult = await db.query(
+ "SELECT project_id FROM tasks WHERE id = $1",
+ [parentTaskId]
+ );
+
+ const projectId = projectResult.rows[0]?.project_id;
+
+ if (projectId) {
+ // Recalculate the parent task's progress based on its subtasks
+ const progressResult = await db.query(
+ "SELECT get_task_complete_ratio($1) AS ratio",
+ [parentTaskId]
+ );
+
+ const progressRatio = progressResult.rows[0]?.ratio?.ratio || 0;
+
+ // Emit the updated progress value to all clients
+ // Note: We don't have socket context here, so we can't directly emit
+ // This will be picked up on the next client refresh
+ console.log(`Recalculated progress for parent task ${parentTaskId}: ${progressRatio}%`);
+ }
+ }
+ } catch (error) {
+ log_error(`Error resetting parent task manual progress: ${error}`);
+ }
+ }
+
@HandleExceptions()
public static async convertToSubtask(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise {
@@ -483,6 +599,11 @@ export default class TasksControllerV2 extends TasksControllerBase {
: [req.body.id, req.body.project_id, req.body.parent_task_id, req.body.to_group_id];
await db.query(q, params);
+ // Reset the parent task's manual progress when converting a task to a subtask
+ if (req.body.parent_task_id) {
+ await this.resetParentTaskManualProgress(req.body.parent_task_id);
+ }
+
const result = await db.query("SELECT get_single_task($1) AS task;", [req.body.id]);
const [data] = result.rows;
const model = TasksControllerV2.updateTaskViewModel(data.task);
@@ -504,6 +625,21 @@ export default class TasksControllerV2 extends TasksControllerBase {
return this.createTagList(result.rows);
}
+ public static async getProjectSubscribers(projectId: string) {
+ const q = `
+ SELECT u.name, u.avatar_url, ps.user_id, ps.team_member_id, ps.project_id
+ FROM project_subscribers ps
+ LEFT JOIN users u ON ps.user_id = u.id
+ WHERE ps.project_id = $1;
+ `;
+ const result = await db.query(q, [projectId]);
+
+ for (const member of result.rows)
+ member.color_code = getColor(member.name);
+
+ return this.createTagList(result.rows);
+ }
+
public static async checkUserAssignedToTask(taskId: string, userId: string, teamId: string) {
const q = `
SELECT EXISTS(
@@ -633,27 +769,27 @@ export default class TasksControllerV2 extends TasksControllerBase {
// Get column information
const columnQuery = `
- SELECT id, field_type
- FROM cc_custom_columns
+ SELECT id, field_type
+ FROM cc_custom_columns
WHERE project_id = $1 AND key = $2
`;
const columnResult = await db.query(columnQuery, [project_id, column_key]);
-
+
if (columnResult.rowCount === 0) {
return res.status(404).send(new ServerResponse(false, "Custom column not found"));
}
-
+
const column = columnResult.rows[0];
const columnId = column.id;
const fieldType = column.field_type;
-
+
// Determine which value field to use based on the field_type
let textValue = null;
let numberValue = null;
let dateValue = null;
let booleanValue = null;
let jsonValue = null;
-
+
switch (fieldType) {
case "number":
numberValue = parseFloat(String(value));
@@ -670,58 +806,585 @@ export default class TasksControllerV2 extends TasksControllerBase {
default:
textValue = String(value);
}
-
+
// Check if a value already exists
const existingValueQuery = `
- SELECT id
- FROM cc_column_values
+ SELECT id
+ FROM cc_column_values
WHERE task_id = $1 AND column_id = $2
`;
const existingValueResult = await db.query(existingValueQuery, [taskId, columnId]);
-
+
if (existingValueResult.rowCount && existingValueResult.rowCount > 0) {
// Update existing value
const updateQuery = `
- UPDATE cc_column_values
- SET text_value = $1,
- number_value = $2,
- date_value = $3,
- boolean_value = $4,
- json_value = $5,
- updated_at = NOW()
+ UPDATE cc_column_values
+ SET text_value = $1,
+ number_value = $2,
+ date_value = $3,
+ boolean_value = $4,
+ json_value = $5,
+ updated_at = NOW()
WHERE task_id = $6 AND column_id = $7
`;
await db.query(updateQuery, [
- textValue,
- numberValue,
- dateValue,
- booleanValue,
- jsonValue,
- taskId,
+ textValue,
+ numberValue,
+ dateValue,
+ booleanValue,
+ jsonValue,
+ taskId,
columnId
]);
} else {
// Insert new value
const insertQuery = `
- INSERT INTO cc_column_values
- (task_id, column_id, text_value, number_value, date_value, boolean_value, json_value, created_at, updated_at)
+ INSERT INTO cc_column_values
+ (task_id, column_id, text_value, number_value, date_value, boolean_value, json_value, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, NOW(), NOW())
`;
await db.query(insertQuery, [
- taskId,
- columnId,
- textValue,
- numberValue,
- dateValue,
- booleanValue,
+ taskId,
+ columnId,
+ textValue,
+ numberValue,
+ dateValue,
+ booleanValue,
jsonValue
]);
}
- return res.status(200).send(new ServerResponse(true, {
+ return res.status(200).send(new ServerResponse(true, {
task_id: taskId,
column_key,
value
}));
}
+
+ public static async refreshProjectTaskProgressValues(projectId: string): Promise {
+ try {
+ // Run the recalculate_all_task_progress function only for tasks in this project
+ const query = `
+ DO $$
+ BEGIN
+ -- First, reset manual_progress flag for all tasks that have subtasks within this project
+ UPDATE tasks AS t
+ SET manual_progress = FALSE
+ WHERE project_id = '${projectId}'
+ AND EXISTS (
+ SELECT 1
+ FROM tasks
+ WHERE parent_task_id = t.id
+ AND archived IS FALSE
+ );
+
+ -- Start recalculation from leaf tasks (no subtasks) and propagate upward
+ -- This ensures calculations are done in the right order
+ WITH RECURSIVE task_hierarchy AS (
+ -- Base case: Start with all leaf tasks (no subtasks) in this project
+ SELECT
+ id,
+ parent_task_id,
+ 0 AS level
+ FROM tasks
+ WHERE project_id = '${projectId}'
+ AND NOT EXISTS (
+ SELECT 1 FROM tasks AS sub
+ WHERE sub.parent_task_id = tasks.id
+ AND sub.archived IS FALSE
+ )
+ AND archived IS FALSE
+
+ UNION ALL
+
+ -- Recursive case: Move up to parent tasks, but only after processing all their children
+ SELECT
+ t.id,
+ t.parent_task_id,
+ th.level + 1
+ FROM tasks t
+ JOIN task_hierarchy th ON t.id = th.parent_task_id
+ WHERE t.archived IS FALSE
+ )
+ -- Sort by level to ensure we calculate in the right order (leaves first, then parents)
+ UPDATE tasks
+ SET progress_value = (SELECT (get_task_complete_ratio(tasks.id)->>'ratio')::FLOAT)
+ FROM (
+ SELECT id, level
+ FROM task_hierarchy
+ ORDER BY level
+ ) AS ordered_tasks
+ WHERE tasks.id = ordered_tasks.id
+ AND tasks.project_id = '${projectId}'
+ AND (manual_progress IS FALSE OR manual_progress IS NULL);
+ END $$;
+ `;
+
+ await db.query(query);
+ console.log(`Finished refreshing progress values for project ${projectId}`);
+ } catch (error) {
+ log_error("Error refreshing project task progress values", error);
+ }
+ }
+
+ public static async updateTaskProgress(taskId: string): Promise {
+ try {
+ // Calculate the task's progress using get_task_complete_ratio
+ const result = await db.query("SELECT get_task_complete_ratio($1) AS info;", [taskId]);
+ const [data] = result.rows;
+
+ if (data && data.info && data.info.ratio !== undefined) {
+ const progressValue = +((data.info.ratio || 0).toFixed());
+
+ // Update the task's progress_value in the database
+ await db.query(
+ "UPDATE tasks SET progress_value = $1 WHERE id = $2",
+ [progressValue, taskId]
+ );
+
+ console.log(`Updated progress for task ${taskId} to ${progressValue}%`);
+
+ // If this task has a parent, update the parent's progress as well
+ const parentResult = await db.query(
+ "SELECT parent_task_id FROM tasks WHERE id = $1",
+ [taskId]
+ );
+
+ if (parentResult.rows.length > 0 && parentResult.rows[0].parent_task_id) {
+ await this.updateTaskProgress(parentResult.rows[0].parent_task_id);
+ }
+ }
+ } catch (error) {
+ log_error(`Error updating task progress: ${error}`);
+ }
+ }
+
+ // Add this method to update progress when a task's weight is changed
+ public static async updateTaskWeight(taskId: string, weight: number): Promise {
+ try {
+ // Update the task's weight
+ await db.query(
+ "UPDATE tasks SET weight = $1 WHERE id = $2",
+ [weight, taskId]
+ );
+
+ // Get the parent task ID
+ const parentResult = await db.query(
+ "SELECT parent_task_id FROM tasks WHERE id = $1",
+ [taskId]
+ );
+
+ // If this task has a parent, update the parent's progress
+ if (parentResult.rows.length > 0 && parentResult.rows[0].parent_task_id) {
+ await this.updateTaskProgress(parentResult.rows[0].parent_task_id);
+ }
+ } catch (error) {
+ log_error(`Error updating task weight: ${error}`);
+ }
+ }
+
+ @HandleExceptions()
+ public static async getTasksV3(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise {
+ const startTime = performance.now();
+ const isSubTasks = !!req.query.parent_task;
+ const groupBy = (req.query.group || GroupBy.STATUS) as string;
+ const archived = req.query.archived === "true";
+
+ // PERFORMANCE OPTIMIZATION: Skip expensive progress calculation by default
+ // Progress values are already calculated and stored in the database
+ // Only refresh if explicitly requested via refresh_progress=true query parameter
+ // This dramatically improves initial load performance (from ~2-5s to ~200-500ms)
+ const shouldRefreshProgress = req.query.refresh_progress === "true";
+
+ if (shouldRefreshProgress && req.params.id) {
+ const progressStartTime = performance.now();
+ await this.refreshProjectTaskProgressValues(req.params.id);
+ const progressEndTime = performance.now();
+ }
+
+ const queryStartTime = performance.now();
+ const q = TasksControllerV2.getQuery(req.user?.id as string, req.query);
+ const params = isSubTasks ? [req.params.id || null, req.query.parent_task] : [req.params.id || null];
+
+ const result = await db.query(q, params);
+ const tasks = [...result.rows];
+ const queryEndTime = performance.now();
+
+ // Get groups metadata dynamically from database
+ const groupsStartTime = performance.now();
+ const groups = await this.getGroups(groupBy, req.params.id);
+ const groupsEndTime = performance.now();
+
+ // Create priority value to name mapping
+ const priorityMap: Record = {
+ "0": "low",
+ "1": "medium",
+ "2": "high"
+ };
+
+ // Create status category mapping based on actual status names from database
+ const statusCategoryMap: Record = {};
+ for (const group of groups) {
+ if (groupBy === GroupBy.STATUS && group.id) {
+ // Use the actual status name from database, convert to lowercase for consistency
+ statusCategoryMap[group.id] = group.name.toLowerCase().replace(/\s+/g, "_");
+ }
+ }
+
+
+
+ // Transform tasks with all necessary data preprocessing
+ const transformStartTime = performance.now();
+ const transformedTasks = tasks.map((task, index) => {
+ // Update task with calculated values (lightweight version)
+ TasksControllerV2.updateTaskViewModel(task);
+ task.index = index;
+
+ // Convert time values
+ const convertTimeValue = (value: any): number => {
+ if (typeof value === "number") return value;
+ if (typeof value === "string") {
+ const parsed = parseFloat(value);
+ return isNaN(parsed) ? 0 : parsed;
+ }
+ if (value && typeof value === "object") {
+ if ("hours" in value || "minutes" in value) {
+ const hours = Number(value.hours || 0);
+ const minutes = Number(value.minutes || 0);
+ return hours + (minutes / 60);
+ }
+ }
+ return 0;
+ };
+
+ return {
+ id: task.id,
+ task_key: task.task_key || "",
+ title: task.name || "",
+ description: task.description || "",
+ // Use dynamic status mapping from database
+ status: statusCategoryMap[task.status] || task.status,
+ // Pre-processed priority using mapping
+ priority: priorityMap[task.priority_value?.toString()] || "medium",
+ // Use actual phase name from database
+ phase: task.phase_name || "Development",
+ progress: typeof task.complete_ratio === "number" ? task.complete_ratio : 0,
+ assignees: task.assignees?.map((a: any) => a.team_member_id) || [],
+ assignee_names: task.assignee_names || task.names || [],
+ labels: task.labels?.map((l: any) => ({
+ id: l.id || l.label_id,
+ name: l.name,
+ color: l.color_code || "#1890ff",
+ end: l.end,
+ names: l.names
+ })) || [],
+ dueDate: task.end_date || task.END_DATE,
+ startDate: task.start_date,
+ timeTracking: {
+ estimated: convertTimeValue(task.total_time),
+ logged: convertTimeValue(task.time_spent),
+ },
+ customFields: {},
+ custom_column_values: task.custom_column_values || {}, // Include custom column values
+ createdAt: task.created_at || new Date().toISOString(),
+ updatedAt: task.updated_at || new Date().toISOString(),
+ order: typeof task.sort_order === "number" ? task.sort_order : 0,
+ // Additional metadata for frontend
+ originalStatusId: task.status,
+ originalPriorityId: task.priority,
+ statusColor: task.status_color,
+ priorityColor: task.priority_color,
+ // Add subtask count
+ sub_tasks_count: task.sub_tasks_count || 0,
+ // Add indicator fields for frontend icons
+ comments_count: task.comments_count || 0,
+ has_subscribers: !!task.has_subscribers,
+ attachments_count: task.attachments_count || 0,
+ has_dependencies: !!task.has_dependencies,
+ schedule_id: task.schedule_id || null,
+ reporter: task.reporter || null,
+ };
+ });
+ const transformEndTime = performance.now();
+
+ // Create groups based on dynamic data from database
+ const groupingStartTime = performance.now();
+ const groupedResponse: Record = {};
+
+ // Initialize groups from database data
+ groups.forEach(group => {
+ const groupKey = groupBy === GroupBy.STATUS
+ ? group.name.toLowerCase().replace(/\s+/g, "_")
+ : groupBy === GroupBy.PRIORITY
+ ? priorityMap[(group as any).value?.toString()] || group.name.toLowerCase()
+ : group.name.toLowerCase().replace(/\s+/g, "_");
+
+ groupedResponse[groupKey] = {
+ id: group.id,
+ title: group.name,
+ groupType: groupBy,
+ groupValue: groupKey,
+ collapsed: false,
+ tasks: [],
+ taskIds: [],
+ color: group.color_code || this.getDefaultGroupColor(groupBy, groupKey),
+ // Include additional metadata from database
+ category_id: group.category_id,
+ start_date: group.start_date,
+ end_date: group.end_date,
+ sort_index: (group as any).sort_index,
+ };
+ });
+
+ // Distribute tasks into groups
+ const unmappedTasks: any[] = [];
+
+ transformedTasks.forEach(task => {
+ let groupKey: string;
+ let taskAssigned = false;
+
+ if (groupBy === GroupBy.STATUS) {
+ groupKey = task.status;
+ if (groupedResponse[groupKey]) {
+ groupedResponse[groupKey].tasks.push(task);
+ groupedResponse[groupKey].taskIds.push(task.id);
+ taskAssigned = true;
+ }
+ } else if (groupBy === GroupBy.PRIORITY) {
+ groupKey = task.priority;
+ if (groupedResponse[groupKey]) {
+ groupedResponse[groupKey].tasks.push(task);
+ groupedResponse[groupKey].taskIds.push(task.id);
+ taskAssigned = true;
+ }
+ } else if (groupBy === GroupBy.PHASE) {
+ // For phase grouping, check if task has a valid phase
+ if (task.phase && task.phase.trim() !== "") {
+ groupKey = task.phase.toLowerCase().replace(/\s+/g, "_");
+ if (groupedResponse[groupKey]) {
+ groupedResponse[groupKey].tasks.push(task);
+ groupedResponse[groupKey].taskIds.push(task.id);
+ taskAssigned = true;
+ }
+ }
+ // If task doesn't have a valid phase, add to unmapped
+ if (!taskAssigned) {
+ unmappedTasks.push(task);
+ }
+ }
+ });
+
+ // Calculate progress stats for priority and phase grouping
+ if (groupBy === GroupBy.PRIORITY || groupBy === GroupBy.PHASE) {
+ Object.values(groupedResponse).forEach((group: any) => {
+ if (group.tasks && group.tasks.length > 0) {
+ const todoCount = group.tasks.filter((task: any) => {
+ // For tasks, we need to check their original status category
+ const originalTask = tasks.find(t => t.id === task.id);
+ return originalTask?.status_category?.is_todo;
+ }).length;
+
+ const doingCount = group.tasks.filter((task: any) => {
+ const originalTask = tasks.find(t => t.id === task.id);
+ return originalTask?.status_category?.is_doing;
+ }).length;
+
+ const doneCount = group.tasks.filter((task: any) => {
+ const originalTask = tasks.find(t => t.id === task.id);
+ return originalTask?.status_category?.is_done;
+ }).length;
+
+ const total = group.tasks.length;
+
+ // Calculate progress percentages
+ group.todo_progress = total > 0 ? +((todoCount / total) * 100).toFixed(0) : 0;
+ group.doing_progress = total > 0 ? +((doingCount / total) * 100).toFixed(0) : 0;
+ group.done_progress = total > 0 ? +((doneCount / total) * 100).toFixed(0) : 0;
+ }
+ });
+ }
+
+ // Create unmapped group if there are tasks without proper phase assignment
+ if (unmappedTasks.length > 0 && groupBy === GroupBy.PHASE) {
+ const unmappedGroup = {
+ id: UNMAPPED,
+ title: UNMAPPED,
+ groupType: groupBy,
+ groupValue: UNMAPPED.toLowerCase(),
+ collapsed: false,
+ tasks: unmappedTasks,
+ taskIds: unmappedTasks.map(task => task.id),
+ color: "#fbc84c69", // Orange color with transparency
+ category_id: null,
+ start_date: null,
+ end_date: null,
+ sort_index: 999, // Put unmapped group at the end
+ todo_progress: 0,
+ doing_progress: 0,
+ done_progress: 0,
+ };
+
+ // Calculate progress stats for unmapped group
+ if (unmappedTasks.length > 0) {
+ const todoCount = unmappedTasks.filter((task: any) => {
+ const originalTask = tasks.find(t => t.id === task.id);
+ return originalTask?.status_category?.is_todo;
+ }).length;
+
+ const doingCount = unmappedTasks.filter((task: any) => {
+ const originalTask = tasks.find(t => t.id === task.id);
+ return originalTask?.status_category?.is_doing;
+ }).length;
+
+ const doneCount = unmappedTasks.filter((task: any) => {
+ const originalTask = tasks.find(t => t.id === task.id);
+ return originalTask?.status_category?.is_done;
+ }).length;
+
+ const total = unmappedTasks.length;
+
+ unmappedGroup.todo_progress = total > 0 ? +((todoCount / total) * 100).toFixed(0) : 0;
+ unmappedGroup.doing_progress = total > 0 ? +((doingCount / total) * 100).toFixed(0) : 0;
+ unmappedGroup.done_progress = total > 0 ? +((doneCount / total) * 100).toFixed(0) : 0;
+ }
+
+ groupedResponse[UNMAPPED.toLowerCase()] = unmappedGroup;
+ }
+
+ // Sort tasks within each group by order
+ Object.values(groupedResponse).forEach((group: any) => {
+ group.tasks.sort((a: any, b: any) => a.order - b.order);
+ });
+
+ // Convert to array format expected by frontend, maintaining database order
+ const responseGroups = groups
+ .map(group => {
+ const groupKey = groupBy === GroupBy.STATUS
+ ? group.name.toLowerCase().replace(/\s+/g, "_")
+ : groupBy === GroupBy.PRIORITY
+ ? priorityMap[(group as any).value?.toString()] || group.name.toLowerCase()
+ : group.name.toLowerCase().replace(/\s+/g, "_");
+
+ return groupedResponse[groupKey];
+ })
+ .filter(group => group && (group.tasks.length > 0 || req.query.include_empty === "true"));
+
+ // Add unmapped group to the end if it exists
+ if (groupedResponse[UNMAPPED.toLowerCase()]) {
+ responseGroups.push(groupedResponse[UNMAPPED.toLowerCase()]);
+ }
+
+ const groupingEndTime = performance.now();
+
+ const endTime = performance.now();
+ const totalTime = endTime - startTime;
+
+ // Log warning if request is taking too long
+ if (totalTime > 1000) {
+ console.warn(`[PERFORMANCE WARNING] Slow request detected: ${totalTime.toFixed(2)}ms for project ${req.params.id} with ${transformedTasks.length} tasks`);
+ }
+
+ return res.status(200).send(new ServerResponse(true, {
+ groups: responseGroups,
+ allTasks: transformedTasks,
+ grouping: groupBy,
+ totalTasks: transformedTasks.length
+ }));
+ }
+
+ private static getDefaultGroupColor(groupBy: string, groupValue: string): string {
+ const colorMaps: Record> = {
+ [GroupBy.STATUS]: {
+ todo: "#f0f0f0",
+ doing: "#1890ff",
+ done: "#52c41a",
+ },
+ [GroupBy.PRIORITY]: {
+ critical: "#ff4d4f",
+ high: "#ff7a45",
+ medium: "#faad14",
+ low: "#52c41a",
+ },
+ [GroupBy.PHASE]: {
+ planning: "#722ed1",
+ development: "#1890ff",
+ testing: "#faad14",
+ deployment: "#52c41a",
+ unmapped: "#fbc84c69",
+ },
+ };
+
+ return colorMaps[groupBy]?.[groupValue] || "#d9d9d9";
+ }
+
+ @HandleExceptions()
+ public static async refreshTaskProgress(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise {
+ try {
+ const startTime = performance.now();
+
+ if (req.params.id) {
+ console.log(`[PERFORMANCE] Starting background progress refresh for project ${req.params.id}`);
+ await this.refreshProjectTaskProgressValues(req.params.id);
+
+ const endTime = performance.now();
+ const totalTime = endTime - startTime;
+ console.log(`[PERFORMANCE] Background progress refresh completed in ${totalTime.toFixed(2)}ms for project ${req.params.id}`);
+
+ return res.status(200).send(new ServerResponse(true, {
+ message: "Task progress values refreshed successfully",
+ performanceMetrics: {
+ refreshTime: Math.round(totalTime),
+ projectId: req.params.id
+ }
+ }));
+ }
+ return res.status(400).send(new ServerResponse(false, null, "Project ID is required"));
+ } catch (error) {
+ console.error("Error refreshing task progress:", error);
+ return res.status(500).send(new ServerResponse(false, null, "Failed to refresh task progress"));
+ }
+ }
+
+ // Optimized method for getting task progress without blocking main UI
+ @HandleExceptions()
+ public static async getTaskProgressStatus(req: IWorkLenzRequest, res: IWorkLenzResponse): Promise {
+ try {
+ if (!req.params.id) {
+ return res.status(400).send(new ServerResponse(false, null, "Project ID is required"));
+ }
+
+ // Get basic progress stats without expensive calculations
+ const result = await db.query(`
+ SELECT
+ COUNT(*) as total_tasks,
+ COUNT(CASE WHEN EXISTS(
+ SELECT 1 FROM tasks_with_status_view
+ WHERE tasks_with_status_view.task_id = tasks.id
+ AND is_done IS TRUE
+ ) THEN 1 END) as completed_tasks,
+ AVG(CASE
+ WHEN progress_value IS NOT NULL THEN progress_value
+ ELSE 0
+ END) as avg_progress,
+ MAX(updated_at) as last_updated
+ FROM tasks
+ WHERE project_id = $1 AND archived IS FALSE
+ `, [req.params.id]);
+
+ const [stats] = result.rows;
+
+ return res.status(200).send(new ServerResponse(true, {
+ projectId: req.params.id,
+ totalTasks: parseInt(stats.total_tasks) || 0,
+ completedTasks: parseInt(stats.completed_tasks) || 0,
+ avgProgress: parseFloat(stats.avg_progress) || 0,
+ lastUpdated: stats.last_updated,
+ completionPercentage: stats.total_tasks > 0 ?
+ Math.round((parseInt(stats.completed_tasks) / parseInt(stats.total_tasks)) * 100) : 0
+ }));
+ } catch (error) {
+ console.error("Error getting task progress status:", error);
+ return res.status(500).send(new ServerResponse(false, null, "Failed to get task progress status"));
+ }
+ }
}
diff --git a/worklenz-backend/src/controllers/worklenz-controller-base.ts b/worklenz-backend/src/controllers/worklenz-controller-base.ts
index 60d0c998..c494f47b 100644
--- a/worklenz-backend/src/controllers/worklenz-controller-base.ts
+++ b/worklenz-backend/src/controllers/worklenz-controller-base.ts
@@ -34,29 +34,24 @@ export default abstract class WorklenzControllerBase {
const offset = queryParams.search ? 0 : (index - 1) * size;
const paging = queryParams.paging || "true";
- // let s = "";
- // if (typeof searchField === "string") {
- // s = `${searchField} || ' ' || id::TEXT`;
- // } else if (Array.isArray(searchField)) {
- // s = searchField.join(" || ' ' || ");
- // }
-
- // const search = (queryParams.search as string || "").trim();
- // const searchQuery = search ? `AND TO_TSVECTOR(${s}) @@ TO_TSQUERY('${toTsQuery(search)}')` : "";
-
const search = (queryParams.search as string || "").trim();
- let s = "";
- if (typeof searchField === "string") {
- s = ` ${searchField} ILIKE '%${search}%'`;
- } else if (Array.isArray(searchField)) {
- s = searchField.map(index => ` ${index} ILIKE '%${search}%'`).join(" OR ");
- }
-
let searchQuery = "";
if (search) {
- searchQuery = isMemberFilter ? ` (${s}) AND ` : ` AND (${s}) `;
+ // Properly escape single quotes to prevent SQL syntax errors
+ const escapedSearch = search.replace(/'/g, "''");
+
+ let s = "";
+ if (typeof searchField === "string") {
+ s = ` ${searchField} ILIKE '%${escapedSearch}%'`;
+ } else if (Array.isArray(searchField)) {
+ s = searchField.map(field => ` ${field} ILIKE '%${escapedSearch}%'`).join(" OR ");
+ }
+
+ if (s) {
+ searchQuery = isMemberFilter ? ` (${s}) AND ` : ` AND (${s}) `;
+ }
}
// Sort
diff --git a/worklenz-backend/src/cron_jobs/index.ts b/worklenz-backend/src/cron_jobs/index.ts
index f13ec2e8..108a76f2 100644
--- a/worklenz-backend/src/cron_jobs/index.ts
+++ b/worklenz-backend/src/cron_jobs/index.ts
@@ -1,11 +1,11 @@
import {startDailyDigestJob} from "./daily-digest-job";
import {startNotificationsJob} from "./notifications-job";
import {startProjectDigestJob} from "./project-digest-job";
-import { startRecurringTasksJob } from "./recurring-tasks";
+import {startRecurringTasksJob} from "./recurring-tasks";
export function startCronJobs() {
startNotificationsJob();
startDailyDigestJob();
startProjectDigestJob();
- // startRecurringTasksJob();
+ if (process.env.ENABLE_RECURRING_JOBS === "true") startRecurringTasksJob();
}
diff --git a/worklenz-backend/src/cron_jobs/recurring-tasks.ts b/worklenz-backend/src/cron_jobs/recurring-tasks.ts
index a9ae7847..2780edd5 100644
--- a/worklenz-backend/src/cron_jobs/recurring-tasks.ts
+++ b/worklenz-backend/src/cron_jobs/recurring-tasks.ts
@@ -7,12 +7,90 @@ import TasksController from "../controllers/tasks-controller";
// At 11:00+00 (4.30pm+530) on every day-of-month if it's on every day-of-week from Monday through Friday.
// const TIME = "0 11 */1 * 1-5";
-const TIME = "*/2 * * * *";
+const TIME = process.env.RECURRING_JOBS_INTERVAL || "0 11 */1 * 1-5";
const TIME_FORMAT = "YYYY-MM-DD";
// const TIME = "0 0 * * *"; // Runs at midnight every day
const log = (value: any) => console.log("recurring-task-cron-job:", value);
+// Define future limits for different schedule types
+// More conservative limits to prevent task list clutter
+const FUTURE_LIMITS = {
+ daily: moment.duration(3, "days"),
+ weekly: moment.duration(1, "week"),
+ monthly: moment.duration(1, "month"),
+ every_x_days: (interval: number) => moment.duration(interval, "days"),
+ every_x_weeks: (interval: number) => moment.duration(interval, "weeks"),
+ every_x_months: (interval: number) => moment.duration(interval, "months")
+};
+
+// Helper function to get the future limit based on schedule type
+function getFutureLimit(scheduleType: string, interval?: number): moment.Duration {
+ switch (scheduleType) {
+ case "daily":
+ return FUTURE_LIMITS.daily;
+ case "weekly":
+ return FUTURE_LIMITS.weekly;
+ case "monthly":
+ return FUTURE_LIMITS.monthly;
+ case "every_x_days":
+ return FUTURE_LIMITS.every_x_days(interval || 1);
+ case "every_x_weeks":
+ return FUTURE_LIMITS.every_x_weeks(interval || 1);
+ case "every_x_months":
+ return FUTURE_LIMITS.every_x_months(interval || 1);
+ default:
+ return moment.duration(3, "days"); // Default to 3 days
+ }
+}
+
+// Helper function to batch create tasks
+async function createBatchTasks(template: ITaskTemplate & IRecurringSchedule, endDates: moment.Moment[]) {
+ const createdTasks = [];
+
+ for (const nextEndDate of endDates) {
+ const existingTaskQuery = `
+ SELECT id FROM tasks
+ WHERE schedule_id = $1 AND end_date::DATE = $2::DATE;
+ `;
+ const existingTaskResult = await db.query(existingTaskQuery, [template.schedule_id, nextEndDate.format(TIME_FORMAT)]);
+
+ if (existingTaskResult.rows.length === 0) {
+ const createTaskQuery = `SELECT create_quick_task($1::json) as task;`;
+ const taskData = {
+ name: template.name,
+ priority_id: template.priority_id,
+ project_id: template.project_id,
+ reporter_id: template.reporter_id,
+ status_id: template.status_id || null,
+ end_date: nextEndDate.format(TIME_FORMAT),
+ schedule_id: template.schedule_id
+ };
+ const createTaskResult = await db.query(createTaskQuery, [JSON.stringify(taskData)]);
+ const createdTask = createTaskResult.rows[0].task;
+
+ if (createdTask) {
+ createdTasks.push(createdTask);
+
+ for (const assignee of template.assignees) {
+ await TasksController.createTaskBulkAssignees(assignee.team_member_id, template.project_id, createdTask.id, assignee.assigned_by);
+ }
+
+ for (const label of template.labels) {
+ const q = `SELECT add_or_remove_task_label($1, $2) AS labels;`;
+ await db.query(q, [createdTask.id, label.label_id]);
+ }
+
+ console.log(`Created task for template ${template.name} with end date ${nextEndDate.format(TIME_FORMAT)}`);
+ }
+ } else {
+ console.log(`Skipped creating task for template ${template.name} with end date ${nextEndDate.format(TIME_FORMAT)} - task already exists`);
+ }
+ }
+
+ return createdTasks;
+}
+
async function onRecurringTaskJobTick() {
try {
log("(cron) Recurring tasks job started.");
@@ -33,65 +111,44 @@ async function onRecurringTaskJobTick() {
? moment(template.last_task_end_date)
: moment(template.created_at);
- const futureLimit = moment(template.last_checked_at || template.created_at).add(1, "week");
+ // Calculate future limit based on schedule type
+ const futureLimit = moment(template.last_checked_at || template.created_at)
+ .add(getFutureLimit(
+ template.schedule_type,
+ template.interval_days || template.interval_weeks || template.interval_months || 1
+ ));
let nextEndDate = calculateNextEndDate(template, lastTaskEndDate);
+ const endDatesToCreate: moment.Moment[] = [];
- // Find the next future occurrence
- while (nextEndDate.isSameOrBefore(now)) {
+ // Find all future occurrences within the limit
+ while (nextEndDate.isSameOrBefore(futureLimit)) {
+ if (nextEndDate.isAfter(now)) {
+ endDatesToCreate.push(moment(nextEndDate));
+ }
nextEndDate = calculateNextEndDate(template, nextEndDate);
}
- // Only create a task if it's within the future limit
- if (nextEndDate.isSameOrBefore(futureLimit)) {
- const existingTaskQuery = `
- SELECT id FROM tasks
- WHERE schedule_id = $1 AND end_date::DATE = $2::DATE;
+ // Batch create tasks for all future dates
+ if (endDatesToCreate.length > 0) {
+ const createdTasks = await createBatchTasks(template, endDatesToCreate);
+ createdTaskCount += createdTasks.length;
+
+ // Update the last_checked_at in the schedule
+ const updateScheduleQuery = `
+ UPDATE task_recurring_schedules
+ SET last_checked_at = $1::DATE,
+ last_created_task_end_date = $2
+ WHERE id = $3;
`;
- const existingTaskResult = await db.query(existingTaskQuery, [template.schedule_id, nextEndDate.format(TIME_FORMAT)]);
-
- if (existingTaskResult.rows.length === 0) {
- const createTaskQuery = `SELECT create_quick_task($1::json) as task;`;
- const taskData = {
- name: template.name,
- priority_id: template.priority_id,
- project_id: template.project_id,
- reporter_id: template.reporter_id,
- status_id: template.status_id || null,
- end_date: nextEndDate.format(TIME_FORMAT),
- schedule_id: template.schedule_id
- };
- const createTaskResult = await db.query(createTaskQuery, [JSON.stringify(taskData)]);
- const createdTask = createTaskResult.rows[0].task;
-
- if (createdTask) {
- createdTaskCount++;
-
- for (const assignee of template.assignees) {
- await TasksController.createTaskBulkAssignees(assignee.team_member_id, template.project_id, createdTask.id, assignee.assigned_by);
- }
-
- for (const label of template.labels) {
- const q = `SELECT add_or_remove_task_label($1, $2) AS labels;`;
- await db.query(q, [createdTask.id, label.label_id]);
- }
-
- console.log(`Created task for template ${template.name} with end date ${nextEndDate.format(TIME_FORMAT)}`);
- }
- } else {
- console.log(`Skipped creating task for template ${template.name} with end date ${nextEndDate.format(TIME_FORMAT)} - task already exists`);
- }
+ await db.query(updateScheduleQuery, [
+ moment().format(TIME_FORMAT),
+ endDatesToCreate[endDatesToCreate.length - 1].format(TIME_FORMAT),
+ template.schedule_id
+ ]);
} else {
- console.log(`No task created for template ${template.name} - next occurrence is beyond the future limit`);
+ console.log(`No tasks created for template ${template.name} - next occurrence is beyond the future limit`);
}
-
- // Update the last_checked_at in the schedule
- const updateScheduleQuery = `
- UPDATE task_recurring_schedules
- SET last_checked_at = $1::DATE, last_created_task_end_date = $2
- WHERE id = $3;
- `;
- await db.query(updateScheduleQuery, [moment(template.last_checked_at || template.created_at).add(1, "day").format(TIME_FORMAT), nextEndDate.format(TIME_FORMAT), template.schedule_id]);
}
log(`(cron) Recurring tasks job ended with ${createdTaskCount} new tasks created.`);
diff --git a/worklenz-backend/src/passport/passport-strategies/passport-local-login.ts b/worklenz-backend/src/passport/passport-strategies/passport-local-login.ts
index 7d29fae8..d71c4a36 100644
--- a/worklenz-backend/src/passport/passport-strategies/passport-local-login.ts
+++ b/worklenz-backend/src/passport/passport-strategies/passport-local-login.ts
@@ -3,13 +3,16 @@ import { Strategy as LocalStrategy } from "passport-local";
import { log_error } from "../../shared/utils";
import db from "../../config/db";
import { Request } from "express";
+import { ERROR_KEY, SUCCESS_KEY } from "./passport-constants";
async function handleLogin(req: Request, email: string, password: string, done: any) {
- console.log("Login attempt for:", email);
+ // Clear any existing flash messages
+ (req.session as any).flash = {};
if (!email || !password) {
- console.log("Missing credentials");
- return done(null, false, { message: "Please enter both email and password" });
+ const errorMsg = "Please enter both email and password";
+ req.flash(ERROR_KEY, errorMsg);
+ return done(null, false);
}
try {
@@ -19,23 +22,27 @@ async function handleLogin(req: Request, email: string, password: string, done:
AND google_id IS NULL
AND is_deleted IS FALSE;`;
const result = await db.query(q, [email]);
- console.log("User query result count:", result.rowCount);
const [data] = result.rows;
if (!data?.password) {
- console.log("No account found");
- return done(null, false, { message: "No account found with this email" });
+ const errorMsg = "No account found with this email";
+ req.flash(ERROR_KEY, errorMsg);
+ return done(null, false);
}
const passwordMatch = bcrypt.compareSync(password, data.password);
- console.log("Password match:", passwordMatch);
if (passwordMatch && email === data.email) {
delete data.password;
- return done(null, data, {message: "User successfully logged in"});
+ const successMsg = "User successfully logged in";
+ req.flash(SUCCESS_KEY, successMsg);
+ return done(null, data);
}
- return done(null, false, { message: "Incorrect email or password" });
+
+ const errorMsg = "Incorrect email or password";
+ req.flash(ERROR_KEY, errorMsg);
+ return done(null, false);
} catch (error) {
console.error("Login error:", error);
log_error(error, req.body);
diff --git a/worklenz-backend/src/public/locales/alb/404-page.json b/worklenz-backend/src/public/locales/alb/404-page.json
new file mode 100644
index 00000000..a5e803fe
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/404-page.json
@@ -0,0 +1,4 @@
+{
+ "doesNotExistText": "Na vjen keq, faqja qรซ kรซrkoni nuk ekziston.",
+ "backHomeButton": "Kthehu nรซ Faqen Kryesore"
+}
diff --git a/worklenz-backend/src/public/locales/alb/account-setup.json b/worklenz-backend/src/public/locales/alb/account-setup.json
new file mode 100644
index 00000000..d5f624b3
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/account-setup.json
@@ -0,0 +1,31 @@
+{
+ "continue": "Vazhdo",
+
+ "setupYourAccount": "Konfiguro Llogarinรซ Tรซnde nรซ Worklenz.",
+ "organizationStepTitle": "Emรซrtoni Organizatรซn Tuaj",
+ "organizationStepLabel": "Zgjidhni njรซ emรซr pรซr llogarinรซ tuaj nรซ Worklenz.",
+
+ "projectStepTitle": "Krijoni projektin tuaj tรซ parรซ",
+ "projectStepLabel": "Nรซ cilin projekt po punoni aktualisht?",
+ "projectStepPlaceholder": "p.sh. Plani i Marketingut",
+
+ "tasksStepTitle": "Krijoni detyrat tuaja tรซ para",
+ "tasksStepLabel": "Shkruani disa detyra qรซ do tรซ kryeni nรซ",
+ "tasksStepAddAnother": "Shto njรซ tjetรซr",
+
+ "emailPlaceholder": "Adresa email",
+ "invalidEmail": "Ju lutemi vendosni njรซ adresรซ email tรซ vlefshme",
+ "or": "ose",
+ "templateButton": "Importo nga shablloni",
+ "goBack": "Kthehu Mbrapa",
+ "cancel": "Anulo",
+ "create": "Krijo",
+ "templateDrawerTitle": "Zgjidh nga shabllonet",
+ "step3InputLabel": "Fto me email",
+ "addAnother": "Shto njรซ tjetรซr",
+ "skipForNow": "Kalo tani pรซr tani",
+ "formTitle": "Krijoni detyrรซn tuaj tรซ parรซ.",
+ "step3Title": "Fto ekipin tรซnd tรซ punojรซ me",
+ "maxMembers": " (Mund tรซ ftoni deri nรซ 5 anรซtarรซ)",
+ "maxTasks": " (Mund tรซ krijoni deri nรซ 5 detyra)"
+}
diff --git a/worklenz-backend/src/public/locales/alb/admin-center/current-bill.json b/worklenz-backend/src/public/locales/alb/admin-center/current-bill.json
new file mode 100644
index 00000000..1f76f32b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/admin-center/current-bill.json
@@ -0,0 +1,113 @@
+{
+ "title": "Faturimet",
+ "currentBill": "Fatura Aktuale",
+ "configuration": "Konfigurimi",
+ "currentPlanDetails": "Detajet e Planit Aktual",
+ "upgradePlan": "Pรซrmirรซso Planin",
+ "cardBodyText01": "Provรซ falas",
+ "cardBodyText02": "(Plani juaj i provรซs skadon nรซ 1 muaj 19 ditรซ)",
+ "redeemCode": "Kodi i Zbritjes",
+ "accountStorage": "Depozita e Llogarisรซ",
+ "used": "Pรซrdorur:",
+ "remaining": "E mbetur:",
+ "charges": "Tarifat",
+ "tooltip": "Tarifat pรซr ciklin aktual tรซ faturimit",
+ "description": "Pรซrshkrimi",
+ "billingPeriod": "Periudha e Faturimit",
+ "billStatus": "Statusi i Faturรซs",
+ "perUserValue": "Vlera pรซr Pรซrdorues",
+ "users": "Pรซrdoruesit",
+
+ "amount": "Shuma",
+ "invoices": "Faturat",
+ "transactionId": "ID e Transaksionit",
+ "transactionDate": "Data e Transaksionit",
+ "paymentMethod": "Metoda e Pagesรซs",
+ "status": "Statusi",
+ "ltdUsers": "Mund tรซ shtoni deri nรซ {{ltd_users}} pรซrdorues.",
+
+ "totalSeats": "Vende totale",
+ "availableSeats": "Vende tรซ disponueshme",
+ "addMoreSeats": "Shto mรซ shumรซ vende",
+
+ "drawerTitle": "Kodi i Zbritjes",
+ "label": "Kodi i Zbritjes",
+ "drawerPlaceholder": "Vendosni kodin tuaj tรซ zbritjes",
+ "redeemSubmit": "Paraqit",
+
+ "modalTitle": "Zgjidhni planin mรซ tรซ mirรซ pรซr ekipin tuaj",
+ "seatLabel": "Numri i vendeve",
+ "freePlan": "Plan Falas",
+ "startup": "Startup",
+ "business": "Biznes",
+ "tag": "Mรซ i Popullarizuar",
+ "enterprise": "Ndรซrmarrje",
+
+ "freeSubtitle": "falas pรซrgjithmonรซ",
+ "freeUsers": "Mรซ e mira pรซr pรซrdorim personal",
+ "freeText01": "100MB depozitรซ",
+ "freeText02": "3 projekte",
+ "freeText03": "5 anรซtarรซ tรซ ekipit",
+
+ "startupSubtitle": "รMIM I RASTรSISHรM / muaj",
+ "startupUsers": "Deri nรซ 15 pรซrdorues",
+ "startupText01": "25GB depozitรซ",
+ "startupText02": "Projekte tรซ pakufizuara aktive",
+ "startupText03": "Orar",
+ "startupText04": "Raportim",
+ "startupText05": "Abonohu nรซ projekte",
+
+ "businessSubtitle": "pรซrdorues / muaj",
+ "businessUsers": "16 - 200 pรซrdorues",
+
+ "enterpriseUsers": "200 - 500+ pรซrdorues",
+
+ "footerTitle": "Ju lutemi na jepni njรซ numรซr kontakti qรซ mund tรซ pรซrdorim pรซr t'ju kontaktuar.",
+ "footerLabel": "Numri i Kontaktit",
+ "footerButton": "Na kontaktoni",
+
+ "redeemCodePlaceHolder": "Vendosni kodin tuaj tรซ zbritjes",
+ "submit": "Paraqit",
+
+ "trialPlan": "Provรซ Falas",
+ "trialExpireDate": "E vlefshme deri mรซ {{trial_expire_date}}",
+ "trialExpired": "Provat tuaja falas skaduan {{trial_expire_string}}",
+ "trialInProgress": "Provat tuaja falas skadojnรซ {{trial_expire_string}}",
+
+ "required": "Kjo fushรซ รซshtรซ e detyrueshme",
+ "invalidCode": "Kod i pavlefshรซm",
+
+ "selectPlan": "Zgjidhni planin mรซ tรซ mirรซ pรซr ekipin tuaj",
+ "changeSubscriptionPlan": "Ndryshoni planin tuaj tรซ abonimit",
+ "noOfSeats": "Numri i vendeve",
+ "annualPlan": "Pro - Vjetor",
+ "monthlyPlan": "Pro - Mujor",
+ "freeForever": "Falas Pรซrgjithmonรซ",
+ "bestForPersonalUse": "Mรซ e mira pรซr pรซrdorim personal",
+ "storage": "Depozitรซ",
+ "projects": "Projekte",
+ "teamMembers": "Anรซtarรซt e Ekipit",
+ "unlimitedTeamMembers": "Anรซtarรซ tรซ pakufizuar tรซ ekipit",
+ "unlimitedActiveProjects": "Projekte tรซ pakufizuara aktive",
+ "schedule": "Orar",
+ "reporting": "Raportim",
+ "subscribeToProjects": "Abonohu nรซ projekte",
+ "billedAnnually": "Faturuar รงdo vit",
+ "billedMonthly": "Faturuar รงdo muaj",
+
+ "pausePlan": "Pauzรซ Planin",
+ "resumePlan": "Rifillo Planin",
+ "changePlan": "Ndrysho Planin",
+ "cancelPlan": "Anulo Planin",
+
+ "perMonthPerUser": "pรซr pรซrdorues/muaj",
+ "viewInvoice": "Shiko Faturรซn",
+ "switchToFreePlan": "Kalo nรซ Planin Falas",
+
+ "expirestoday": "sot",
+ "expirestomorrow": "nesรซr",
+ "expiredDaysAgo": "{{days}} ditรซ mรซ parรซ",
+
+ "continueWith": "Vazhdo me {{plan}}",
+ "changeToPlan": "Ndrysho nรซ {{plan}}"
+}
diff --git a/worklenz-backend/src/public/locales/alb/admin-center/overview.json b/worklenz-backend/src/public/locales/alb/admin-center/overview.json
new file mode 100644
index 00000000..296eae4c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/admin-center/overview.json
@@ -0,0 +1,8 @@
+{
+ "overview": "Pรซrmbledhje",
+ "name": "Emri i Organizatรซs",
+ "owner": "Pronari i Organizatรซs",
+ "admins": "Administruesit e Organizatรซs",
+ "contactNumber": "Shto Numrin e Kontaktit",
+ "edit": "Redakto"
+}
diff --git a/worklenz-backend/src/public/locales/alb/admin-center/projects.json b/worklenz-backend/src/public/locales/alb/admin-center/projects.json
new file mode 100644
index 00000000..356aaec9
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/admin-center/projects.json
@@ -0,0 +1,12 @@
+{
+ "membersCount": "Numri i Anรซtarรซve",
+ "createdAt": "Krijuar mรซ",
+ "projectName": "Emri i Projektit",
+ "teamName": "Emri i Ekipit",
+ "refreshProjects": "Rifresko Projektet",
+ "searchPlaceholder": "Kรซrkoni sipas emrit tรซ projektit",
+ "deleteProject": "Jeni i sigurt qรซ dรซshironi tรซ fshini kรซtรซ projekt?",
+ "confirm": "Konfirmo",
+ "cancel": "Anulo",
+ "delete": "Fshi Projektin"
+}
diff --git a/worklenz-backend/src/public/locales/alb/admin-center/sidebar.json b/worklenz-backend/src/public/locales/alb/admin-center/sidebar.json
new file mode 100644
index 00000000..584a9a10
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/admin-center/sidebar.json
@@ -0,0 +1,8 @@
+{
+ "overview": "Pรซrmbledhje",
+ "users": "Pรซrdoruesit",
+ "teams": "Ekipet",
+ "billing": "Faturimi",
+ "projects": "Projektet",
+ "adminCenter": "Qendra Administrative"
+}
diff --git a/worklenz-backend/src/public/locales/alb/admin-center/teams.json b/worklenz-backend/src/public/locales/alb/admin-center/teams.json
new file mode 100644
index 00000000..de37bf7a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/admin-center/teams.json
@@ -0,0 +1,33 @@
+{
+ "title": "Ekipet",
+ "subtitle": "ekipet",
+ "tooltip": "Rifresko ekipet",
+ "placeholder": "Kรซrko sipas emrit",
+ "addTeam": "Shto Ekip",
+ "team": "Ekipi",
+ "membersCount": "Numri i Anรซtarรซve",
+ "members": "Anรซtarรซt",
+ "drawerTitle": "Krijo Ekip tรซ Ri",
+ "label": "Emri i Ekipit",
+ "drawerPlaceholder": "Emri",
+ "create": "Krijo",
+ "delete": "Fshi",
+ "settings": "Cilรซsimet",
+ "popTitle": "Jeni i sigurt?",
+ "message": "Ju lutemi shkruani njรซ Emรซr",
+ "teamSettings": "Cilรซsimet e Ekipit",
+ "teamName": "Emri i Ekipit",
+ "teamDescription": "Pรซrshkrimi i Ekipit",
+ "teamMembers": "Anรซtarรซt e Ekipit",
+ "teamMembersCount": "Numri i Anรซtarรซve tรซ Ekipit",
+ "teamMembersPlaceholder": "Kรซrko sipas emrit",
+ "addMember": "Shto Anรซtar",
+ "add": "Shto",
+ "update": "Pรซrditรซso",
+ "teamNamePlaceholder": "Emri i ekipit",
+ "user": "Pรซrdoruesi",
+ "role": "Roli",
+ "owner": "Pronari",
+ "admin": "Administruesi",
+ "member": "Anรซtari"
+}
diff --git a/worklenz-backend/src/public/locales/alb/admin-center/users.json b/worklenz-backend/src/public/locales/alb/admin-center/users.json
new file mode 100644
index 00000000..9cfe7956
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/admin-center/users.json
@@ -0,0 +1,9 @@
+{
+ "title": "Pรซrdoruesit",
+ "subTitle": "pรซrdoruesit",
+ "placeholder": "Kรซrko sipas emrit",
+ "user": "Pรซrdoruesi",
+ "email": "Email",
+ "lastActivity": "Aktiviteti i Fundit",
+ "refresh": "Rifresko pรซrdoruesit"
+}
diff --git a/worklenz-backend/src/public/locales/alb/all-project-list.json b/worklenz-backend/src/public/locales/alb/all-project-list.json
new file mode 100644
index 00000000..8079f13d
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/all-project-list.json
@@ -0,0 +1,34 @@
+{
+ "name": "Emri",
+ "client": "Klienti",
+ "category": "Kategoria",
+ "status": "Statusi",
+ "tasksProgress": "Pรซrparimi i Detyrave",
+ "updated_at": "E Pรซrditรซsuar sรซ Fundi",
+ "members": "Anรซtarรซt",
+ "setting": "Cilรซsimet",
+ "projects": "Projektet",
+ "refreshProjects": "Rifresko projektet",
+ "all": "Tรซ gjitha",
+ "favorites": "Tรซ preferuarit",
+ "archived": "E arkivuar",
+ "placeholder": "Kรซrko sipas emrit",
+ "archive": "Arkivo",
+ "unarchive": "รarkivo",
+ "archiveConfirm": "Jeni i sigurt qรซ dรซshironi tรซ arkivoni kรซtรซ projekt?",
+ "unarchiveConfirm": "Jeni i sigurt qรซ dรซshironi tรซ รงarkivoni kรซtรซ projekt?",
+ "yes": "Po",
+ "no": "Jo",
+ "clickToFilter": "Kliko pรซr tรซ filtruar sipas",
+ "noProjects": "Nuk u gjetรซn projekte",
+ "addToFavourites": "Shto te tรซ preferuarit",
+ "list": "Lista",
+ "group": "Grupi",
+ "listView": "Pamja e Listรซs",
+ "groupView": "Pamja e Grupit",
+ "groupBy": {
+ "category": "Kategoria",
+ "client": "Klienti"
+ },
+ "noPermission": "Nuk keni leje pรซr tรซ kryer kรซtรซ veprim"
+}
diff --git a/worklenz-backend/src/public/locales/alb/auth/auth-common.json b/worklenz-backend/src/public/locales/alb/auth/auth-common.json
new file mode 100644
index 00000000..5f687234
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/auth/auth-common.json
@@ -0,0 +1,5 @@
+{
+ "loggingOut": "Po dilni...",
+ "authenticating": "Po autentikoheni...",
+ "gettingThingsReady": "Po pรซrgatiten gjรซrat pรซr ju..."
+}
diff --git a/worklenz-backend/src/public/locales/alb/auth/forgot-password.json b/worklenz-backend/src/public/locales/alb/auth/forgot-password.json
new file mode 100644
index 00000000..2ee64388
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/auth/forgot-password.json
@@ -0,0 +1,12 @@
+{
+ "headerDescription": "Rivendosni fjalรซkalimin tuaj",
+ "emailLabel": "Email",
+ "emailPlaceholder": "Vendosni email-in tuaj",
+ "emailRequired": "Ju lutemi vendosni Email-in tuaj!",
+ "resetPasswordButton": "Rivendos Fjalรซkalimin",
+ "returnToLoginButton": "Kthehu te Hyrja",
+ "passwordResetSuccessMessage": "Njรซ lidhje pรซr rivendosjen e fjalรซkalimit รซshtรซ dรซrguar nรซ email-in tuaj.",
+ "orText": "OSE",
+ "successTitle": "U dรซrguan udhรซzimet pรซr rivendosje!",
+ "successMessage": "Informacioni pรซr rivendosje รซshtรซ dรซrguar nรซ email-in tuaj. Ju lutemi kontrolloni email-in."
+}
diff --git a/worklenz-backend/src/public/locales/alb/auth/login.json b/worklenz-backend/src/public/locales/alb/auth/login.json
new file mode 100644
index 00000000..668b4fdc
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/auth/login.json
@@ -0,0 +1,27 @@
+{
+ "headerDescription": "Hyni nรซ llogarinรซ tuaj",
+ "emailLabel": "Email",
+ "emailPlaceholder": "Vendosni email-in tuaj",
+ "emailRequired": "Ju lutemi vendosni Email-in tuaj!",
+ "passwordLabel": "Fjalรซkalimi",
+ "passwordPlaceholder": "Vendosni fjalรซkalimin",
+ "passwordRequired": "Ju lutemi vendosni Fjalรซkalimin!",
+ "rememberMe": "Mรซ mbaj mend",
+ "loginButton": "Hyr",
+ "signupButton": "Regjistrohu",
+ "forgotPasswordButton": "Keni harruar fjalรซkalimin?",
+ "signInWithGoogleButton": "Hyr me Google",
+ "dontHaveAccountText": "Nuk keni llogari?",
+ "orText": "OSE",
+ "successMessage": "Jeni futur me sukses!",
+ "loginError": "Hyrja dรซshtoi",
+ "googleLoginError": "Hyrja pรซrmes Google dรซshtoi",
+ "validationMessages": {
+ "email": "Ju lutemi vendosni njรซ adresรซ email tรซ vlefshme",
+ "password": "Fjalรซkalimi duhet tรซ jetรซ sรซ paku 8 karaktere"
+ },
+ "errorMessages": {
+ "loginErrorTitle": "Hyrja dรซshtoi",
+ "loginErrorMessage": "Ju lutemi kontrolloni email-in dhe fjalรซkalimin dhe provoni pรซrsรซri"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/alb/auth/signup.json b/worklenz-backend/src/public/locales/alb/auth/signup.json
new file mode 100644
index 00000000..1dac7a39
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/auth/signup.json
@@ -0,0 +1,29 @@
+{
+ "headerDescription": "Regjistrohuni pรซr tรซ filluar",
+ "nameLabel": "Emri i Plotรซ",
+ "namePlaceholder": "Shkruani emrin tuaj tรซ plotรซ",
+ "nameRequired": "Ju lutemi shkruani emrin tuaj tรซ plotรซ!",
+ "nameMinCharacterRequired": "Emri duhet tรซ jetรซ sรซ paku 4 karaktere!",
+ "emailLabel": "Email",
+ "emailPlaceholder": "Shkruani email-in tuaj",
+ "emailRequired": "Ju lutemi shkruani Email-in tuaj!",
+ "passwordLabel": "Fjalรซkalimi",
+ "passwordPlaceholder": "Krijoni njรซ fjalรซkalim",
+ "passwordRequired": "Ju lutemi krijoni njรซ Fjalรซkalim!",
+ "passwordMinCharacterRequired": "Fjalรซkalimi duhet tรซ jetรซ sรซ paku 8 karaktere!",
+ "passwordPatternRequired": "Fjalรซkalimi nuk plotรซson kรซrkesat!",
+ "strongPasswordPlaceholder": "Vendosni njรซ fjalรซkalim mรซ tรซ fortรซ",
+ "passwordValidationAltText": "Fjalรซkalimi duhet tรซ pรซrmbajรซ sรซ paku 8 karaktere me shkronja tรซ mรซdha dhe tรซ vogla, njรซ numรซr dhe njรซ simbol.",
+ "signupSuccessMessage": "Jeni regjistruar me sukses!",
+ "privacyPolicyLink": "Politika e Privatรซsisรซ",
+ "termsOfUseLink": "Kushtet e Pรซrdorimit",
+ "bySigningUpText": "Duke u regjistruar, ju pranoni",
+ "andText": "dhe",
+ "signupButton": "Regjistrohu",
+ "signInWithGoogleButton": "Hyr me Google",
+ "alreadyHaveAccountText": "Keni tashmรซ njรซ llogari?",
+ "loginButton": "Hyr",
+ "orText": "OSE",
+ "reCAPTCHAVerificationError": "Gabim nรซ Verifikimin e reCAPTCHA",
+ "reCAPTCHAVerificationErrorMessage": "Nuk mundรซm tรซ verifikojmรซ reCAPTCHA-n tuaj. Ju lutemi provoni pรซrsรซri."
+}
diff --git a/worklenz-backend/src/public/locales/alb/auth/verify-reset-email.json b/worklenz-backend/src/public/locales/alb/auth/verify-reset-email.json
new file mode 100644
index 00000000..16017318
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/auth/verify-reset-email.json
@@ -0,0 +1,14 @@
+{
+ "title": "Verifikoni Email-in pรซr Rivendosje",
+ "description": "Vendosni fjalรซkalimin tuaj tรซ ri",
+ "placeholder": "Vendosni fjalรซkalimin tuaj tรซ ri",
+ "confirmPasswordPlaceholder": "Konfirmoni fjalรซkalimin e ri",
+ "passwordHint": "Tรซ paktรซn 8 karaktere, me shkronja tรซ mรซdha dhe tรซ vogla, njรซ numรซr dhe njรซ simbol.",
+ "resetPasswordButton": "Rivendos fjalรซkalimin",
+ "orText": "Ose",
+ "resendResetEmail": "Dรซrgo pรซrsรซri email-in e rivendosjes",
+ "passwordRequired": "Ju lutemi vendosni fjalรซkalimin e ri",
+ "returnToLoginButton": "Kthehu te Hyrja",
+ "confirmPasswordRequired": "Ju lutemi konfirmoni fjalรซkalimin e ri",
+ "passwordMismatch": "Fjalรซkalimet nuk pรซrputhen"
+}
diff --git a/worklenz-backend/src/public/locales/alb/common.json b/worklenz-backend/src/public/locales/alb/common.json
new file mode 100644
index 00000000..5af25f69
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/common.json
@@ -0,0 +1,9 @@
+{
+ "login-success": "Hyrja u krye me sukses!",
+ "login-failed": "Hyrja dรซshtoi. Ju lutemi kontrolloni kredencialet dhe provoni pรซrsรซri.",
+ "signup-success": "Regjistrimi u krye me sukses! Mirรซ se erdhรซt.",
+ "signup-failed": "Regjistrimi dรซshtoi. Ju lutemi sigurohuni qรซ tรซ gjitha fushat e nevojshme janรซ plotรซsuar dhe provoni pรซrsรซri.",
+ "reconnecting": "Jeni shkรซputur nga serveri.",
+ "connection-lost": "Lidhja me serverin dรซshtoi. Ju lutemi kontrolloni lidhjen tuaj me internet.",
+ "connection-restored": "U lidhรซt me serverin me sukses"
+}
diff --git a/worklenz-backend/src/public/locales/alb/create-first-project-form.json b/worklenz-backend/src/public/locales/alb/create-first-project-form.json
new file mode 100644
index 00000000..80c3bb86
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/create-first-project-form.json
@@ -0,0 +1,13 @@
+{
+ "formTitle": "Krijoni projektin tuaj tรซ parรซ",
+ "inputLabel": "Nรซ cilin projekt po punoni aktualisht?",
+ "or": "ose",
+ "templateButton": "Importo nga shablloni",
+ "createFromTemplate": "Krijo nga shablloni",
+ "goBack": "Kthehu Mbrapa",
+ "continue": "Vazhdo",
+ "cancel": "Anulo",
+ "create": "Krijo",
+ "templateDrawerTitle": "Zgjidh nga shabllonet",
+ "createProject": "Krijo Projekt"
+}
diff --git a/worklenz-backend/src/public/locales/alb/create-first-tasks.json b/worklenz-backend/src/public/locales/alb/create-first-tasks.json
new file mode 100644
index 00000000..5e74d7d4
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/create-first-tasks.json
@@ -0,0 +1,7 @@
+{
+ "formTitle": "Krijo detyrรซn tรซnde tรซ parรซ.",
+ "inputLabel": "Shkruaj disa detyra qรซ do tรซ kryesh nรซ",
+ "addAnother": "Shto njรซ tjetรซr",
+ "goBack": "Kthehu mbrapa",
+ "continue": "Vazhdo"
+}
diff --git a/worklenz-backend/src/public/locales/alb/home.json b/worklenz-backend/src/public/locales/alb/home.json
new file mode 100644
index 00000000..58d26e0b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/home.json
@@ -0,0 +1,46 @@
+{
+ "todoList": {
+ "title": "Lista e Detyrave",
+ "refreshTasks": "Rifresko detyrat",
+ "addTask": "+ Shto Detyrรซ",
+ "noTasks": "Asnjรซ detyrรซ",
+ "pressEnter": "Shtyp",
+ "toCreate": "pรซr tรซ krijuar.",
+ "markAsDone": "Shรซno si tรซ pรซrfunduar"
+ },
+ "projects": {
+ "title": "Projektet",
+ "refreshProjects": "Rifresko projektet",
+ "noRecentProjects": "Aktualisht nuk jeni caktuar nรซ asnjรซ projekt.",
+ "noFavouriteProjects": "Asnjรซ projekt i shรซnuar si i preferuar.",
+ "recent": "Tรซ Fundit",
+ "favourites": "Tรซ Preferuarat"
+ },
+ "tasks": {
+ "assignedToMe": "Mรซ janรซ caktuar",
+ "assignedByMe": "I kam caktuar",
+ "all": "Tรซ Gjitha",
+ "today": "Sot",
+ "upcoming": "Ardhj",
+ "overdue": "Tรซ vonuara",
+ "noDueDate": "Pa afat",
+ "noTasks": "Asnjรซ detyrรซ pรซr tรซ shfaqur.",
+ "addTask": "+ Shto detyrรซ",
+ "name": "Emri",
+ "project": "Projekti",
+ "status": "Statusi",
+ "dueDate": "Afati",
+ "dueDatePlaceholder": "Cakto Afatin",
+ "tomorrow": "Nesรซr",
+ "nextWeek": "Javรซn e Ardhshme",
+ "nextMonth": "Muajin e Ardhshรซm",
+ "projectRequired": "Ju lutemi zgjidhni njรซ projekt",
+ "pressTabToSelectDueDateAndProject": "Shtyp Tab pรซr tรซ zgjedhur afatin dhe projektin",
+ "dueOn": "Detyrat me afat mรซ",
+ "taskRequired": "Ju lutemi shtoni njรซ detyrรซ",
+ "list": "Listรซ",
+ "calendar": "Kalendar",
+ "tasks": "Detyrat",
+ "refresh": "Rifresko"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/alb/invite-initial-team-members.json b/worklenz-backend/src/public/locales/alb/invite-initial-team-members.json
new file mode 100644
index 00000000..c86da726
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/invite-initial-team-members.json
@@ -0,0 +1,8 @@
+{
+ "formTitle": "Fto ekipin tรซnd tรซ punojรซ me",
+ "inputLabel": "Fto me email",
+ "addAnother": "Shto njรซ tjetรซr",
+ "goBack": "Kthehu mbrapa",
+ "continue": "Vazhdo",
+ "skipForNow": "Anashkalo tani pรซr tani"
+}
diff --git a/worklenz-backend/src/public/locales/alb/kanban-board.json b/worklenz-backend/src/public/locales/alb/kanban-board.json
new file mode 100644
index 00000000..def705aa
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/kanban-board.json
@@ -0,0 +1,30 @@
+{
+ "rename": "Riemรซrto",
+ "delete": "Fshi",
+ "addTask": "Shto Detyrรซ",
+ "addSectionButton": "Shto Seksion",
+ "changeCategory": "Ndrysho kategorinรซ",
+
+ "deleteTooltip": "Fshi",
+ "deleteConfirmationTitle": "Jeni i sigurt?",
+ "deleteConfirmationOk": "Po",
+ "deleteConfirmationCancel": "Anulo",
+
+ "dueDate": "Data e pรซrfundimit",
+ "cancel": "Anulo",
+
+ "today": "Sot",
+ "tomorrow": "Nesรซr",
+ "assignToMe": "Cakto mua",
+ "archive": "Arkivo",
+
+ "newTaskNamePlaceholder": "Shkruaj emrin e detyrรซs",
+ "newSubtaskNamePlaceholder": "Shkruaj emrin e nรซndetyrรซs",
+ "untitledSection": "Seksion pa titull",
+ "unmapped": "Pa hartรซ",
+ "clickToChangeDate": "Klikoni pรซr tรซ ndryshuar datรซn",
+ "noDueDate": "Pa datรซ pรซrfundimi",
+ "save": "Ruaj",
+ "clear": "Pastro",
+ "nextWeek": "Javรซn e ardhshme"
+}
diff --git a/worklenz-backend/src/public/locales/alb/license-expired.json b/worklenz-backend/src/public/locales/alb/license-expired.json
new file mode 100644
index 00000000..94abf5ae
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/license-expired.json
@@ -0,0 +1,6 @@
+{
+ "title": "Prova juaj e Worklenz ka skaduar!",
+ "subtitle": "Ju lutemi pรซrmirรซsoni tani.",
+ "button": "Pรซrmirรซso tani",
+ "checking": "Po kontrollohet statusi i abonimit..."
+}
diff --git a/worklenz-backend/src/public/locales/alb/navbar.json b/worklenz-backend/src/public/locales/alb/navbar.json
new file mode 100644
index 00000000..88c53de4
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/navbar.json
@@ -0,0 +1,31 @@
+{
+ "logoAlt": "Logoja e Worklenz",
+ "home": "Kryefaqja",
+ "projects": "Projektet",
+ "schedule": "Orari",
+ "reporting": "Raportimi",
+ "clients": "Klientรซt",
+ "teams": "Ekipet",
+ "labels": "Etiketa",
+ "jobTitles": "Tituj Pune",
+ "upgradePlan": "Pรซrmirรซso Abonimin",
+ "upgradePlanTooltip": "Pรซrmirรซso abonimin",
+ "invite": "Fto",
+ "inviteTooltip": "Fto anรซtarรซ tรซ ekipit tรซ bashkohen",
+ "switchTeamTooltip": "Ndrysho ekipin",
+ "help": "Ndihmรซ",
+ "notificationTooltip": "Shiko njoftimet",
+ "profileTooltip": "Shiko profilin",
+ "adminCenter": "Qendra Administrative",
+ "settings": "Cilรซsimet",
+ "logOut": "Dil",
+ "notificationsDrawer": {
+ "read": "Lexuara e njoftimet ",
+ "unread": "Njoftimet e palexuara",
+ "markAsRead": "Shรซno si tรซ lexuara",
+ "readAndJoin": "Lexo & Bashkohu",
+ "accept": "Prano",
+ "acceptAndJoin": "Prano & Bashkohu",
+ "noNotifications": "Asnjรซ njoftim"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/alb/organization-name-form.json b/worklenz-backend/src/public/locales/alb/organization-name-form.json
new file mode 100644
index 00000000..d01b09c8
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/organization-name-form.json
@@ -0,0 +1,5 @@
+{
+ "nameYourOrganization": "Emรซrtoni organizatรซn tuaj.",
+ "worklenzAccountTitle": "Zgjidhni njรซ emรซr pรซr llogarinรซ tuaj nรซ Worklenz.",
+ "continue": "Vazhdo"
+}
diff --git a/worklenz-backend/src/public/locales/alb/phases-drawer.json b/worklenz-backend/src/public/locales/alb/phases-drawer.json
new file mode 100644
index 00000000..cccda7d2
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/phases-drawer.json
@@ -0,0 +1,19 @@
+{
+ "configurePhases": "Konfiguro Fazat",
+ "phaseLabel": "Etiketa e Fazรซs",
+ "enterPhaseName": "Vendosni njรซ emรซr pรซr etiketรซn e fazรซs",
+ "addOption": "Shto Opsion",
+ "phaseOptions": "Opsionet e Fazรซs:",
+ "dragToReorderPhases": "Zvarrit fazat pรซr t'i rirenditur. รdo fazรซ mund tรซ ketรซ njรซ ngjyrรซ tรซ ndryshme.",
+ "enterNewPhaseName": "Shkruani emrin e fazรซs sรซ re...",
+ "addPhase": "Shto Fazรซ",
+ "noPhasesFound": "Nuk u gjetรซn faza. Krijoni fazรซn tuaj tรซ parรซ mรซ sipรซr.",
+ "deletePhase": "Fshi Fazรซn",
+ "deletePhaseConfirm": "Jeni tรซ sigurt qรซ doni tรซ fshini kรซtรซ fazรซ? Ky veprim nuk mund tรซ zhbรซhet.",
+ "rename": "Riemรซro",
+ "delete": "Fshi",
+ "enterPhaseName": "Shkruani emrin e fazรซs",
+ "selectColor": "Zgjidh ngjyrรซn",
+ "managePhases": "Menaxho Fazat",
+ "close": "Mbyll"
+}
diff --git a/worklenz-backend/src/public/locales/alb/project-drawer.json b/worklenz-backend/src/public/locales/alb/project-drawer.json
new file mode 100644
index 00000000..952dba7e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/project-drawer.json
@@ -0,0 +1,42 @@
+{
+ "createProject": "Krijo Projekt",
+ "editProject": "Modifiko Projektin",
+ "enterCategoryName": "Vendosni emรซr pรซr kategorinรซ",
+ "hitEnterToCreate": "Shtyp Enter pรซr tรซ krijuar!",
+ "enterNotes": "Shรซnime",
+ "youCanManageClientsUnderSettings": "Mund tรซ menaxhoni klientรซt nรซn Cilรซsimet",
+ "addCategory": "Shto kategori projektit",
+ "newCategory": "Kategori e Re",
+ "notes": "Shรซnime",
+ "startDate": "Data e Fillimit",
+ "endDate": "Data e Pรซrfundimit",
+ "estimateWorkingDays": "Vlerรซso ditรซt e punรซs",
+ "estimateManDays": "Vlerรซso ditรซt e punรซtorรซve",
+ "hoursPerDay": "Orรซ nรซ ditรซ",
+ "create": "Krijo",
+ "update": "Pรซrditรซso",
+ "delete": "Fshi",
+ "typeToSearchClients": "Shkruani pรซr tรซ kรซrkuar klientรซ",
+ "projectColor": "Ngjyra e Projektit",
+ "pleaseEnterAName": "Ju lutemi vendosni njรซ emรซr",
+ "enterProjectName": "Vendosni emrin e projektit",
+ "name": "Emri",
+ "status": "Statusi",
+ "health": "Gjendja",
+ "category": "Kategoria",
+ "projectManager": "Menaxheri i Projektit",
+ "client": "Klienti",
+ "deleteConfirmation": "Jeni i sigurt qรซ doni tรซ fshini?",
+ "deleteConfirmationDescription": "Kjo do tรซ fshijรซ tรซ gjitha tรซ dhรซnat e lidhura dhe nuk mund tรซ zhbรซhet.",
+ "yes": "Po",
+ "no": "Jo",
+ "createdAt": "Krijuar mรซ",
+ "updatedAt": "Pรซrditรซsuar mรซ",
+ "by": "nga",
+ "add": "Shto",
+ "asClient": "si klient",
+ "createClient": "Krijo klient",
+ "searchInputPlaceholder": "Kรซrko sipas emrit ose emailit",
+ "hoursPerDayValidationMessage": "Orรซt nรซ ditรซ duhet tรซ jenรซ njรซ numรซr midis 1 dhe 24",
+ "noPermission": "Nuk ka leje"
+}
diff --git a/worklenz-backend/src/public/locales/alb/project-view-files.json b/worklenz-backend/src/public/locales/alb/project-view-files.json
new file mode 100644
index 00000000..1a49c36a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/project-view-files.json
@@ -0,0 +1,14 @@
+{
+ "nameColumn": "Emri",
+ "attachedTaskColumn": "Detyra e Bashkangjitur",
+ "sizeColumn": "Madhรซsia",
+ "uploadedByColumn": "Ngarkuar Nga",
+ "uploadedAtColumn": "Ngarkuar Mรซ",
+ "fileIconAlt": "Ikona e skedarit",
+ "titleDescriptionText": "Tรซ gjitha bashkรซngjitjet e detyrave nรซ kรซtรซ projekt do tรซ shfahen kรซtu.",
+ "deleteConfirmationTitle": "Jeni i sigurt?",
+ "deleteConfirmationOk": "Po",
+ "deleteConfirmationCancel": "Anulo",
+ "segmentedTooltip": "Sรซ shpejti! Kaloni midis pamjes listรซ dhe pamjes miniaturash.",
+ "emptyText": "Nuk ka bashkรซngjitje nรซ projekt."
+}
diff --git a/worklenz-backend/src/public/locales/alb/project-view-insights.json b/worklenz-backend/src/public/locales/alb/project-view-insights.json
new file mode 100644
index 00000000..c7714578
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/project-view-insights.json
@@ -0,0 +1,41 @@
+{
+ "overview": {
+ "title": "Pรซrmbledhje",
+ "statusOverview": "Pรซrmbledhje Statusi",
+ "priorityOverview": "Pรซrmbledhje Prioriteti",
+ "lastUpdatedTasks": "Detyrat e Pรซrditรซsuara Sรซ Fundi"
+ },
+ "members": {
+ "title": "Anรซtarรซt",
+ "tooltip": "Anรซtarรซt",
+ "tasksByMembers": "Detyrat sipas anรซtarรซve",
+ "tasksByMembersTooltip": "Detyrat sipas anรซtarรซve",
+ "name": "Emri",
+ "taskCount": "Numri i Detyrave",
+ "contribution": "Kontributi",
+ "completed": "Tรซ Pรซrfunduara",
+ "incomplete": "Tรซ Papรซrfunduara",
+ "overdue": "Tรซ Vonuara",
+ "progress": "Progresi"
+ },
+ "tasks": {
+ "overdueTasks": "Detyrat e Vonuara",
+ "overLoggedTasks": "Detyrat me regjistrim tรซ tepรซrt",
+ "tasksCompletedEarly": "Detyrat e pรซrfunduara para afatit",
+ "tasksCompletedLate": "Detyrat e pรซrfunduara pas afatit",
+ "overLoggedTasksTooltip": "Detyrat me kohรซ tรซ regjistruar mbi kohรซn e vlerรซsuar",
+ "overdueTasksTooltip": "Detyrat qรซ kanรซ kaluar afatin e tyre"
+ },
+ "common": {
+ "seeAll": "Shiko tรซ gjitha",
+ "totalLoggedHours": "Orรซt totale tรซ regjistruara",
+ "totalEstimation": "Vlerรซsimi total",
+ "completedTasks": "Detyrat e pรซrfunduara",
+ "incompleteTasks": "Detyrat e papรซrfunduara",
+ "overdueTasks": "Detyrat e vonuara",
+ "overdueTasksTooltip": "Detyrat qรซ kanรซ kaluar afatin e tyre",
+ "totalLoggedHoursTooltip": "Vlerรซsimi dhe koha e regjistruar pรซr detyrat.",
+ "includeArchivedTasks": "Pรซrfshi Detyrat e Arkivuara",
+ "export": "Eksporto"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/alb/project-view-members.json b/worklenz-backend/src/public/locales/alb/project-view-members.json
new file mode 100644
index 00000000..239b77e9
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/project-view-members.json
@@ -0,0 +1,17 @@
+{
+ "nameColumn": "Emri",
+ "jobTitleColumn": "Titulli i Punรซs",
+ "emailColumn": "Email",
+ "tasksColumn": "Detyrat",
+ "taskProgressColumn": "Progresi i Detyrave",
+ "accessColumn": "Qasja",
+ "fileIconAlt": "Ikona e skedarit",
+ "deleteConfirmationTitle": "Jeni i sigurt?",
+ "deleteConfirmationOk": "Po",
+ "deleteConfirmationCancel": "Anulo",
+ "refreshButtonTooltip": "Rifresko anรซtarรซt",
+ "deleteButtonTooltip": "Hiq nga projekti",
+ "memberCount": "Anรซtar",
+ "membersCountPlural": "Anรซtarรซ",
+ "emptyText": "Nuk ka bashkรซngjitje nรซ projekt."
+}
diff --git a/worklenz-backend/src/public/locales/alb/project-view-updates.json b/worklenz-backend/src/public/locales/alb/project-view-updates.json
new file mode 100644
index 00000000..15a4ec1c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/project-view-updates.json
@@ -0,0 +1,6 @@
+{
+ "inputPlaceholder": "Shto njรซ koment..",
+ "addButton": "Shto",
+ "cancelButton": "Anulo",
+ "deleteButton": "Fshi"
+}
diff --git a/worklenz-backend/src/public/locales/alb/project-view.json b/worklenz-backend/src/public/locales/alb/project-view.json
new file mode 100644
index 00000000..2bc256fe
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/project-view.json
@@ -0,0 +1,14 @@
+{
+ "taskList": "Lista e Detyrave",
+ "board": "Tabela Kanban",
+ "insights": "Analiza",
+ "files": "Skedarรซ",
+ "members": "Anรซtarรซ",
+ "updates": "Pรซrditรซsime",
+ "projectView": "Pamja e Projektit",
+ "loading": "Duke ngarkuar projektin...",
+ "error": "Gabim nรซ ngarkimin e projektit",
+ "pinnedTab": "E fiksuar si tab i parazgjedhur",
+ "pinTab": "Fikso si tab i parazgjedhur",
+ "unpinTab": "Hiqe fiksimin e tab-it tรซ parazgjedhur"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/alb/project-view/import-task-templates.json b/worklenz-backend/src/public/locales/alb/project-view/import-task-templates.json
new file mode 100644
index 00000000..fab0381b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/project-view/import-task-templates.json
@@ -0,0 +1,11 @@
+{
+ "importTaskTemplate": "Importo Shabllon Detyrash",
+ "templateName": "Emri i Shabllonit",
+ "templateDescription": "Pรซrshkrimi i Shabllonit",
+ "selectedTasks": "Detyrat e Pรซrzgjedhura",
+ "tasks": "Detyrat",
+ "templates": "Shabllonet",
+ "remove": "Hiq",
+ "cancel": "Anulo",
+ "import": "Importo"
+}
diff --git a/worklenz-backend/src/public/locales/alb/project-view/project-member-drawer.json b/worklenz-backend/src/public/locales/alb/project-view/project-member-drawer.json
new file mode 100644
index 00000000..aa6637e1
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/project-view/project-member-drawer.json
@@ -0,0 +1,7 @@
+{
+ "title": "Anรซtarรซt e Projektit",
+ "searchLabel": "Shtoni anรซtarรซ duke shkruar emrin ose email-in e tyre",
+ "searchPlaceholder": "Shkruani emrin ose email-in",
+ "inviteAsAMember": "Fto si anรซtar",
+ "inviteNewMemberByEmail": "Fto anรซtar tรซ ri me email"
+}
diff --git a/worklenz-backend/src/public/locales/alb/project-view/project-view-header.json b/worklenz-backend/src/public/locales/alb/project-view/project-view-header.json
new file mode 100644
index 00000000..51d91ba1
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/project-view/project-view-header.json
@@ -0,0 +1,30 @@
+{
+ "importTasks": "Importo detyra",
+ "importTask": "Importo detyrรซ",
+ "createTask": "Krijo detyrรซ",
+ "settings": "Cilรซsimet",
+ "subscribe": "Abonohu",
+ "unsubscribe": "รabonohu",
+ "deleteProject": "Fshi projektin",
+ "startDate": "Data e fillimit",
+ "endDate": "Data e mbarimit",
+ "projectSettings": "Cilรซsimet e projektit",
+ "projectSummary": "Pรซrmbledhja e projektit",
+ "receiveProjectSummary": "Merrni njรซ pรซrmbledhje tรซ projektit รงdo mbrรซmje.",
+ "refreshProject": "Rifresko projektin",
+ "saveAsTemplate": "Ruaj si model",
+ "invite": "Fto",
+ "share": "Ndaj",
+ "subscribeTooltip": "Abonohu tek njoftimet e projektit",
+ "unsubscribeTooltip": "รabonohu nga njoftimet e projektit",
+ "refreshTooltip": "Rifresko tรซ dhรซnat e projektit",
+ "settingsTooltip": "Hap cilรซsimet e projektit",
+ "saveAsTemplateTooltip": "Ruaj kรซtรซ projekt si model",
+ "inviteTooltip": "Fto anรซtarรซ tรซ ekipit nรซ kรซtรซ projekt",
+ "createTaskTooltip": "Krijo njรซ detyrรซ tรซ re",
+ "importTaskTooltip": "Importo detyrรซ nga modeli",
+ "navigateBackTooltip": "Kthehu tek lista e projekteve",
+ "projectStatusTooltip": "Statusi i projektit",
+ "projectDatesInfo": "Informacion pรซr kohรซzgjatjen e projektit",
+ "projectCategoryTooltip": "Kategoria e projektit"
+}
diff --git a/worklenz-backend/src/public/locales/alb/project-view/save-as-template.json b/worklenz-backend/src/public/locales/alb/project-view/save-as-template.json
new file mode 100644
index 00000000..63d7ace8
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/project-view/save-as-template.json
@@ -0,0 +1,27 @@
+{
+ "title": "Ruaj si Shabllon",
+ "templateName": "Emri i Shabllonit",
+ "includes": "รfarรซ duhet tรซ pรซrfshihet nรซ shabllon nga projekti?",
+ "includesOptions": {
+ "statuses": "Statuset",
+ "phases": "Fazat",
+ "labels": "Etiketat"
+ },
+ "taskIncludes": "รfarรซ duhet tรซ pรซrfshihet nรซ shabllon nga detyrat?",
+ "taskIncludesOptions": {
+ "statuses": "Statuset",
+ "phases": "Fazat",
+ "labels": "Etiketat",
+ "name": "Emri",
+ "priority": "Prioriteti",
+ "status": "Statusi",
+ "phase": "Faza",
+ "label": "Etiketa",
+ "timeEstimate": "Vlerรซsimi i Kohรซs",
+ "description": "Pรซrshkrimi",
+ "subTasks": "Nรซndetyrat"
+ },
+ "cancel": "Anulo",
+ "save": "Ruaj",
+ "templateNamePlaceholder": "Shkruani emrin e shabllonit"
+}
diff --git a/worklenz-backend/src/public/locales/alb/reporting-members-drawer.json b/worklenz-backend/src/public/locales/alb/reporting-members-drawer.json
new file mode 100644
index 00000000..899e590e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/reporting-members-drawer.json
@@ -0,0 +1,90 @@
+{
+ "exportButton": "Eksporto",
+ "timeLogsButton": "Regjistrimet e Kohรซs",
+ "activityLogsButton": "Regjistrimet e Aktivitetit",
+ "tasksButton": "Detyrat",
+ "searchByNameInputPlaceholder": "Kรซrko sipas emrit",
+
+ "overviewTab": "Pรซrmbledhje",
+ "timeLogsTab": "Regjistrimet e Kohรซs",
+ "activityLogsTab": "Regjistrimet e Aktivitetit",
+ "tasksTab": "Detyrat",
+
+ "projectsText": "Projektet",
+ "totalTasksText": "Detyrat Gjithsej",
+ "assignedTasksText": "Detyrat e Caktuara",
+ "completedTasksText": "Detyrat e Pรซrfunduara",
+ "ongoingTasksText": "Detyrat nรซ Vazhdim",
+ "overdueTasksText": "Detyrat e Vonuara",
+ "loggedHoursText": "Orรซt e Regjistruara",
+
+ "tasksText": "Detyrat",
+ "allText": "Tรซ Gjitha",
+
+ "tasksByProjectsText": "Detyrat Sipas Projekteve",
+ "tasksByStatusText": "Detyrat Sipas Statusit",
+ "tasksByPriorityText": "Detyrat Sipas Prioritetit",
+
+ "todoText": "Pรซr Tรซ Bรซrรซ",
+ "doingText": "Duke bรซrรซ",
+ "doneText": "E Pรซrfunduar",
+ "lowText": "I Ulรซt",
+ "mediumText": "I Mesรซm",
+ "highText": "I Lartรซ",
+
+ "billableButton": "Fakturueshme",
+ "billableText": "Fakturueshme",
+ "nonBillableText": "Jo Fakturueshme",
+
+ "timeLogsEmptyPlaceholder": "Asnjรซ regjistrim kohe pรซr tรซ shfaqur",
+ "loggedText": "Regjistruar",
+ "forText": "pรซr",
+ "inText": "nรซ",
+ "updatedText": "Pรซrditรซsuar",
+ "fromText": "Nga",
+ "toText": "nรซ",
+ "withinText": "brenda",
+
+ "activityLogsEmptyPlaceholder": "Asnjรซ regjistrim aktiviteti pรซr tรซ shfaqur",
+
+ "filterByText": "Filtro sipas:",
+ "selectProjectPlaceholder": "Zgjidh Projektin",
+
+ "taskColumn": "Detyra",
+ "nameColumn": "Emri",
+ "projectColumn": "Projekti",
+ "statusColumn": "Statusi",
+ "priorityColumn": "Prioriteti",
+ "dueDateColumn": "Afati",
+ "completedDateColumn": "Data e Pรซrfundimit",
+ "estimatedTimeColumn": "Koha e Vlerรซsuar",
+ "loggedTimeColumn": "Koha e Regjistruar",
+ "overloggedTimeColumn": "Koha e Tepรซrt",
+ "daysLeftColumn": "Ditรซ tรซ Mbetura/Vonuar",
+ "startDateColumn": "Data e Fillimit",
+ "endDateColumn": "Data e Pรซrfundimit",
+ "actualTimeColumn": "Koha Aktuale",
+ "projectHealthColumn": "Gjendja e Projektit",
+ "categoryColumn": "Kategoria",
+ "projectManagerColumn": "Menaxheri i Projektit",
+
+ "tasksStatsOverviewDrawerTitle": "Detyrat e ",
+ "projectsStatsOverviewDrawerTitle": "Projektet e ",
+
+ "cancelledText": "Anuluar",
+ "blockedText": "E Bllokuar",
+ "onHoldText": "Nรซ Pritje",
+ "proposedText": "E Propozuar",
+ "inPlanningText": "Nรซ Planifikim",
+ "inProgressText": "Nรซ Progres",
+ "completedText": "E Pรซrfunduar",
+ "continuousText": "E Vazhdueshme",
+
+ "daysLeftText": "ditรซ tรซ mbetura",
+ "daysOverdueText": "ditรซ vonuar",
+
+ "notSetText": "Pa Caktuar",
+ "needsAttentionText": "Kรซrkon Vรซmendje",
+ "atRiskText": "Nรซ Rrezik",
+ "goodText": "Nรซ Rregull"
+}
diff --git a/worklenz-backend/src/public/locales/alb/reporting-members.json b/worklenz-backend/src/public/locales/alb/reporting-members.json
new file mode 100644
index 00000000..d88f0662
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/reporting-members.json
@@ -0,0 +1,35 @@
+{
+ "yesterdayText": "Dje",
+ "lastSevenDaysText": "7 Ditรซt e Fundit",
+ "lastWeekText": "Javรซn e Kaluar",
+ "lastThirtyDaysText": "30 Ditรซt e Fundit",
+ "lastMonthText": "Muajin e Kaluar",
+ "lastThreeMonthsText": "3 Muajt e Fundit",
+ "allTimeText": "Tรซ Gjitha",
+ "customRangeText": "Interval i Pรซrshtatur",
+ "startDateInputPlaceholder": "Data e fillimit",
+ "EndDateInputPlaceholder": "Data e pรซrfundimit",
+ "filterButton": "Filtro",
+
+ "membersTitle": "Anรซtarรซt",
+ "includeArchivedButton": "Pรซrfshij Projektet e Arkivuara",
+ "exportButton": "Eksporto",
+ "excelButton": "Excel",
+ "searchByNameInputPlaceholder": "Kรซrko sipas emrit",
+
+ "memberColumn": "Anรซtari",
+ "tasksProgressColumn": "Progresi i Detyrave",
+ "tasksAssignedColumn": "Detyrat e Caktuara",
+ "completedTasksColumn": "Detyrat e Pรซrfunduara",
+ "overdueTasksColumn": "Detyrat e Vonuara",
+ "ongoingTasksColumn": "Detyrat nรซ Vazhdim",
+
+ "tasksAssignedColumnTooltip": "Detyrat e caktuara nรซ intervalin e zgjedhur",
+ "overdueTasksColumnTooltip": "Detyrat e vonuara deri nรซ fund tรซ intervalit tรซ zgjedhur",
+ "completedTasksColumnTooltip": "Detyrat e pรซrfunduara nรซ intervalin e zgjedhur",
+ "ongoingTasksColumnTooltip": "Detyrat e filluara por jo tรซ pรซrfunduara ende",
+
+ "todoText": "Pรซr Tรซ Bรซrรซ",
+ "doingText": "Duke bรซrรซ",
+ "doneText": "E Pรซrfunduar"
+}
diff --git a/worklenz-backend/src/public/locales/alb/reporting-overview-drawer.json b/worklenz-backend/src/public/locales/alb/reporting-overview-drawer.json
new file mode 100644
index 00000000..9e4d9186
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/reporting-overview-drawer.json
@@ -0,0 +1,39 @@
+{
+ "exportButton": "Eksporto",
+ "projectsButton": "Projektet",
+ "membersButton": "Anรซtarรซt",
+ "searchByNameInputPlaceholder": "Kรซrko sipas emrit",
+
+ "overviewTab": "Pรซrmbledhje",
+ "projectsTab": "Projektet",
+ "membersTab": "Anรซtarรซt",
+
+ "projectsByStatusText": "Projektet Sipas Statusit",
+ "projectsByCategoryText": "Projektet Sipas Kategorisรซ",
+ "projectsByHealthText": "Projektet Sipas Gjendjes",
+
+ "projectsText": "Projektet",
+ "allText": "Tรซ Gjitha",
+
+ "cancelledText": "Anuluar",
+ "blockedText": "E Bllokuar",
+ "onHoldText": "Nรซ Pritje",
+ "proposedText": "E Propozuar",
+ "inPlanningText": "Nรซ Planifikim",
+ "inProgressText": "Nรซ Progres",
+ "completedText": "E Pรซrfunduar",
+ "continuousText": "E Vazhdueshme",
+
+ "notSetText": "Pa Caktuar",
+ "needsAttentionText": "Kรซrkon Vรซmendje",
+ "atRiskText": "Nรซ Rrezik",
+ "goodText": "Nรซ Rregull",
+
+ "nameColumn": "Emri",
+ "emailColumn": "Email",
+ "projectsColumn": "Projektet",
+ "tasksColumn": "Detyrat",
+ "overdueTasksColumn": "Detyrat e Vonuara",
+ "completedTasksColumn": "Detyrat e Pรซrfunduara",
+ "ongoingTasksColumn": "Detyrat nรซ Vazhdim"
+}
diff --git a/worklenz-backend/src/public/locales/alb/reporting-overview.json b/worklenz-backend/src/public/locales/alb/reporting-overview.json
new file mode 100644
index 00000000..b8977912
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/reporting-overview.json
@@ -0,0 +1,25 @@
+{
+ "overviewTitle": "Pรซrmbledhje",
+ "includeArchivedButton": "Pรซrfshij Projektet e Arkivuara",
+
+ "teamCount": "Ekip",
+ "teamCountPlural": "Ekipe",
+ "projectCount": "Projekt",
+ "projectCountPlural": "Projekte",
+ "memberCount": "Anรซtar",
+ "memberCountPlural": "Anรซtarรซ",
+ "activeProjectCount": "Projekt Aktiv",
+ "activeProjectCountPlural": "Projekte Aktive",
+ "overdueProjectCount": "Projekt i Vonuar",
+ "overdueProjectCountPlural": "Projekte tรซ Vonuara",
+ "unassignedMemberCount": "Anรซtar i Pacaktuar",
+ "unassignedMemberCountPlural": "Anรซtarรซ tรซ Pacaktuar",
+ "memberWithOverdueTaskCount": "Anรซtar me Detyrรซ tรซ Vonuar",
+ "memberWithOverdueTaskCountPlural": "Anรซtarรซ me Detyra tรซ Vonuara",
+
+ "teamsText": "Ekipet",
+
+ "nameColumn": "Emri",
+ "projectsColumn": "Projektet",
+ "membersColumn": "Anรซtarรซt"
+}
diff --git a/worklenz-backend/src/public/locales/alb/reporting-projects-drawer.json b/worklenz-backend/src/public/locales/alb/reporting-projects-drawer.json
new file mode 100644
index 00000000..fd3a380c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/reporting-projects-drawer.json
@@ -0,0 +1,59 @@
+{
+ "exportButton": "Eksporto",
+ "membersButton": "Anรซtarรซt",
+ "tasksButton": "Detyrat",
+ "searchByNameInputPlaceholder": "Kรซrko sipas emrit",
+
+ "overviewTab": "Pรซrmbledhje",
+ "membersTab": "Anรซtarรซt",
+ "tasksTab": "Detyrat",
+
+ "completedTasksText": "Detyrat e Pรซrfunduara",
+ "incompleteTasksText": "Detyrat e Papรซrfunduara",
+ "overdueTasksText": "Detyrat e Vonuara",
+ "allocatedHoursText": "Orรซt e Alokuara",
+ "loggedHoursText": "Orรซt e Regjistruara",
+
+ "tasksText": "Detyrat",
+ "allText": "Tรซ Gjitha",
+
+ "tasksByStatusText": "Detyrat Sipas Statusit",
+ "tasksByPriorityText": "Detyrat Sipas Prioritetit",
+ "tasksByDueDateText": "Detyrat Sipas Afatit",
+
+ "todoText": "Pรซr Tรซ Bรซrรซ",
+ "doingText": "Duke bรซrรซ",
+ "doneText": "E Pรซrfunduar",
+ "lowText": "I Ulรซt",
+ "mediumText": "I Mesรซm",
+ "highText": "I Lartรซ",
+ "completedText": "E Pรซrfunduar",
+ "upcomingText": "Nรซ Ardhje",
+ "overdueText": "E Vonuar",
+ "noDueDateText": "Pa Afat",
+
+ "nameColumn": "Emri",
+ "tasksCountColumn": "Numri i Detyrave",
+ "completedTasksColumn": "Detyrat e Pรซrfunduara",
+ "incompleteTasksColumn": "Detyrat e Papรซrfunduara",
+ "overdueTasksColumn": "Detyrat e Vonuara",
+ "contributionColumn": "Kontributi",
+ "progressColumn": "Progresi",
+ "loggedTimeColumn": "Koha e Regjistruar",
+ "taskColumn": "Detyra",
+ "projectColumn": "Projekti",
+ "statusColumn": "Statusi",
+ "priorityColumn": "Prioriteti",
+ "phaseColumn": "Faza",
+ "dueDateColumn": "Afati",
+ "completedDateColumn": "Data e Pรซrfundimit",
+ "estimatedTimeColumn": "Koha e Vlerรซsuar",
+ "overloggedTimeColumn": "Koha e Tepรซrt",
+ "completedOnColumn": "Pรซrfunduar Mรซ",
+ "daysOverdueColumn": "Ditรซ vonim",
+
+ "groupByText": "Grupo Sipas:",
+ "statusText": "Statusi",
+ "priorityText": "Prioriteti",
+ "phaseText": "Faza"
+}
diff --git a/worklenz-backend/src/public/locales/alb/reporting-projects-filters.json b/worklenz-backend/src/public/locales/alb/reporting-projects-filters.json
new file mode 100644
index 00000000..614d57f3
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/reporting-projects-filters.json
@@ -0,0 +1,35 @@
+{
+ "searchByNamePlaceholder": "Kรซrko sipas emrit",
+ "searchByCategoryPlaceholder": "Kรซrko sipas kategorisรซ",
+
+ "statusText": "Statusi",
+ "healthText": "Gjendja",
+ "categoryText": "Kategoria",
+ "projectManagerText": "Menaxheri i Projektit",
+ "showFieldsText": "Shfaq fushat",
+
+ "cancelledText": "Anuluar",
+ "blockedText": "E bllokuar",
+ "onHoldText": "Nรซ pritje",
+ "proposedText": "E propozuar",
+ "inPlanningText": "Nรซ planifikim",
+ "inProgressText": "Nรซ progres",
+ "completedText": "E pรซrfunduar",
+ "continuousText": "E vazhdueshme",
+
+ "notSetText": "Pa caktuar",
+ "needsAttentionText": "Kรซrkon vรซmendje",
+ "atRiskText": "Nรซ rrezik",
+ "goodText": "Nรซ rregull",
+
+ "nameText": "Projekti",
+ "estimatedVsActualText": "Vlerรซsuar vs Aktual",
+ "tasksProgressText": "Progresi i detyrave",
+ "lastActivityText": "Aktiviteti i fundit",
+ "datesText": "Datat e Fillimit/Pรซrfundimit",
+ "daysLeftText": "Ditรซ tรซ mbetura/vonuar",
+ "projectHealthText": "Gjendja e projektit",
+ "projectUpdateText": "Pรซrditรซsimi i projektit",
+ "clientText": "Klienti",
+ "teamText": "Ekipi"
+}
diff --git a/worklenz-backend/src/public/locales/alb/reporting-projects.json b/worklenz-backend/src/public/locales/alb/reporting-projects.json
new file mode 100644
index 00000000..c10e8f7a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/reporting-projects.json
@@ -0,0 +1,52 @@
+{
+ "projectCount": "Projekt",
+ "projectCountPlural": "Projekte",
+ "includeArchivedButton": "Pรซrfshij Projektet e Arkivuara",
+ "exportButton": "Eksporto",
+ "excelButton": "Excel",
+
+ "projectColumn": "Projekti",
+ "estimatedVsActualColumn": "Vlerรซsuar vs Aktual",
+ "tasksProgressColumn": "Progresi i Detyrave",
+ "lastActivityColumn": "Aktiviteti i Fundit",
+ "statusColumn": "Statusi",
+ "datesColumn": "Data e Fillimit/Pรซrfundimit",
+ "daysLeftColumn": "Ditรซ tรซ Mbetura/Vonuar",
+ "projectHealthColumn": "Gjendja e Projektit",
+ "categoryColumn": "Kategoria",
+ "projectUpdateColumn": "Pรซrditรซsimi i Projektit",
+ "clientColumn": "Klienti",
+ "teamColumn": "Ekipi",
+ "projectManagerColumn": "Menaxheri i Projektit",
+
+ "openButton": "Hap",
+
+ "estimatedText": "Vlerรซsuar",
+ "actualText": "Aktual",
+
+ "todoText": "Pรซr tรซ Bรซrรซ",
+ "doingText": "duke bรซrรซ",
+ "doneText": "E Pรซrfunduar",
+
+ "cancelledText": "Anuluar",
+ "blockedText": "E Bllokuar",
+ "onHoldText": "Nรซ Pritje",
+ "proposedText": "E Propozuar",
+ "inPlanningText": "Nรซ Planifikim",
+ "inProgressText": "Nรซ Progres",
+ "completedText": "E Pรซrfunduar",
+ "continuousText": "E Vazhdueshme",
+
+ "daysLeftText": "ditรซ tรซ mbetura",
+ "dayLeftText": "ditรซ e mbetur",
+ "daysOverdueText": "ditรซ vonuar",
+
+ "notSetText": "Pa Caktuar",
+ "needsAttentionText": "Kรซrkon Vรซmendje",
+ "atRiskText": "Nรซ Rrezik",
+ "goodText": "Nรซ Rregull",
+
+ "setCategoryText": "Cakto Kategorinรซ",
+ "searchByNameInputPlaceholder": "Kรซrko sipas emrit",
+ "todayText": "Sot"
+}
diff --git a/worklenz-backend/src/public/locales/alb/reporting-sidebar.json b/worklenz-backend/src/public/locales/alb/reporting-sidebar.json
new file mode 100644
index 00000000..a8c14e68
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/reporting-sidebar.json
@@ -0,0 +1,8 @@
+{
+ "overview": "Pรซrmbledhje",
+ "projects": "Projektet",
+ "members": "Anรซtarรซt",
+ "timeReports": "Raportet e Kohรซs",
+ "estimateVsActual": "Vlerรซsimi vs Aktual",
+ "currentOrganizationTooltip": "Organizata aktuale"
+}
diff --git a/worklenz-backend/src/public/locales/alb/schedule.json b/worklenz-backend/src/public/locales/alb/schedule.json
new file mode 100644
index 00000000..a5670aaa
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/schedule.json
@@ -0,0 +1,39 @@
+{
+ "today": "Sot",
+ "week": "Javรซ",
+ "month": "Muaj",
+
+ "settings": "Cilรซsimet",
+ "workingDays": "Ditรซt e punรซs",
+ "monday": "E hรซnรซ",
+ "tuesday": "E martรซ",
+ "wednesday": "E mรซrkurรซ",
+ "thursday": "E enjte",
+ "friday": "E premte",
+ "saturday": "E shtunรซ",
+ "sunday": "E diel",
+ "workingHours": "Orรซt e punรซs",
+ "hours": "Orรซ",
+ "saveButton": "Ruaj",
+
+ "totalAllocation": "Alokimi Total",
+ "timeLogged": "Koha e Regjistruar",
+ "remainingTime": "Koha e Mbetur",
+ "total": "Total",
+ "perDay": "Nรซ Ditรซ",
+ "tasks": "detyra",
+ "startDate": "Data e Fillimit",
+ "endDate": "Data e Pรซrfundimit",
+
+ "hoursPerDay": "Orรซ Nรซ Ditรซ",
+ "totalHours": "Orรซ Totale",
+ "deleteButton": "Fshi",
+ "cancelButton": "Anulo",
+
+ "tabTitle": "Detyra pa Data Fillimi & Pรซrfundimi",
+
+ "allocatedTime": "Koha e alokuar",
+ "totalLogged": "Total i Regjistruar",
+ "loggedBillable": "Regjistruar Fakturueshme",
+ "loggedNonBillable": "Regjistruar Jo Fakturueshme"
+}
diff --git a/worklenz-backend/src/public/locales/alb/settings/categories.json b/worklenz-backend/src/public/locales/alb/settings/categories.json
new file mode 100644
index 00000000..62eb60d5
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/settings/categories.json
@@ -0,0 +1,10 @@
+{
+ "categoryColumn": "Kategoria",
+ "deleteConfirmationTitle": "Jeni tรซ sigurt?",
+ "deleteConfirmationOk": "Po",
+ "deleteConfirmationCancel": "Anulo",
+ "associatedTaskColumn": "Projektet e Lidhura",
+ "searchPlaceholder": "Kรซrko sipas emrit",
+ "emptyText": "Kategoritรซ mund tรซ krijohen gjatรซ pรซrditรซsimit ose krijimit tรซ projekteve.",
+ "colorChangeTooltip": "Klikoni pรซr tรซ ndryshuar ngjyrรซn"
+}
diff --git a/worklenz-backend/src/public/locales/alb/settings/change-password.json b/worklenz-backend/src/public/locales/alb/settings/change-password.json
new file mode 100644
index 00000000..ac1500bd
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/settings/change-password.json
@@ -0,0 +1,15 @@
+{
+ "title": "Ndrysho Fjalรซkalimin",
+ "currentPassword": "Fjalรซkalimi Aktual",
+ "newPassword": "Fjalรซkalimi i Ri",
+ "confirmPassword": "Konfirmo Fjalรซkalimin",
+ "currentPasswordPlaceholder": "Vendosni fjalรซkalimin aktual",
+ "newPasswordPlaceholder": "Fjalรซkalimi i Ri",
+ "confirmPasswordPlaceholder": "Konfirmo Fjalรซkalimin",
+ "currentPasswordRequired": "Ju lutemi vendosni fjalรซkalimin aktual!",
+ "newPasswordRequired": "Ju lutemi vendosni fjalรซkalimin e ri!",
+ "passwordValidationError": "Fjalรซkalimi duhet tรซ pรซrmbajรซ tรซ paktรซn 8 karaktere, me njรซ shkronjรซ tรซ madhe, njรซ numรซr dhe njรซ simbol.",
+ "passwordMismatch": "Fjalรซkalimet nuk pรซrputhen!",
+ "passwordRequirements": "Fjalรซkalimi i ri duhet tรซ jetรซ sรซ paku 8 karaktere, me njรซ shkronjรซ tรซ madhe, njรซ numรซr dhe njรซ simbol.",
+ "updateButton": "Pรซrditรซso Fjalรซkalimin"
+}
diff --git a/worklenz-backend/src/public/locales/alb/settings/clients.json b/worklenz-backend/src/public/locales/alb/settings/clients.json
new file mode 100644
index 00000000..72407a5e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/settings/clients.json
@@ -0,0 +1,22 @@
+{
+ "nameColumn": "Emri",
+ "projectColumn": "Projekti",
+ "noProjectsAvailable": "Nuk ka projekte tรซ disponueshme",
+ "deleteConfirmationTitle": "Jeni i sigurt?",
+ "deleteConfirmationOk": "Po",
+ "deleteConfirmationCancel": "Anulo",
+ "searchPlaceholder": "Kรซrko sipas emrit",
+ "createClient": "Krijo Klient",
+ "pinTooltip": "Klikoni pรซr ta fiksuar nรซ menynรซ kryesore",
+ "createClientDrawerTitle": "Krijo Klient",
+ "updateClientDrawerTitle": "Pรซrditรซso Klientin",
+ "nameLabel": "Emri",
+ "namePlaceholder": "Emri",
+ "nameRequiredError": "Ju lutemi shkruani njรซ Emรซr",
+ "createButton": "Krijo",
+ "updateButton": "Pรซrditรซso",
+ "createClientSuccessMessage": "Klienti u krijua me sukses!",
+ "createClientErrorMessage": "Krijimi i klientit dรซshtoi!",
+ "updateClientSuccessMessage": "Klienti u pรซrditรซsua me sukses!",
+ "updateClientErrorMessage": "Pรซrditรซsimi i klientit dรซshtoi!"
+}
diff --git a/worklenz-backend/src/public/locales/alb/settings/job-titles.json b/worklenz-backend/src/public/locales/alb/settings/job-titles.json
new file mode 100644
index 00000000..a464716a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/settings/job-titles.json
@@ -0,0 +1,20 @@
+{
+ "nameColumn": "Emri",
+ "deleteConfirmationTitle": "Jeni i sigurt?",
+ "deleteConfirmationOk": "Po",
+ "deleteConfirmationCancel": "Anulo",
+ "searchPlaceholder": "Kรซrko sipas emrit",
+ "createJobTitleButton": "Krijo Titull Pune",
+ "pinTooltip": "Klikoni pรซr ta fiksuar nรซ menynรซ kryesore",
+ "createJobTitleDrawerTitle": "Krijo Titull Pune",
+ "updateJobTitleDrawerTitle": "Pรซrditรซso Titullin e Punรซs",
+ "nameLabel": "Emri",
+ "namePlaceholder": "Emri",
+ "nameRequiredError": "Ju lutemi shkruani njรซ Emรซr",
+ "createButton": "Krijo",
+ "updateButton": "Pรซrditรซso",
+ "createJobTitleSuccessMessage": "Titulli i punรซs u krijua me sukses!",
+ "createJobTitleErrorMessage": "Krijimi i titullit tรซ punรซs dรซshtoi!",
+ "updateJobTitleSuccessMessage": "Titulli i punรซs u pรซrditรซsua me sukses!",
+ "updateJobTitleErrorMessage": "Pรซrditรซsimi i titullit tรซ punรซs dรซshtoi!"
+}
diff --git a/worklenz-backend/src/public/locales/alb/settings/labels.json b/worklenz-backend/src/public/locales/alb/settings/labels.json
new file mode 100644
index 00000000..40e6361b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/settings/labels.json
@@ -0,0 +1,11 @@
+{
+ "labelColumn": "Etiketa",
+ "deleteConfirmationTitle": "Jeni i sigurt?",
+ "deleteConfirmationOk": "Po",
+ "deleteConfirmationCancel": "Anulo",
+ "associatedTaskColumn": "Numri i Detyrave tรซ Lidhura",
+ "searchPlaceholder": "Kรซrko sipas emrit",
+ "emptyText": "Etiketat mund tรซ krijohen gjatรซ pรซrditรซsimit ose krijimit tรซ detyrave.",
+ "pinTooltip": "Klikoni pรซr ta fiksuar nรซ menynรซ kryesore",
+ "colorChangeTooltip": "Klikoni pรซr tรซ ndryshuar ngjyrรซn"
+}
diff --git a/worklenz-backend/src/public/locales/alb/settings/language.json b/worklenz-backend/src/public/locales/alb/settings/language.json
new file mode 100644
index 00000000..7c0d3756
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/settings/language.json
@@ -0,0 +1,7 @@
+{
+ "language": "Gjuha",
+ "language_required": "Gjuha รซshtรซ e detyrueshme",
+ "time_zone": "Zona kohore",
+ "time_zone_required": "Zona kohore รซshtรซ e detyrueshme",
+ "save_changes": "Ruaj Ndryshimet"
+}
diff --git a/worklenz-backend/src/public/locales/alb/settings/notifications.json b/worklenz-backend/src/public/locales/alb/settings/notifications.json
new file mode 100644
index 00000000..4bfd55b2
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/settings/notifications.json
@@ -0,0 +1,11 @@
+{
+ "title": "Cilรซsimet e Njoftimeve",
+ "emailTitle": "Mรซ dรซrgo njoftime me email",
+ "emailDescription": "Kjo pรซrfshin caktimet e reja tรซ detyrave",
+ "dailyDigestTitle": "Mรซ dรซrgo njรซ pรซrmbledhje ditore",
+ "dailyDigestDescription": "รdo mbrรซmje, do tรซ merrni njรซ pรซrmbledhje tรซ aktivitetit tรซ fundit nรซ detyra.",
+ "popupTitle": "Shfaq njoftimet nรซ kompjuterin tim kur Worklenz รซshtรซ i hapur",
+ "popupDescription": "Njoftimet e shfaqura mund tรซ รงaktivizohen nga shfletuesi juaj. Ndryshoni cilรซsimet e shfletuesit pรซr t'i lejuar ato.",
+ "unreadItemsTitle": "Shfaq numrin e artikujve tรซ palexuar",
+ "unreadItemsDescription": "Do tรซ shihni numรซrimin pรซr รงdo njoftim."
+}
diff --git a/worklenz-backend/src/public/locales/alb/settings/profile.json b/worklenz-backend/src/public/locales/alb/settings/profile.json
new file mode 100644
index 00000000..dcce50d5
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/settings/profile.json
@@ -0,0 +1,14 @@
+{
+ "uploadError": "Mund tรซ ngarkoni vetรซm skedarรซ JPG/PNG!",
+ "uploadSizeError": "Imazhi duhet tรซ jetรซ mรซ i vogรซl se 2MB!",
+ "upload": "Ngarko",
+ "nameLabel": "Emri",
+ "nameRequiredError": "Emri รซshtรซ i detyrueshรซm",
+ "emailLabel": "Email",
+ "emailRequiredError": "Email-i รซshtรซ i detyrueshรซm",
+ "saveChanges": "Ruaj Ndryshimet",
+ "profileJoinedText": "U bashkua njรซ muaj mรซ parรซ",
+ "profileLastUpdatedText": "Pรซrditรซsuar njรซ muaj mรซ parรซ",
+ "avatarTooltip": "Klikoni pรซr tรซ ngarkuar njรซ avatar",
+ "title": "Cilรซsimet e Profilit"
+}
diff --git a/worklenz-backend/src/public/locales/alb/settings/project-templates.json b/worklenz-backend/src/public/locales/alb/settings/project-templates.json
new file mode 100644
index 00000000..ac0a87ef
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/settings/project-templates.json
@@ -0,0 +1,8 @@
+{
+ "nameColumn": "Emri",
+ "editToolTip": "Modifiko",
+ "deleteToolTip": "Fshi",
+ "confirmText": "Jeni i sigurt?",
+ "okText": "Po",
+ "cancelText": "Anulo"
+}
diff --git a/worklenz-backend/src/public/locales/alb/settings/sidebar.json b/worklenz-backend/src/public/locales/alb/settings/sidebar.json
new file mode 100644
index 00000000..a2b6dd2e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/settings/sidebar.json
@@ -0,0 +1,14 @@
+{
+ "profile": "Profili",
+ "notifications": "Njoftimet",
+ "clients": "Klientรซt",
+ "job-titles": "Tituj Pune",
+ "labels": "Etiketa",
+ "categories": "Kategoritรซ",
+ "project-templates": "Shabllonet e Projekteve",
+ "task-templates": "Shabllonet e Detyrave",
+ "team-members": "Anรซtarรซt e Ekipit",
+ "teams": "Ekipet",
+ "change-password": "Ndrysho Fjalรซkalimin",
+ "language-and-region": "Gjuha dhe Rajoni"
+}
diff --git a/worklenz-backend/src/public/locales/alb/settings/task-templates.json b/worklenz-backend/src/public/locales/alb/settings/task-templates.json
new file mode 100644
index 00000000..b053027c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/settings/task-templates.json
@@ -0,0 +1,9 @@
+{
+ "nameColumn": "Emri",
+ "createdColumn": "Krijuar",
+ "editToolTip": "Redakto",
+ "deleteToolTip": "Fshi",
+ "confirmText": "Jeni i sigurt?",
+ "okText": "Po",
+ "cancelText": "Anulo"
+}
diff --git a/worklenz-backend/src/public/locales/alb/settings/team-members.json b/worklenz-backend/src/public/locales/alb/settings/team-members.json
new file mode 100644
index 00000000..955954dc
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/settings/team-members.json
@@ -0,0 +1,47 @@
+{
+ "title": "Anรซtarรซt e Ekipit",
+ "nameColumn": "Emri",
+ "projectsColumn": "Projektet",
+ "emailColumn": "Email",
+ "teamAccessColumn": "Qasja nรซ Ekip",
+ "memberCount": "Anรซtar",
+ "membersCountPlural": "Anรซtarรซ",
+ "searchPlaceholder": "Kรซrko anรซtarรซ sipas emrit",
+ "pinTooltip": "Rifresko listรซn e anรซtarรซve",
+ "addMemberButton": "Shto Anรซtar tรซ Ri",
+ "editTooltip": "Modifiko anรซtarin",
+ "deactivateTooltip": "รaktivizo anรซtarin",
+ "activateTooltip": "Aktivizo anรซtarin",
+ "deleteTooltip": "Fshi anรซtarin",
+ "confirmDeleteTitle": "Jeni i sigurt qรซ doni tรซ fshini kรซtรซ anรซtar?",
+ "confirmActivateTitle": "Jeni i sigurt qรซ doni tรซ ndryshoni statusin e kรซtij anรซtari?",
+ "okText": "Po, vazhdo",
+ "cancelText": "Jo, anulo",
+ "deactivatedText": "(Aktualisht i รงaktivizuar)",
+ "pendingInvitationText": "(Ftesรซ nรซ pritje)",
+ "addMemberDrawerTitle": "Shto Anรซtar tรซ Ri nรซ Ekip",
+ "updateMemberDrawerTitle": "Pรซrditรซso Anรซtarin e Ekipit",
+ "addMemberEmailHint": "Anรซtarรซt do tรซ shtohen nรซ ekip pavarรซsisht nga statusi i pranimit tรซ ftesรซs",
+ "memberEmailLabel": "Email(o)",
+ "memberEmailPlaceholder": "Vendos adresรซn email tรซ anรซtarit tรซ ekipit",
+ "memberEmailRequiredError": "Ju lutemi vendosni njรซ adresรซ email tรซ vlefshme",
+ "jobTitleLabel": "Titulli i Punรซs",
+ "jobTitlePlaceholder": "Zgjidh ose kรซrko titull pune (Opsionale)",
+ "memberAccessLabel": "Niveli i Qasjes",
+ "addToTeamButton": "Shto Anรซtar nรซ Ekip",
+ "updateButton": "Ruaj Ndryshimet",
+ "resendInvitationButton": "Dรซrgo Pรซrsรซri Email-in e Ftesรซs",
+ "invitationSentSuccessMessage": "Ftesa pรซr ekip u dรซrgua me sukses!",
+ "createMemberSuccessMessage": "Anรซtari i ri i ekipit u shtua me sukses!",
+ "createMemberErrorMessage": "Dรซshtoi shtimi i anรซtarit tรซ ri. Ju lutemi provoni pรซrsรซri.",
+ "updateMemberSuccessMessage": "Anรซtari i ekipit u pรซrditรซsua me sukses!",
+ "updateMemberErrorMessage": "Dรซshtoi pรซrditรซsimi i anรซtarit. Ju lutemi provoni pรซrsรซri.",
+ "memberText": "Anรซtar",
+ "adminText": "Administrues",
+ "ownerText": "Pronar i Ekipit",
+ "addedText": "Shtuar",
+ "updatedText": "Pรซrditรซsuar",
+ "noResultFound": "Shkruani njรซ adresรซ email dhe shtypni Enter...",
+ "jobTitlesFetchError": "Dรซshtoi marrja e titujve tรซ punรซs",
+ "invitationResent": "Ftesa u dรซrgua sรซrish me sukses!"
+}
diff --git a/worklenz-backend/src/public/locales/alb/settings/teams.json b/worklenz-backend/src/public/locales/alb/settings/teams.json
new file mode 100644
index 00000000..30f87d79
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/settings/teams.json
@@ -0,0 +1,16 @@
+{
+ "title": "Ekipet",
+ "team": "Ekip",
+ "teams": "Ekipet",
+ "name": "Emri",
+ "created": "Krijuar",
+ "ownsBy": "I pรซrket",
+ "edit": "Ndrysho",
+ "editTeam": "Ndrysho Ekipin",
+ "pinTooltip": "Kliko pรซr ta fiksuar nรซ menunรซ kryesore",
+ "editTeamName": "Ndrysho Emrin e Ekipit",
+ "updateName": "Pรซrditรซso Emrin",
+ "namePlaceholder": "Emri",
+ "nameRequired": "Ju lutem shkruani njรซ Emรซr",
+ "updateFailed": "Ndryshimi i emrit tรซ ekipit dรซshtoi!"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/alb/task-drawer/task-drawer-info-tab.json b/worklenz-backend/src/public/locales/alb/task-drawer/task-drawer-info-tab.json
new file mode 100644
index 00000000..75e1226a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/task-drawer/task-drawer-info-tab.json
@@ -0,0 +1,29 @@
+{
+ "details": {
+ "task-key": "รelรซsi i Detyrรซs",
+ "phase": "Faza",
+ "assignees": "Pรซrgjegjรซsit",
+ "due-date": "Data e Pรซrfundimit",
+ "time-estimation": "Vlerรซsimi i Kohรซs",
+ "priority": "Prioriteti",
+ "labels": "Etiketa",
+ "billable": "Fakturueshme",
+ "notify": "Njofto",
+ "when-done-notify": "Kur tรซ pรซrfundojรซ, njofto",
+ "start-date": "Data e Fillimit",
+ "end-date": "Data e Pรซrfundimit",
+ "hide-start-date": "Fshih Datรซn e Fillimit",
+ "show-start-date": "Shfaq Datรซn e Fillimit",
+ "hours": "Orรซ",
+ "minutes": "Minuta"
+ },
+ "description": {
+ "title": "Pรซrshkrimi",
+ "placeholder": "Shtoni njรซ pรซrshkrim mรซ tรซ detajuar..."
+ },
+ "subTasks": {
+ "title": "Nรซn-Detyrat",
+ "add-sub-task": "+ Shto Nรซn-Detyrรซ",
+ "refresh-sub-tasks": "Rifresko Nรซn-Detyrat"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/alb/task-drawer/task-drawer.json b/worklenz-backend/src/public/locales/alb/task-drawer/task-drawer.json
new file mode 100644
index 00000000..9d6c022f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/task-drawer/task-drawer.json
@@ -0,0 +1,123 @@
+{
+ "taskHeader": {
+ "taskNamePlaceholder": "Shkruani Detyrรซn tuaj",
+ "deleteTask": "Fshi Detyrรซn"
+ },
+ "taskInfoTab": {
+ "title": "Informacioni",
+ "details": {
+ "title": "Detajet",
+ "task-key": "รelรซsi i Detyrรซs",
+ "phase": "Faza",
+ "assignees": "Tรซ Caktuar",
+ "due-date": "Data e Pรซrfundimit",
+ "time-estimation": "Vlerรซsimi i Kohรซs",
+ "priority": "Prioriteti",
+ "labels": "Etiketat",
+ "billable": "E Faturueshme",
+ "notify": "Njofto",
+ "when-done-notify": "Kur pรซrfundon, njofto",
+ "start-date": "Data e Fillimit",
+ "end-date": "Data e Pรซrfundimit",
+ "hide-start-date": "Fshih Datรซn e Fillimit",
+ "show-start-date": "Shfaq Datรซn e Fillimit",
+ "hours": "Orรซ",
+ "minutes": "Minuta",
+ "progressValue": "Vlera e Progresit",
+ "progressValueTooltip": "Vendosni pรซrqindjen e progresit (0-100%)",
+ "progressValueRequired": "Ju lutemi vendosni njรซ vlerรซ progresi",
+ "progressValueRange": "Progresi duhet tรซ jetรซ midis 0 dhe 100",
+ "taskWeight": "Pesha e Detyrรซs",
+ "taskWeightTooltip": "Vendosni peshรซn e kรซsaj nรซndetyre (pรซrqindje)",
+ "taskWeightRequired": "Ju lutemi vendosni njรซ peshรซ detyre",
+ "taskWeightRange": "Pesha duhet tรซ jetรซ midis 0 dhe 100",
+ "recurring": "E Pรซrsรซritur"
+ },
+ "labels": {
+ "labelInputPlaceholder": "Kรซrko ose krijo",
+ "labelsSelectorInputTip": "Shtyp Enter pรซr tรซ krijuar"
+ },
+ "description": {
+ "title": "Pรซrshkrimi",
+ "placeholder": "Shto njรซ pรซrshkrim mรซ tรซ detajuar..."
+ },
+ "subTasks": {
+ "title": "Nรซndetyrat",
+ "addSubTask": "Shto Nรซndetyrรซ",
+ "addSubTaskInputPlaceholder": "Shkruani detyrรซn tuaj dhe shtypni enter",
+ "refreshSubTasks": "Rifresko Nรซndetyrat",
+ "edit": "Modifiko",
+ "delete": "Fshi",
+ "confirmDeleteSubTask": "Jeni i sigurt qรซ doni tรซ fshini kรซtรซ nรซndetyrรซ?",
+ "deleteSubTask": "Fshi Nรซndetyrรซn"
+ },
+ "dependencies": {
+ "title": "Varรซsitรซ",
+ "addDependency": "+ Shto varรซsi tรซ re",
+ "blockedBy": "Bllokuar nga",
+ "searchTask": "Shkruani pรซr tรซ kรซrkuar detyrรซ",
+ "noTasksFound": "Nuk u gjetรซn detyra",
+ "confirmDeleteDependency": "Jeni i sigurt qรซ doni tรซ fshini?"
+ },
+ "attachments": {
+ "title": "Bashkรซngjitjet",
+ "chooseOrDropFileToUpload": "Zgjidhni ose hidhni skedar pรซr tรซ ngarkuar",
+ "uploading": "Duke ngarkuar..."
+ },
+ "comments": {
+ "title": "Komentet",
+ "addComment": "+ Shto koment tรซ ri",
+ "noComments": "Ende pa komente. Bรซhu i pari qรซ komenton!",
+ "delete": "Fshi",
+ "confirmDeleteComment": "Jeni i sigurt qรซ doni tรซ fshini kรซtรซ koment?",
+ "addCommentPlaceholder": "Shto njรซ koment...",
+ "cancel": "Anulo",
+ "commentButton": "Komento",
+ "attachFiles": "Bashkรซngjit skedarรซ",
+ "addMoreFiles": "Shto mรซ shumรซ skedarรซ",
+ "selectedFiles": "Skedarรซt e Zgjedhur (Deri nรซ 25MB, Maksimumi {count})",
+ "maxFilesError": "Mund tรซ ngarkoni maksimum {count} skedarรซ",
+ "processFilesError": "Dรซshtoi pรซrpunimi i skedarรซve",
+ "addCommentError": "Ju lutemi shtoni njรซ koment ose bashkรซngjitni skedarรซ",
+ "createdBy": "Krijuar {{time}} nga {{user}}",
+ "updatedTime": "Pรซrditรซsuar {{time}}"
+ },
+ "searchInputPlaceholder": "Kรซrko sipas emrit",
+ "pendingInvitation": "Ftesรซ nรซ Pritje"
+ },
+ "taskTimeLogTab": {
+ "title": "Regjistri i Kohรซs",
+ "addTimeLog": "Shto regjistrim tรซ ri kohe",
+ "totalLogged": "Totali i Regjistruar",
+ "exportToExcel": "Eksporto nรซ Excel",
+ "noTimeLogsFound": "Nuk u gjetรซn regjistra kohe",
+ "timeLogForm": {
+ "date": "Data",
+ "startTime": "Koha e Fillimit",
+ "endTime": "Koha e Pรซrfundimit",
+ "workDescription": "Pรซrshkrimi i Punรซs",
+ "descriptionPlaceholder": "Shto njรซ pรซrshkrim",
+ "logTime": "Regjistro kohรซn",
+ "updateTime": "Pรซrditรซso kohรซn",
+ "cancel": "Anulo",
+ "selectDateError": "Ju lutemi zgjidhni njรซ datรซ",
+ "selectStartTimeError": "Ju lutemi zgjidhni kohรซn e fillimit",
+ "selectEndTimeError": "Ju lutemi zgjidhni kohรซn e pรซrfundimit",
+ "endTimeAfterStartError": "Koha e pรซrfundimit duhet tรซ jetรซ pas kohรซs sรซ fillimit"
+ }
+ },
+ "taskActivityLogTab": {
+ "title": "Regjistri i Aktivitetit",
+ "add": "SHTO",
+ "remove": "HIQE",
+ "none": "Asnjรซ",
+ "weight": "Pesha",
+ "createdTask": "krijoi detyrรซn."
+ },
+ "taskProgress": {
+ "markAsDoneTitle": "Shรซno Detyrรซn si tรซ Kryer?",
+ "confirmMarkAsDone": "Po, shรซno si tรซ kryer",
+ "cancelMarkAsDone": "Jo, mbaj statusin aktual",
+ "markAsDoneDescription": "Keni vendosur progresin nรซ 100%. Doni tรซ pรซrditรซsoni statusin e detyrรซs nรซ \"Kryer\"?"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/alb/task-list-filters.json b/worklenz-backend/src/public/locales/alb/task-list-filters.json
new file mode 100644
index 00000000..c3156498
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/task-list-filters.json
@@ -0,0 +1,85 @@
+{
+ "searchButton": "Kรซrko",
+ "resetButton": "Rivendos",
+ "searchInputPlaceholder": "Kรซrko sipas emrit",
+
+ "sortText": "Rendit",
+ "statusText": "Statusi",
+ "phaseText": "Faza",
+ "memberText": "Anรซtarรซt",
+ "assigneesText": "Pรซrgjegjรซsit",
+ "priorityText": "Prioriteti",
+ "labelsText": "Etiketa",
+ "membersText": "Anรซtarรซt",
+ "groupByText": "Grupo sipas",
+ "showArchivedText": "Shfaq tรซ arkivuara",
+ "showFieldsText": "Shfaq fushat",
+ "keyText": "รelรซsi",
+ "taskText": "Detyra",
+ "descriptionText": "Pรซrshkrimi",
+ "phasesText": "Fazat",
+ "listText": "Listรซ",
+ "progressText": "Progresi",
+ "timeTrackingText": "Gjurmimi i Kohรซs",
+ "timetrackingText": "Gjurmimi i Kohรซs",
+ "estimationText": "Vlerรซsimi",
+ "startDateText": "Data e Fillimit",
+ "startdateText": "Data e Fillimit",
+ "endDateText": "Data e Pรซrfundimit",
+ "dueDateText": "Afati",
+ "duedateText": "Afati",
+ "completedDateText": "Data e Pรซrfundimit",
+ "completeddateText": "Data e Pรซrfundimit",
+ "createdDateText": "Data e Krijimit",
+ "createddateText": "Data e Krijimit",
+ "lastUpdatedText": "Pรซrditรซsuar Sรซ Fundi",
+ "lastupdatedText": "Pรซrditรซsuar Sรซ Fundi",
+ "reporterText": "Raportuesi",
+ "dueTimeText": "Koha e Afatit",
+ "duetimeText": "Koha e Afatit",
+
+ "lowText": "I ulรซt",
+ "mediumText": "I mesรซm",
+ "highText": "I lartรซ",
+
+ "createStatusButtonTooltip": "Cilรซsimet e statusit",
+ "configPhaseButtonTooltip": "Cilรซsimet e fazรซs",
+ "noLabelsFound": "Nuk u gjetรซn etiketa",
+
+ "addStatusButton": "Shto Status",
+ "addPhaseButton": "Shto Fazรซ",
+
+ "createStatus": "Krijo Status",
+ "name": "Emri",
+ "category": "Kategoria",
+ "selectCategory": "Zgjidh njรซ kategori",
+ "pleaseEnterAName": "Ju lutemi vendosni njรซ emรซr",
+ "pleaseSelectACategory": "Ju lutemi zgjidhni njรซ kategori",
+ "create": "Krijo",
+
+ "searchTasks": "Kรซrko detyrat...",
+ "searchPlaceholder": "Kรซrko...",
+ "fieldsText": "Fushat",
+ "loadingFilters": "Duke ngarkuar filtrat...",
+ "noOptionsFound": "Nuk u gjetรซn opsione",
+ "filtersActive": "filtra aktiv",
+ "filterActive": "filtรซr aktiv",
+ "clearAll": "Pastro tรซ gjitha",
+ "clearing": "Duke pastruar...",
+ "cancel": "Anulo",
+ "search": "Kรซrko",
+ "groupedBy": "Grupuar sipas",
+ "manageStatuses": "Menaxho Statuset",
+ "managePhases": "Menaxho Fazat",
+ "dragToReorderStatuses": "Zvarrit statuset pรซr t'i rirenditur. รdo status mund tรซ ketรซ njรซ kategori tรซ ndryshme.",
+ "enterNewStatusName": "Shkruani emrin e statusit tรซ ri...",
+ "addStatus": "Shto Status",
+ "noStatusesFound": "Nuk u gjetรซn statuse. Krijoni statusin tuaj tรซ parรซ mรซ sipรซr.",
+ "deleteStatus": "Fshi Statusin",
+ "deleteStatusConfirm": "Jeni tรซ sigurt qรซ doni tรซ fshini kรซtรซ status? Ky veprim nuk mund tรซ zhbรซhet.",
+ "rename": "Riemรซro",
+ "delete": "Fshi",
+ "enterStatusName": "Shkruani emrin e statusit",
+ "selectCategory": "Zgjidh kategorinรซ",
+ "close": "Mbyll"
+}
diff --git a/worklenz-backend/src/public/locales/alb/task-list-table.json b/worklenz-backend/src/public/locales/alb/task-list-table.json
new file mode 100644
index 00000000..7e3f83dd
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/task-list-table.json
@@ -0,0 +1,136 @@
+{
+ "keyColumn": "รelรซsi",
+ "taskColumn": "Detyra",
+ "descriptionColumn": "Pรซrshkrimi",
+ "progressColumn": "Progresi",
+ "membersColumn": "Anรซtarรซt",
+ "assigneesColumn": "Pรซrgjegjรซsit",
+ "labelsColumn": "Etiketa",
+ "phasesColumn": "Fazat",
+ "phaseColumn": "Faza",
+ "statusColumn": "Statusi",
+ "priorityColumn": "Prioriteti",
+ "timeTrackingColumn": "Gjurmimi i Kohรซs",
+ "timetrackingColumn": "Gjurmimi i Kohรซs",
+ "estimationColumn": "Vlerรซsimi",
+ "startDateColumn": "Data e Fillimit",
+ "startdateColumn": "Data e Fillimit",
+ "dueDateColumn": "Data e Afatit",
+ "duedateColumn": "Data e Afatit",
+ "completedDateColumn": "Data e Pรซrfundimit",
+ "completeddateColumn": "Data e Pรซrfundimit",
+ "createdDateColumn": "Data e Krijimit",
+ "createddateColumn": "Data e Krijimit",
+ "lastUpdatedColumn": "Pรซrditรซsuar Sรซ Fundi",
+ "lastupdatedColumn": "Pรซrditรซsuar Sรซ Fundi",
+ "reporterColumn": "Raportuesi",
+ "dueTimeColumn": "Koha e Afatit",
+ "todoSelectorText": "Pรซr tรซ Bรซrรซ",
+ "doingSelectorText": "Duke bรซrรซ",
+ "doneSelectorText": "E Pรซrfunduar",
+
+ "lowSelectorText": "I ulรซt",
+ "mediumSelectorText": "I mesรซm",
+ "highSelectorText": "I lartรซ",
+
+ "selectText": "Zgjidh",
+ "labelsSelectorInputTip": "Shtyp Enter pรซr tรซ krijuar!",
+
+ "addTaskText": "Shto Detyrรซ",
+ "addSubTaskText": "+ Shto Nรซn-Detyrรซ",
+ "noTasksInGroup": "Nuk ka detyra nรซ kรซtรซ grup",
+ "addTaskInputPlaceholder": "Shkruaj detyrรซn dhe shtyp Enter",
+
+ "openButton": "Hap",
+ "okButton": "Nรซ rregull",
+
+ "noLabelsFound": "Nuk u gjetรซn etiketa",
+ "searchInputPlaceholder": "Kรซrko ose krijo",
+ "assigneeSelectorInviteButton": "Fto njรซ anรซtar tรซ ri me email",
+ "labelInputPlaceholder": "Kรซrko ose krijo",
+ "searchLabelsPlaceholder": "Kรซrko etiketa...",
+ "createLabelButton": "Krijo \"{{name}}\"",
+ "manageLabelsPath": "Cilรซsimet โ Etiketat",
+
+ "pendingInvitation": "Ftesรซ nรซ Pritje",
+
+ "contextMenu": {
+ "assignToMe": "Cakto mua",
+ "moveTo": "Zhvendos nรซ",
+ "unarchive": "ร'arkivizo",
+ "archive": "Arkivizo",
+ "convertToSubTask": "Shndรซrro nรซ Nรซn-Detyrรซ",
+ "convertToTask": "Shndรซrro nรซ Detyrรซ",
+ "delete": "Fshi",
+ "searchByNameInputPlaceholder": "Kรซrko sipas emrit"
+ },
+ "setDueDate": "Cakto datรซn e afatit",
+ "setStartDate": "Cakto datรซn e fillimit",
+ "clearDueDate": "Pastro datรซn e afatit",
+ "clearStartDate": "Pastro datรซn e fillimit",
+ "dueDatePlaceholder": "Data e afatit",
+ "startDatePlaceholder": "Data e fillimit",
+
+ "emptyStates": {
+ "noTaskGroups": "Nuk u gjetรซn grupe detyrash",
+ "noTaskGroupsDescription": "Detyrat do tรซ shfaqen kรซtu kur krijohen ose kur aplikohen filtra.",
+ "errorPrefix": "Gabim:",
+ "dragTaskFallback": "Detyrรซ"
+ },
+
+ "customColumns": {
+ "addCustomColumn": "Shto njรซ kolonรซ tรซ personalizuar",
+ "customColumnHeader": "Kolona e Personalizuar",
+ "customColumnSettings": "Cilรซsimet e kolonรซs sรซ personalizuar",
+ "noCustomValue": "Asnjรซ vlerรซ",
+ "peopleField": "Fusha e njerรซzve",
+ "noDate": "Asnjรซ datรซ",
+ "unsupportedField": "Lloj fushe i pambรซshtetur",
+
+ "modal": {
+ "addFieldTitle": "Shto fushรซ",
+ "editFieldTitle": "Redakto fushรซn",
+ "fieldTitle": "Titulli i fushรซs",
+ "fieldTitleRequired": "Titulli i fushรซs รซshtรซ i kรซrkuar",
+ "columnTitlePlaceholder": "Titulli i kolonรซs",
+ "type": "Lloji",
+ "deleteConfirmTitle": "Jeni i sigurt qรซ doni tรซ fshini kรซtรซ kolonรซ tรซ personalizuar?",
+ "deleteConfirmDescription": "Kjo veprim nuk mund tรซ zhbรซhet. Tรซ gjitha tรซ dhรซnat e lidhura me kรซtรซ kolonรซ do tรซ fshihen pรซrgjithmonรซ.",
+ "deleteButton": "Fshi",
+ "cancelButton": "Anulo",
+ "createButton": "Krijo",
+ "updateButton": "Pรซrditรซso",
+ "createSuccessMessage": "Kolona e personalizuar u krijua me sukses",
+ "updateSuccessMessage": "Kolona e personalizuar u pรซrditรซsua me sukses",
+ "deleteSuccessMessage": "Kolona e personalizuar u fshi me sukses",
+ "deleteErrorMessage": "Dรซshtoi nรซ fshirjen e kolonรซs sรซ personalizuar",
+ "createErrorMessage": "Dรซshtoi nรซ krijimin e kolonรซs sรซ personalizuar",
+ "updateErrorMessage": "Dรซshtoi nรซ pรซrditรซsimin e kolonรซs sรซ personalizuar"
+ },
+
+ "fieldTypes": {
+ "people": "Njerรซz",
+ "number": "Numรซr",
+ "date": "Data",
+ "selection": "Zgjedhje",
+ "checkbox": "Kutia e kontrollit",
+ "labels": "Etiketat",
+ "key": "รelรซsi",
+ "formula": "Formula"
+ }
+ },
+
+ "indicators": {
+ "tooltips": {
+ "subtasks": "{{count}} nรซn-detyrรซ",
+ "subtasks_plural": "{{count}} nรซn-detyra",
+ "comments": "{{count}} koment",
+ "comments_plural": "{{count}} komente",
+ "attachments": "{{count}} bashkรซngjitje",
+ "attachments_plural": "{{count}} bashkรซngjitje",
+ "subscribers": "Detyra ka pajtues",
+ "dependencies": "Detyra ka varรซsi",
+ "recurring": "Detyrรซ pรซrsรซritรซse"
+ }
+ }
+}
diff --git a/worklenz-backend/src/public/locales/alb/task-management.json b/worklenz-backend/src/public/locales/alb/task-management.json
new file mode 100644
index 00000000..a156ef3f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/task-management.json
@@ -0,0 +1,21 @@
+{
+ "noTasksInGroup": "Nuk ka detyra nรซ kรซtรซ grup",
+ "noTasksInGroupDescription": "Shtoni njรซ detyrรซ pรซr tรซ filluar",
+ "addFirstTask": "Shtoni detyrรซn tuaj tรซ parรซ",
+ "openTask": "Hap",
+ "subtask": "nรซn-detyrรซ",
+ "subtasks": "nรซn-detyra",
+ "comment": "koment",
+ "comments": "komente",
+ "attachment": "bashkรซngjitje",
+ "attachments": "bashkรซngjitje",
+ "enterSubtaskName": "Shkruani emrin e nรซn-detyrรซs...",
+ "add": "Shto",
+ "cancel": "Anulo",
+ "renameGroup": "Riemรซrto Grupin",
+ "renameStatus": "Riemรซrto Statusin",
+ "renamePhase": "Riemรซrto Fazรซn",
+ "changeCategory": "Ndrysho Kategorinรซ",
+ "clickToEditGroupName": "Kliko pรซr tรซ ndryshuar emrin e grupit",
+ "enterGroupName": "Shkruani emrin e grupit"
+}
diff --git a/worklenz-backend/src/public/locales/alb/task-template-drawer.json b/worklenz-backend/src/public/locales/alb/task-template-drawer.json
new file mode 100644
index 00000000..034ac916
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/task-template-drawer.json
@@ -0,0 +1,11 @@
+{
+ "createTaskTemplate": "Krijo Shabllon Detyre",
+ "editTaskTemplate": "Modifiko Shabllon Detyre",
+ "cancelText": "Anulo",
+ "saveText": "Ruaj",
+ "templateNameText": "Emri i Shabllonit",
+ "selectedTasks": "Detyrat e Pรซrzgjedhura",
+ "removeTask": "Hiq",
+ "cancelButton": "Anulo",
+ "saveButton": "Ruaj"
+}
diff --git a/worklenz-backend/src/public/locales/alb/tasks/task-table-bulk-actions.json b/worklenz-backend/src/public/locales/alb/tasks/task-table-bulk-actions.json
new file mode 100644
index 00000000..45980b24
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/tasks/task-table-bulk-actions.json
@@ -0,0 +1,26 @@
+{
+ "taskSelected": "detyrรซ e zgjedhur",
+ "tasksSelected": "detyra tรซ zgjedhura",
+ "changeStatus": "Ndrysho Statusin/ Prioritetin/ Fazat",
+ "changeLabel": "Ndrysho Etiketรซn",
+ "assignToMe": "Cakto mua",
+ "changeAssignees": "Ndrysho Pรซrgjegjรซsit",
+ "archive": "Arkivo",
+ "unarchive": "ร'arkivo",
+ "delete": "Fshi",
+ "moreOptions": "Mรซ shumรซ opsione",
+ "deselectAll": "Zgjidhja tรซ gjitha",
+ "status": "Statusi",
+ "priority": "Prioriteti",
+ "phase": "Faza",
+ "member": "Anรซtar",
+ "createTaskTemplate": "Krijo Shabllon Detyre",
+ "apply": "Apliko",
+ "createLabel": "+ Krijo Etiketรซ",
+ "searchOrCreateLabel": "Kรซrko ose krijo etiketรซ...",
+ "hitEnterToCreate": "Shtyp Enter pรซr tรซ krijuar",
+ "labelExists": "Etiketa ekziston tashmรซ",
+ "pendingInvitation": "Ftesรซ nรซ Pritje",
+ "noMatchingLabels": "Asnjรซ etiketรซ qรซ pรซrputhet",
+ "noLabels": "Asnjรซ etiketรซ"
+}
diff --git a/worklenz-backend/src/public/locales/alb/template-drawer.json b/worklenz-backend/src/public/locales/alb/template-drawer.json
new file mode 100644
index 00000000..e6174c10
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/template-drawer.json
@@ -0,0 +1,19 @@
+{
+ "title": "Modifiko Shabllon Detyre",
+ "cancelText": "Anulo",
+ "saveText": "Ruaj",
+ "templateNameText": "Emri i Shabllonit",
+ "selectedTasks": "Detyrat e Pรซrzgjedhura",
+ "removeTask": "Hiq",
+ "description": "Pรซrshkrimi",
+ "phase": "Faza",
+ "statuses": "Statuset",
+ "priorities": "Prioritetet",
+ "labels": "Etiketa",
+ "tasks": "Detyrat",
+ "noTemplateSelected": "Asnjรซ shabllon i pรซrzgjedhur",
+ "noDescription": "Pa pรซrshkrim",
+ "worklenzTemplates": "Shabllonet Worklenz",
+ "yourTemplatesLibrary": "Biblioteka Juaj",
+ "searchTemplates": "Kรซrko Shabllone"
+}
diff --git a/worklenz-backend/src/public/locales/alb/templateDrawer.json b/worklenz-backend/src/public/locales/alb/templateDrawer.json
new file mode 100644
index 00000000..6b2cd828
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/templateDrawer.json
@@ -0,0 +1,23 @@
+{
+ "bugTracking": "Gjurmimi i Gabimeve",
+ "construction": "Ndรซrtim",
+ "designCreative": "Dizajn & Kreativ",
+ "education": "Arsim",
+ "finance": "Financรซ",
+ "hrRecruiting": "Burime Njerรซzore & Rekrutim",
+ "informationTechnology": "Teknologji Informacioni",
+ "legal": "Juridik",
+ "manufacturing": "Prodhim",
+ "marketing": "Marketing",
+ "nonprofit": "Jo-fitimprurรซs",
+ "personalUse": "Pรซrdorim Personal",
+ "salesCRM": "Shitje & CRM",
+ "serviceConsulting": "Shรซrbime & Kรซshillim",
+ "softwareDevelopment": "Zhvillim Softueri",
+ "description": "Pรซrshkrimi",
+ "phase": "Faza",
+ "statuses": "Statuset",
+ "priorities": "Prioritetet",
+ "labels": "Etiketa",
+ "tasks": "Detyrat"
+}
diff --git a/worklenz-backend/src/public/locales/alb/time-report.json b/worklenz-backend/src/public/locales/alb/time-report.json
new file mode 100644
index 00000000..8a0bb69b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/time-report.json
@@ -0,0 +1,44 @@
+{
+ "includeArchivedProjects": "Pรซrfshij Projektet e Arkivuara",
+ "export": "Eksporto",
+ "timeSheet": "Fletรซ Kohore",
+
+ "searchByName": "Kรซrko sipas emrit",
+ "selectAll": "Zgjidh tรซ Gjitha",
+ "teams": "Ekipet",
+
+ "searchByProject": "Kรซrko sipas emrit tรซ projektit",
+ "projects": "Projektet",
+
+ "searchByCategory": "Kรซrko sipas emrit tรซ kategorisรซ",
+ "categories": "Kategoritรซ",
+
+ "billable": "Fakturueshme",
+ "nonBillable": "Jo Fakturueshme",
+
+ "total": "Total",
+
+ "projectsTimeSheet": "Fletรซ Kohore e Projekteve",
+
+ "loggedTime": "Koha e Regjistruar(orรซ)",
+
+ "exportToExcel": "Eksporto nรซ Excel",
+ "logged": "regjistruar",
+ "for": "pรซr",
+
+ "membersTimeSheet": "Fletรซ Kohore e Anรซtarรซve",
+ "member": "Anรซtar",
+
+ "estimatedVsActual": "Vlerรซsuar vs Aktual",
+ "workingDays": "Ditรซ Pune",
+ "manDays": "Ditรซ Njeri",
+ "days": "Ditรซ",
+ "estimatedDays": "Ditรซ tรซ Vlerรซsuara",
+ "actualDays": "Ditรซ Aktuale",
+
+ "noCategories": "Nuk u gjetรซn kategori",
+ "noCategory": "Pa Kategori",
+ "noProjects": "Nuk u gjetรซn projekte",
+ "noTeams": "Nuk u gjetรซn ekipe",
+ "noData": "Nuk u gjetรซn tรซ dhรซna"
+}
diff --git a/worklenz-backend/src/public/locales/alb/unauthorized.json b/worklenz-backend/src/public/locales/alb/unauthorized.json
new file mode 100644
index 00000000..a731e676
--- /dev/null
+++ b/worklenz-backend/src/public/locales/alb/unauthorized.json
@@ -0,0 +1,5 @@
+{
+ "title": "E paautorizuar!",
+ "subtitle": "Nuk jeni tรซ autorizuar tรซ hyni nรซ kรซtรซ faqe",
+ "button": "Kthehu nรซ Faqen Kryesore"
+}
diff --git a/worklenz-backend/src/public/locales/de/404-page.json b/worklenz-backend/src/public/locales/de/404-page.json
new file mode 100644
index 00000000..641a1847
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/404-page.json
@@ -0,0 +1,4 @@
+{
+ "doesNotExistText": "Entschuldigung, die von Ihnen besuchte Seite existiert nicht.",
+ "backHomeButton": "Zurรผck zur Startseite"
+}
diff --git a/worklenz-backend/src/public/locales/de/account-setup.json b/worklenz-backend/src/public/locales/de/account-setup.json
new file mode 100644
index 00000000..ddfb7b80
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/account-setup.json
@@ -0,0 +1,31 @@
+{
+ "continue": "Weiter",
+
+ "setupYourAccount": "Richten Sie Ihr Worklenz-Konto ein.",
+ "organizationStepTitle": "Organisation benennen",
+ "organizationStepLabel": "Wรคhlen Sie einen Namen fรผr Ihr Worklenz-Konto.",
+
+ "projectStepTitle": "Erstellen Sie Ihr erstes Projekt",
+ "projectStepLabel": "An welchem Projekt arbeiten Sie gerade?",
+ "projectStepPlaceholder": "z.B. Marketingplan",
+
+ "tasksStepTitle": "Erstellen Sie Ihre ersten Aufgaben",
+ "tasksStepLabel": "Geben Sie einige Aufgaben ein, die Sie in",
+ "tasksStepAddAnother": "Weitere hinzufรผgen",
+
+ "emailPlaceholder": "E-Mail-Adresse",
+ "invalidEmail": "Bitte geben Sie eine gรผltige E-Mail-Adresse ein",
+ "or": "oder",
+ "templateButton": "Aus Vorlage importieren",
+ "goBack": "Zurรผck",
+ "cancel": "Abbrechen",
+ "create": "Erstellen",
+ "templateDrawerTitle": "Aus Vorlagen auswรคhlen",
+ "step3InputLabel": "Per E-Mail einladen",
+ "addAnother": "Weitere hinzufรผgen",
+ "skipForNow": "Jetzt รผberspringen",
+ "formTitle": "Erstellen Sie Ihre erste Aufgabe.",
+ "step3Title": "Laden Sie Ihr Team zur Zusammenarbeit ein",
+ "maxMembers": " (Sie kรถnnen bis zu 5 Mitglieder einladen)",
+ "maxTasks": " (Sie kรถnnen bis zu 5 Aufgaben erstellen)"
+}
diff --git a/worklenz-backend/src/public/locales/de/admin-center/current-bill.json b/worklenz-backend/src/public/locales/de/admin-center/current-bill.json
new file mode 100644
index 00000000..fcf2c636
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/admin-center/current-bill.json
@@ -0,0 +1,113 @@
+{
+ "title": "Abrechnungen",
+ "currentBill": "Aktuelle Rechnung",
+ "configuration": "Konfiguration",
+ "currentPlanDetails": "Aktuelle Plan Details",
+ "upgradePlan": "Plan upgraden",
+ "cardBodyText01": "Kostenlose Testversion",
+ "cardBodyText02": "(Ihr Testplan lรคuft in 1 Monat 19 Tagen ab)",
+ "redeemCode": "Gutscheincode einlรถsen",
+ "accountStorage": "Kontospeicher",
+ "used": "Verwendet:",
+ "remaining": "Verbleibend:",
+ "charges": "Gebรผhren",
+ "tooltip": "Gebรผhren fรผr den aktuellen Abrechnungszeitraum",
+ "description": "Beschreibung",
+ "billingPeriod": "Abrechnungszeitraum",
+ "billStatus": "Rechnungsstatus",
+ "perUserValue": "Pro Benutzer Wert",
+ "users": "Benutzer",
+
+ "amount": "Betrag",
+ "invoices": "Rechnungen",
+ "transactionId": "Transaktions-ID",
+ "transactionDate": "Transaktionsdatum",
+ "paymentMethod": "Zahlungsmethode",
+ "status": "Status",
+ "ltdUsers": "Sie kรถnnen bis zu {{ltd_users}} Benutzer hinzufรผgen.",
+
+ "totalSeats": "Gesamte Plรคtze",
+ "availableSeats": "Verfรผgbare Plรคtze",
+ "addMoreSeats": "Weitere Plรคtze hinzufรผgen",
+
+ "drawerTitle": "Gutscheincode einlรถsen",
+ "label": "Gutscheincode",
+ "drawerPlaceholder": "Geben Sie Ihren Gutscheincode ein",
+ "redeemSubmit": "Einreichen",
+
+ "modalTitle": "Wรคhlen Sie den besten Plan fรผr Ihr Team",
+ "seatLabel": "Anzahl der Plรคtze",
+ "freePlan": "Kostenloser Plan",
+ "startup": "Startup",
+ "business": "Business",
+ "tag": "Am beliebtesten",
+ "enterprise": "Enterprise",
+
+ "freeSubtitle": "kostenlos fรผr immer",
+ "freeUsers": "Ideal fรผr die persรถnliche Nutzung",
+ "freeText01": "100MB Speicher",
+ "freeText02": "3 Projekte",
+ "freeText03": "5 Teammitglieder",
+
+ "startupSubtitle": "PAUSCHALPREIS / Monat",
+ "startupUsers": "Bis zu 15 Benutzer",
+ "startupText01": "25GB Speicher",
+ "startupText02": "Unbegrenzte aktive Projekte",
+ "startupText03": "Zeitplan",
+ "startupText04": "Berichterstattung",
+ "startupText05": "Projekte abonnieren",
+
+ "businessSubtitle": "Benutzer / Monat",
+ "businessUsers": "16 - 200 Benutzer",
+
+ "enterpriseUsers": "200 - 500+ Benutzer",
+
+ "footerTitle": "Bitte geben Sie uns eine Kontaktnummer, unter der wir Sie erreichen kรถnnen.",
+ "footerLabel": "Kontaktnummer",
+ "footerButton": "Kontaktieren Sie uns",
+
+ "redeemCodePlaceHolder": "Geben Sie Ihren Gutscheincode ein",
+ "submit": "Einreichen",
+
+ "trialPlan": "Kostenlose Testversion",
+ "trialExpireDate": "Gรผltig bis {{trial_expire_date}}",
+ "trialExpired": "Ihre kostenlose Testversion ist {{trial_expire_string}} abgelaufen",
+ "trialInProgress": "Ihre kostenlose Testversion lรคuft {{trial_expire_string}} ab",
+
+ "required": "Dieses Feld ist erforderlich",
+ "invalidCode": "Ungรผltiger Code",
+
+ "selectPlan": "Wรคhlen Sie den besten Plan fรผr Ihr Team",
+ "changeSubscriptionPlan": "รndern Sie Ihren Abonnementplan",
+ "noOfSeats": "Anzahl der Plรคtze",
+ "annualPlan": "Pro - Jรคhrlich",
+ "monthlyPlan": "Pro - Monatlich",
+ "freeForever": "Kostenlos fรผr immer",
+ "bestForPersonalUse": "Ideal fรผr die persรถnliche Nutzung",
+ "storage": "Speicher",
+ "projects": "Projekte",
+ "teamMembers": "Teammitglieder",
+ "unlimitedTeamMembers": "Unbegrenzte Teammitglieder",
+ "unlimitedActiveProjects": "Unbegrenzte aktive Projekte",
+ "schedule": "Zeitplan",
+ "reporting": "Berichterstattung",
+ "subscribeToProjects": "Projekte abonnieren",
+ "billedAnnually": "Jรคhrlich abgerechnet",
+ "billedMonthly": "Monatlich abgerechnet",
+
+ "pausePlan": "Plan pausieren",
+ "resumePlan": "Plan fortsetzen",
+ "changePlan": "Plan รคndern",
+ "cancelPlan": "Plan kรผndigen",
+
+ "perMonthPerUser": "pro Benutzer/Monat",
+ "viewInvoice": "Rechnung anzeigen",
+ "switchToFreePlan": "Wechsel zum kostenlosen Plan",
+
+ "expirestoday": "heute",
+ "expirestomorrow": "morgen",
+ "expiredDaysAgo": "vor {{days}} Tagen",
+
+ "continueWith": "Fortfahren mit {{plan}}",
+ "changeToPlan": "Wechseln zu {{plan}}"
+}
diff --git a/worklenz-backend/src/public/locales/de/admin-center/overview.json b/worklenz-backend/src/public/locales/de/admin-center/overview.json
new file mode 100644
index 00000000..0330d788
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/admin-center/overview.json
@@ -0,0 +1,8 @@
+{
+ "overview": "รbersicht",
+ "name": "Organisationsname",
+ "owner": "Organisationsinhaber",
+ "admins": "Organisationsadministratoren",
+ "contactNumber": "Kontaktnummer hinzufรผgen",
+ "edit": "Bearbeiten"
+}
diff --git a/worklenz-backend/src/public/locales/de/admin-center/projects.json b/worklenz-backend/src/public/locales/de/admin-center/projects.json
new file mode 100644
index 00000000..2d4f3534
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/admin-center/projects.json
@@ -0,0 +1,12 @@
+{
+ "membersCount": "Mitgliederanzahl",
+ "createdAt": "Erstellt am",
+ "projectName": "Projektname",
+ "teamName": "Teamname",
+ "refreshProjects": "Projekte aktualisieren",
+ "searchPlaceholder": "Nach Projektname suchen",
+ "deleteProject": "Sind Sie sicher, dass Sie dieses Projekt lรถschen mรถchten?",
+ "confirm": "Bestรคtigen",
+ "cancel": "Abbrechen",
+ "delete": "Projekt lรถschen"
+}
diff --git a/worklenz-backend/src/public/locales/de/admin-center/sidebar.json b/worklenz-backend/src/public/locales/de/admin-center/sidebar.json
new file mode 100644
index 00000000..670595a3
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/admin-center/sidebar.json
@@ -0,0 +1,8 @@
+{
+ "overview": "รbersicht",
+ "users": "Benutzer",
+ "teams": "Teams",
+ "billing": "Abrechnung",
+ "projects": "Projekte",
+ "adminCenter": "Admin-Center"
+}
diff --git a/worklenz-backend/src/public/locales/de/admin-center/teams.json b/worklenz-backend/src/public/locales/de/admin-center/teams.json
new file mode 100644
index 00000000..7ab2831f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/admin-center/teams.json
@@ -0,0 +1,33 @@
+{
+ "title": "Teams",
+ "subtitle": "Teams",
+ "tooltip": "Teams aktualisieren",
+ "placeholder": "Nach Namen suchen",
+ "addTeam": "Team hinzufรผgen",
+ "team": "Team",
+ "membersCount": "Mitgliederanzahl",
+ "members": "Mitglieder",
+ "drawerTitle": "Neues Team erstellen",
+ "label": "Teamname",
+ "drawerPlaceholder": "Name",
+ "create": "Erstellen",
+ "delete": "Lรถschen",
+ "settings": "Einstellungen",
+ "popTitle": "Sind Sie sicher?",
+ "message": "Bitte geben Sie einen Namen ein",
+ "teamSettings": "Team-Einstellungen",
+ "teamName": "Teamname",
+ "teamDescription": "Teambeschreibung",
+ "teamMembers": "Teammitglieder",
+ "teamMembersCount": "Anzahl der Teammitglieder",
+ "teamMembersPlaceholder": "Nach Namen suchen",
+ "addMember": "Mitglied hinzufรผgen",
+ "add": "Hinzufรผgen",
+ "update": "Aktualisieren",
+ "teamNamePlaceholder": "Name des Teams",
+ "user": "Benutzer",
+ "role": "Rolle",
+ "owner": "Besitzer",
+ "admin": "Administrator",
+ "member": "Mitglied"
+}
diff --git a/worklenz-backend/src/public/locales/de/admin-center/users.json b/worklenz-backend/src/public/locales/de/admin-center/users.json
new file mode 100644
index 00000000..47de9a59
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/admin-center/users.json
@@ -0,0 +1,9 @@
+{
+ "title": "Benutzer",
+ "subTitle": "Benutzer",
+ "placeholder": "Nach Namen suchen",
+ "user": "Benutzer",
+ "email": "E-Mail",
+ "lastActivity": "Letzte Aktivitรคt",
+ "refresh": "Benutzer aktualisieren"
+}
diff --git a/worklenz-backend/src/public/locales/de/all-project-list.json b/worklenz-backend/src/public/locales/de/all-project-list.json
new file mode 100644
index 00000000..89a9803d
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/all-project-list.json
@@ -0,0 +1,34 @@
+{
+ "name": "Name",
+ "client": "Kunde",
+ "category": "Kategorie",
+ "status": "Status",
+ "tasksProgress": "Aufgabenfortschritt",
+ "updated_at": "Zuletzt aktualisiert",
+ "members": "Mitglieder",
+ "setting": "Einstellungen",
+ "projects": "Projekte",
+ "refreshProjects": "Projekte aktualisieren",
+ "all": "Alle",
+ "favorites": "Favoriten",
+ "archived": "Archiviert",
+ "placeholder": "Nach Namen suchen",
+ "archive": "Archivieren",
+ "unarchive": "Dearchivieren",
+ "archiveConfirm": "Sind Sie sicher, dass Sie dieses Projekt archivieren mรถchten?",
+ "unarchiveConfirm": "Sind Sie sicher, dass Sie dieses Projekt dearchivieren mรถchten?",
+ "yes": "Ja",
+ "no": "Nein",
+ "clickToFilter": "Zum Filtern klicken nach",
+ "noProjects": "Keine Projekte gefunden",
+ "addToFavourites": "Zu Favoriten hinzufรผgen",
+ "list": "Liste",
+ "group": "Gruppe",
+ "listView": "Listenansicht",
+ "groupView": "Gruppenansicht",
+ "groupBy": {
+ "category": "Kategorie",
+ "client": "Kunde"
+ },
+ "noPermission": "Sie haben keine Berechtigung, diese Aktion durchzufรผhren"
+}
diff --git a/worklenz-backend/src/public/locales/de/auth/auth-common.json b/worklenz-backend/src/public/locales/de/auth/auth-common.json
new file mode 100644
index 00000000..dab26d10
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/auth/auth-common.json
@@ -0,0 +1,5 @@
+{
+ "loggingOut": "Abmelden...",
+ "authenticating": "Authentifizierung lรคuft...",
+ "gettingThingsReady": "Bereite alles fรผr Sie vor..."
+}
diff --git a/worklenz-backend/src/public/locales/de/auth/forgot-password.json b/worklenz-backend/src/public/locales/de/auth/forgot-password.json
new file mode 100644
index 00000000..a94c7463
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/auth/forgot-password.json
@@ -0,0 +1,12 @@
+{
+ "headerDescription": "Passwort zurรผcksetzen",
+ "emailLabel": "E-Mail",
+ "emailPlaceholder": "Ihre E-Mail eingeben",
+ "emailRequired": "Bitte geben Sie Ihre E-Mail-Adresse ein!",
+ "resetPasswordButton": "Passwort zurรผcksetzen",
+ "returnToLoginButton": "Zurรผck zum Login",
+ "passwordResetSuccessMessage": "Ein Link zum Zurรผcksetzen des Passworts wurde an Ihre E-Mail gesendet.",
+ "orText": "ODER",
+ "successTitle": "Anweisung zum Zurรผcksetzen gesendet!",
+ "successMessage": "Die Informationen zum Zurรผcksetzen wurden an Ihre E-Mail gesendet. Bitte รผberprรผfen Sie Ihr E-Mail-Postfach."
+}
diff --git a/worklenz-backend/src/public/locales/de/auth/login.json b/worklenz-backend/src/public/locales/de/auth/login.json
new file mode 100644
index 00000000..f42d0db9
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/auth/login.json
@@ -0,0 +1,27 @@
+{
+ "headerDescription": "Melden Sie sich an",
+ "emailLabel": "E-Mail",
+ "emailPlaceholder": "Ihre E-Mail-Adresse eingeben",
+ "emailRequired": "Bitte geben Sie Ihre E-Mail-Adresse ein!",
+ "passwordLabel": "Passwort",
+ "passwordPlaceholder": "Ihr Passwort eingeben",
+ "passwordRequired": "Bitte geben Sie Ihr Passwort ein!",
+ "rememberMe": "Erinnere dich an mich",
+ "loginButton": "Anmelden",
+ "signupButton": "Registrieren",
+ "forgotPasswordButton": "Passwort vergessen?",
+ "signInWithGoogleButton": "Mit Google anmelden",
+ "dontHaveAccountText": "Noch kein Konto?",
+ "orText": "ODER",
+ "successMessage": "Sie haben sich erfolgreich angemeldet!",
+ "loginError": "Anmeldung fehlgeschlagen",
+ "googleLoginError": "Google-Anmeldung fehlgeschlagen",
+ "validationMessages": {
+ "email": "Bitte geben Sie eine gรผltige E-Mail-Adresse ein",
+ "password": "Das Passwort muss mindestens 8 Zeichen lang sein"
+ },
+ "errorMessages": {
+ "loginErrorTitle": "Anmeldung fehlgeschlagen",
+ "loginErrorMessage": "Bitte รผberprรผfen Sie Ihre E-Mail-Adresse und Ihr Passwort und versuchen Sie es erneut"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/de/auth/signup.json b/worklenz-backend/src/public/locales/de/auth/signup.json
new file mode 100644
index 00000000..55a63a23
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/auth/signup.json
@@ -0,0 +1,29 @@
+{
+ "headerDescription": "Registrieren Sie sich, um loszulegen",
+ "nameLabel": "Vollstรคndiger Name",
+ "namePlaceholder": "Ihren vollstรคndigen Namen eingeben",
+ "nameRequired": "Bitte geben Sie Ihren vollstรคndigen Namen ein!",
+ "nameMinCharacterRequired": "Der Name muss mindestens 4 Zeichen lang sein!",
+ "emailLabel": "E-Mail",
+ "emailPlaceholder": "Ihre E-Mail-Adresse eingeben",
+ "emailRequired": "Bitte geben Sie Ihre E-Mail-Adresse ein!",
+ "passwordLabel": "Passwort",
+ "passwordPlaceholder": "Ihr Passwort eingeben",
+ "passwordRequired": "Bitte geben Sie Ihr Passwort ein!",
+ "passwordMinCharacterRequired": "Das Passwort muss mindestens 8 Zeichen lang sein!",
+ "passwordPatternRequired": "Das Passwort erfรผllt nicht die Anforderungen!",
+ "strongPasswordPlaceholder": "Ein stรคrkeres Passwort eingeben",
+ "passwordValidationAltText": "Das Passwort muss mindestens 8 Zeichen enthalten, mit Groร- und Kleinbuchstaben, einer Zahl und einem Sonderzeichen.",
+ "signupSuccessMessage": "Sie haben sich erfolgreich registriert!",
+ "privacyPolicyLink": "Datenschutzrichtlinie",
+ "termsOfUseLink": "Nutzungsbedingungen",
+ "bySigningUpText": "Mit der Registrierung stimmen Sie unseren",
+ "andText": "und",
+ "signupButton": "Registrieren",
+ "signInWithGoogleButton": "Mit Google anmelden",
+ "alreadyHaveAccountText": "Sie haben bereits ein Konto?",
+ "loginButton": "Anmelden",
+ "orText": "ODER",
+ "reCAPTCHAVerificationError": "reCAPTCHA-Verifizierungsfehler",
+ "reCAPTCHAVerificationErrorMessage": "Wir konnten Ihre reCAPTCHA nicht verifizieren. Bitte versuchen Sie es erneut."
+}
diff --git a/worklenz-backend/src/public/locales/de/auth/verify-reset-email.json b/worklenz-backend/src/public/locales/de/auth/verify-reset-email.json
new file mode 100644
index 00000000..323c685f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/auth/verify-reset-email.json
@@ -0,0 +1,14 @@
+{
+ "title": "E-Mail zurรผcksetzen bestรคtigen",
+ "description": "Geben Sie Ihr neues Passwort ein",
+ "placeholder": "Neues Passwort eingeben",
+ "confirmPasswordPlaceholder": "Neues Passwort bestรคtigen",
+ "passwordHint": "Mindestens 8 Zeichen, mit Groร- und Kleinbuchstaben, einer Zahl und einem Sonderzeichen.",
+ "resetPasswordButton": "Passwort zurรผcksetzen",
+ "orText": "Oder",
+ "resendResetEmail": "Zurรผcksetz-E-Mail erneut senden",
+ "passwordRequired": "Bitte geben Sie Ihr neues Passwort ein",
+ "returnToLoginButton": "Zurรผck zur Anmeldung",
+ "confirmPasswordRequired": "Bitte bestรคtigen Sie Ihr neues Passwort",
+ "passwordMismatch": "Die beiden Passwรถrter stimmen nicht รผberein"
+}
diff --git a/worklenz-backend/src/public/locales/de/common.json b/worklenz-backend/src/public/locales/de/common.json
new file mode 100644
index 00000000..937ad4a9
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/common.json
@@ -0,0 +1,9 @@
+{
+ "login-success": "Anmeldung erfolgreich!",
+ "login-failed": "Anmeldung fehlgeschlagen. Bitte รผberprรผfen Sie Ihre Anmeldedaten und versuchen Sie es erneut.",
+ "signup-success": "Registrierung erfolgreich! Willkommen an Bord.",
+ "signup-failed": "Registrierung fehlgeschlagen. Bitte fรผllen Sie alle erforderlichen Felder aus und versuchen Sie es erneut.",
+ "reconnecting": "Vom Server getrennt.",
+ "connection-lost": "Verbindung zum Server fehlgeschlagen. Bitte รผberprรผfen Sie Ihre Internetverbindung.",
+ "connection-restored": "Erfolgreich mit dem Server verbunden"
+}
diff --git a/worklenz-backend/src/public/locales/de/create-first-project-form.json b/worklenz-backend/src/public/locales/de/create-first-project-form.json
new file mode 100644
index 00000000..02ce495e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/create-first-project-form.json
@@ -0,0 +1,13 @@
+{
+ "formTitle": "Erstellen Sie Ihr erstes Projekt",
+ "inputLabel": "An welchem Projekt arbeiten Sie gerade?",
+ "or": "oder",
+ "templateButton": "Aus Vorlage importieren",
+ "createFromTemplate": "Aus Vorlage erstellen",
+ "goBack": "Zurรผck",
+ "continue": "Weitermachen",
+ "cancel": "Abbrechen",
+ "create": "Erstellen",
+ "templateDrawerTitle": "Aus Vorlagen auswรคhlen",
+ "createProject": "Projekt erstellen"
+}
diff --git a/worklenz-backend/src/public/locales/de/create-first-tasks.json b/worklenz-backend/src/public/locales/de/create-first-tasks.json
new file mode 100644
index 00000000..ae7a4256
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/create-first-tasks.json
@@ -0,0 +1,7 @@
+{
+ "formTitle": "Erstellen Sie Ihre erste Aufgabe.",
+ "inputLabel": "Geben Sie einige Aufgaben ein, die Sie erledigen werden in",
+ "addAnother": "Einen weiteren hinzufรผgen",
+ "goBack": "Zurรผck",
+ "continue": "Weiter"
+}
diff --git a/worklenz-backend/src/public/locales/de/home.json b/worklenz-backend/src/public/locales/de/home.json
new file mode 100644
index 00000000..cc868952
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/home.json
@@ -0,0 +1,46 @@
+{
+ "todoList": {
+ "title": "Aufgabenliste",
+ "refreshTasks": "Aufgaben aktualisieren",
+ "addTask": "+ Aufgabe hinzufรผgen",
+ "noTasks": "Keine Aufgaben",
+ "pressEnter": "Drรผcken Sie",
+ "toCreate": "zum Erstellen.",
+ "markAsDone": "Als erledigt markieren"
+ },
+ "projects": {
+ "title": "Projekte",
+ "refreshProjects": "Projekte aktualisieren",
+ "noRecentProjects": "Sie sind aktuell keinem Projekt zugewiesen.",
+ "noFavouriteProjects": "Keine Projekte als Favoriten markiert.",
+ "recent": "Kรผrzlich",
+ "favourites": "Favoriten"
+ },
+ "tasks": {
+ "assignedToMe": "Mir zugewiesen",
+ "assignedByMe": "Von mir zugewiesen",
+ "all": "Alle",
+ "today": "Heute",
+ "upcoming": "Bevorstehend",
+ "overdue": "รberfรคllig",
+ "noDueDate": "Kein Fรคlligkeitsdatum",
+ "noTasks": "Keine Aufgaben zum Anzeigen.",
+ "addTask": "+ Aufgabe hinzufรผgen",
+ "name": "Name",
+ "project": "Projekt",
+ "status": "Status",
+ "dueDate": "Fรคlligkeitsdatum",
+ "dueDatePlaceholder": "Fรคlligkeitsdatum festlegen",
+ "tomorrow": "Morgen",
+ "nextWeek": "Nรคchste Woche",
+ "nextMonth": "Nรคchster Monat",
+ "projectRequired": "Bitte wรคhlen Sie ein Projekt aus",
+ "pressTabToSelectDueDateAndProject": "Drรผcken Sie Tab, um ein Fรคlligkeitsdatum und ein Projekt auszuwรคhlen",
+ "dueOn": "Fรคllige Aufgaben am",
+ "taskRequired": "Bitte fรผgen Sie eine Aufgabe hinzu",
+ "list": "Liste",
+ "calendar": "Kalender",
+ "tasks": "Aufgaben",
+ "refresh": "Aktualisieren"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/de/invite-initial-team-members.json b/worklenz-backend/src/public/locales/de/invite-initial-team-members.json
new file mode 100644
index 00000000..e3ba64ae
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/invite-initial-team-members.json
@@ -0,0 +1,8 @@
+{
+ "formTitle": "Laden Sie Ihr Team zur Zusammenarbeit ein",
+ "inputLabel": "Per E-Mail einladen",
+ "addAnother": "Weitere hinzufรผgen",
+ "goBack": "Zurรผck",
+ "continue": "Weitermachen",
+ "skipForNow": "Vorerst รผberspringen"
+}
diff --git a/worklenz-backend/src/public/locales/de/kanban-board.json b/worklenz-backend/src/public/locales/de/kanban-board.json
new file mode 100644
index 00000000..70e1f6ca
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/kanban-board.json
@@ -0,0 +1,30 @@
+{
+ "rename": "Umbenennen",
+ "delete": "Lรถschen",
+ "addTask": "Aufgabe hinzufรผgen",
+ "addSectionButton": "Abschnitt hinzufรผgen",
+ "changeCategory": "Kategorie รคndern",
+
+ "deleteTooltip": "Lรถschen",
+ "deleteConfirmationTitle": "Sind Sie sicher?",
+ "deleteConfirmationOk": "Ja",
+ "deleteConfirmationCancel": "Abbrechen",
+
+ "dueDate": "Fรคlligkeitsdatum",
+ "cancel": "Abbrechen",
+
+ "today": "Heute",
+ "tomorrow": "Morgen",
+ "assignToMe": "Mir zuweisen",
+ "archive": "Archivieren",
+
+ "newTaskNamePlaceholder": "Aufgabenname eingeben",
+ "newSubtaskNamePlaceholder": "Unteraufgabenname eingeben",
+ "untitledSection": "Unbenannter Abschnitt",
+ "unmapped": "Nicht zugeordnet",
+ "clickToChangeDate": "Klicken Sie, um das Datum zu รคndern",
+ "noDueDate": "Kein Fรคlligkeitsdatum",
+ "save": "Speichern",
+ "clear": "Lรถschen",
+ "nextWeek": "Nรคchste Woche"
+}
diff --git a/worklenz-backend/src/public/locales/de/license-expired.json b/worklenz-backend/src/public/locales/de/license-expired.json
new file mode 100644
index 00000000..437ddeb2
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/license-expired.json
@@ -0,0 +1,6 @@
+{
+ "title": "Ihre Worklenz-Testversion ist abgelaufen!",
+ "subtitle": "Bitte fรผhren Sie jetzt ein Upgrade durch.",
+ "button": "Jetzt upgraden",
+ "checking": "รberprรผfen des Abonnementstatus..."
+}
diff --git a/worklenz-backend/src/public/locales/de/navbar.json b/worklenz-backend/src/public/locales/de/navbar.json
new file mode 100644
index 00000000..c84912e4
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/navbar.json
@@ -0,0 +1,31 @@
+{
+ "logoAlt": "Worklenz-Logo",
+ "home": "Startseite",
+ "projects": "Projekte",
+ "schedule": "Zeitplan",
+ "reporting": "Berichterstattung",
+ "clients": "Kunden",
+ "teams": "Teams",
+ "labels": "Labels",
+ "jobTitles": "Jobtitel",
+ "upgradePlan": "Plan upgraden",
+ "upgradePlanTooltip": "Plan upgraden",
+ "invite": "Einladen",
+ "inviteTooltip": "Teammitglieder zur Teilnahme einladen",
+ "switchTeamTooltip": "Team wechseln",
+ "help": "Hilfe",
+ "notificationTooltip": "Benachrichtigungen anzeigen",
+ "profileTooltip": "Profil anzeigen",
+ "adminCenter": "Admin-Center",
+ "settings": "Einstellungen",
+ "logOut": "Abmelden",
+ "notificationsDrawer": {
+ "read": "Gelesene Benachrichtigungen",
+ "unread": "Ungelesene Benachrichtigungen",
+ "markAsRead": "Als gelesen markieren",
+ "readAndJoin": "Lesen & Beitreten",
+ "accept": "Annehmen",
+ "acceptAndJoin": "Annehmen & Beitreten",
+ "noNotifications": "Keine Benachrichtigungen"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/de/organization-name-form.json b/worklenz-backend/src/public/locales/de/organization-name-form.json
new file mode 100644
index 00000000..06d3efcf
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/organization-name-form.json
@@ -0,0 +1,5 @@
+{
+ "nameYourOrganization": "Benennen Sie Ihre Organisation.",
+ "worklenzAccountTitle": "Wรคhlen Sie einen Namen fรผr Ihr Worklenz-Konto.",
+ "continue": "Weiter"
+}
diff --git a/worklenz-backend/src/public/locales/de/phases-drawer.json b/worklenz-backend/src/public/locales/de/phases-drawer.json
new file mode 100644
index 00000000..c9e41e09
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/phases-drawer.json
@@ -0,0 +1,19 @@
+{
+ "configurePhases": "Phasen konfigurieren",
+ "phaseLabel": "Phasenbezeichnung",
+ "enterPhaseName": "Namen fรผr Phasenbezeichnung eingeben",
+ "addOption": "Option hinzufรผgen",
+ "phaseOptions": "Phasenoptionen:",
+ "dragToReorderPhases": "Ziehen Sie Phasen, um sie neu zu ordnen. Jede Phase kann eine andere Farbe haben.",
+ "enterNewPhaseName": "Neuen Phasennamen eingeben...",
+ "addPhase": "Phase hinzufรผgen",
+ "noPhasesFound": "Keine Phasen gefunden. Erstellen Sie Ihre erste Phase oben.",
+ "deletePhase": "Phase lรถschen",
+ "deletePhaseConfirm": "Sind Sie sicher, dass Sie diese Phase lรถschen mรถchten? Diese Aktion kann nicht rรผckgรคngig gemacht werden.",
+ "rename": "Umbenennen",
+ "delete": "Lรถschen",
+ "enterPhaseName": "Phasennamen eingeben",
+ "selectColor": "Farbe auswรคhlen",
+ "managePhases": "Phasen verwalten",
+ "close": "Schlieรen"
+}
diff --git a/worklenz-backend/src/public/locales/de/project-drawer.json b/worklenz-backend/src/public/locales/de/project-drawer.json
new file mode 100644
index 00000000..d20f220b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/project-drawer.json
@@ -0,0 +1,42 @@
+{
+ "createProject": "Projekt erstellen",
+ "editProject": "Projekt bearbeiten",
+ "enterCategoryName": "Namen fรผr die Kategorie eingeben",
+ "hitEnterToCreate": "Enter drรผcken zum Erstellen!",
+ "enterNotes": "Notizen",
+ "youCanManageClientsUnderSettings": "Kunden kรถnnen Sie unter Einstellungen verwalten",
+ "addCategory": "Kategorie zum Projekt hinzufรผgen",
+ "newCategory": "Neue Kategorie",
+ "notes": "Notizen",
+ "startDate": "Startdatum",
+ "endDate": "Enddatum",
+ "estimateWorkingDays": "Arbeitstage schรคtzen",
+ "estimateManDays": "Personentage schรคtzen",
+ "hoursPerDay": "Stunden pro Tag",
+ "create": "Erstellen",
+ "update": "Aktualisieren",
+ "delete": "Lรถschen",
+ "typeToSearchClients": "Kundensuche",
+ "projectColor": "Projektfarbe",
+ "pleaseEnterAName": "Bitte geben Sie einen Namen ein",
+ "enterProjectName": "Projektnamen eingeben",
+ "name": "Name",
+ "status": "Status",
+ "health": "Gesundheit",
+ "category": "Kategorie",
+ "projectManager": "Projektleiter",
+ "client": "Kunde",
+ "deleteConfirmation": "Sind Sie sicher, dass Sie lรถschen mรถchten?",
+ "deleteConfirmationDescription": "Dies entfernt alle zugehรถrigen Daten und kann nicht rรผckgรคngig gemacht werden.",
+ "yes": "Ja",
+ "no": "Nein",
+ "createdAt": "Erstellt am",
+ "updatedAt": "Aktualisiert am",
+ "by": "von",
+ "add": "Hinzufรผgen",
+ "asClient": "als Kunde",
+ "createClient": "Kunde erstellen",
+ "searchInputPlaceholder": "Nach Name oder E-Mail suchen",
+ "hoursPerDayValidationMessage": "Stunden pro Tag mรผssen zwischen 1 und 24",
+ "noPermission": "Keine Berechtigung"
+}
diff --git a/worklenz-backend/src/public/locales/de/project-view-files.json b/worklenz-backend/src/public/locales/de/project-view-files.json
new file mode 100644
index 00000000..8408df16
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/project-view-files.json
@@ -0,0 +1,14 @@
+{
+ "nameColumn": "Name",
+ "attachedTaskColumn": "Zugehรถrige Aufgabe",
+ "sizeColumn": "Grรถรe",
+ "uploadedByColumn": "Hochgeladen von",
+ "uploadedAtColumn": "Hochgeladen am",
+ "fileIconAlt": "Dateisymbol",
+ "titleDescriptionText": "Alle Anhรคnge zu Aufgaben in diesem Projekt werden hier angezeigt.",
+ "deleteConfirmationTitle": "Sind Sie sicher?",
+ "deleteConfirmationOk": "Ja",
+ "deleteConfirmationCancel": "Abbrechen",
+ "segmentedTooltip": "Demnรคchst verfรผgbar! Wechseln zwischen Listenansicht und Miniaturansicht.",
+ "emptyText": "Es gibt keine Anhรคnge in diesem Projekt."
+}
diff --git a/worklenz-backend/src/public/locales/de/project-view-insights.json b/worklenz-backend/src/public/locales/de/project-view-insights.json
new file mode 100644
index 00000000..5f11df54
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/project-view-insights.json
@@ -0,0 +1,41 @@
+{
+ "overview": {
+ "title": "รbersicht",
+ "statusOverview": "Statusรผbersicht",
+ "priorityOverview": "Prioritรคtenรผbersicht",
+ "lastUpdatedTasks": "Zuletzt aktualisierte Aufgaben"
+ },
+ "members": {
+ "title": "Mitglieder",
+ "tooltip": "Mitglieder",
+ "tasksByMembers": "Aufgaben nach Mitgliedern",
+ "tasksByMembersTooltip": "Aufgaben nach Mitgliedern",
+ "name": "Name",
+ "taskCount": "Anzahl Aufgaben",
+ "contribution": "Beitrag",
+ "completed": "Abgeschlossen",
+ "incomplete": "Unvollstรคndig",
+ "overdue": "รberfรคllig",
+ "progress": "Fortschritt"
+ },
+ "tasks": {
+ "overdueTasks": "รberfรคllige Aufgaben",
+ "overLoggedTasks": "Aufgaben mit zu viel erfasster Zeit",
+ "tasksCompletedEarly": "Vorzeitig abgeschlossene Aufgaben",
+ "tasksCompletedLate": "Verspรคtet abgeschlossene Aufgaben",
+ "overLoggedTasksTooltip": "Aufgaben, bei denen mehr Zeit erfasst wurde als geschรคtzt",
+ "overdueTasksTooltip": "Aufgaben, deren Fรคlligkeitsdatum รผberschritten wurde"
+ },
+ "common": {
+ "seeAll": "Alle anzeigen",
+ "totalLoggedHours": "Gesamterfasste Stunden",
+ "totalEstimation": "Gesamtschรคtzung",
+ "completedTasks": "Abgeschlossene Aufgaben",
+ "incompleteTasks": "Unvollstรคndige Aufgaben",
+ "overdueTasks": "รberfรคllige Aufgaben",
+ "overdueTasksTooltip": "Aufgaben, deren Fรคlligkeitsdatum รผberschritten wurde",
+ "totalLoggedHoursTooltip": "Zeitschรคtzung und erfasste Zeit fรผr Aufgaben.",
+ "includeArchivedTasks": "Archivierte Aufgaben einbeziehen",
+ "export": "Exportieren"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/de/project-view-members.json b/worklenz-backend/src/public/locales/de/project-view-members.json
new file mode 100644
index 00000000..eee5d0a1
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/project-view-members.json
@@ -0,0 +1,17 @@
+{
+ "nameColumn": "Name",
+ "jobTitleColumn": "Jobtitel",
+ "emailColumn": "E-Mail",
+ "tasksColumn": "Aufgaben",
+ "taskProgressColumn": "Aufgabenfortschritt",
+ "accessColumn": "Zugriff",
+ "fileIconAlt": "Dateisymbol",
+ "deleteConfirmationTitle": "Sind Sie sicher?",
+ "deleteConfirmationOk": "Ja",
+ "deleteConfirmationCancel": "Abbrechen",
+ "refreshButtonTooltip": "Mitglieder aktualisieren",
+ "deleteButtonTooltip": "Aus Projekt entfernen",
+ "memberCount": "Mitglied",
+ "membersCountPlural": "Mitglieder",
+ "emptyText": "Es gibt keine Anhรคnge in diesem Projekt."
+}
diff --git a/worklenz-backend/src/public/locales/de/project-view-updates.json b/worklenz-backend/src/public/locales/de/project-view-updates.json
new file mode 100644
index 00000000..d32cf352
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/project-view-updates.json
@@ -0,0 +1,6 @@
+{
+ "inputPlaceholder": "Kommentar hinzufรผgen..",
+ "addButton": "Hinzufรผgen",
+ "cancelButton": "Abbrechen",
+ "deleteButton": "Lรถschen"
+}
diff --git a/worklenz-backend/src/public/locales/de/project-view.json b/worklenz-backend/src/public/locales/de/project-view.json
new file mode 100644
index 00000000..448a7249
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/project-view.json
@@ -0,0 +1,14 @@
+{
+ "taskList": "Aufgabenliste",
+ "board": "Kanban-Board",
+ "insights": "Insights",
+ "files": "Dateien",
+ "members": "Mitglieder",
+ "updates": "Aktualisierungen",
+ "projectView": "Projektansicht",
+ "loading": "Projekt wird geladen...",
+ "error": "Fehler beim Laden des Projekts",
+ "pinnedTab": "Als Standard-Registerkarte festgesetzt",
+ "pinTab": "Als Standard-Registerkarte festsetzen",
+ "unpinTab": "Standard-Registerkarte lรถsen"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/de/project-view/import-task-templates.json b/worklenz-backend/src/public/locales/de/project-view/import-task-templates.json
new file mode 100644
index 00000000..c5af50a0
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/project-view/import-task-templates.json
@@ -0,0 +1,11 @@
+{
+ "importTaskTemplate": "Aufgabenvorlage importieren",
+ "templateName": "Vorlagenname",
+ "templateDescription": "Vorlagenbeschreibung",
+ "selectedTasks": "Ausgewรคhlte Aufgaben",
+ "tasks": "Aufgaben",
+ "templates": "Vorlagen",
+ "remove": "Entfernen",
+ "cancel": "Abbrechen",
+ "import": "Importieren"
+}
diff --git a/worklenz-backend/src/public/locales/de/project-view/project-member-drawer.json b/worklenz-backend/src/public/locales/de/project-view/project-member-drawer.json
new file mode 100644
index 00000000..cb391b2c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/project-view/project-member-drawer.json
@@ -0,0 +1,7 @@
+{
+ "title": "Projektmitglieder",
+ "searchLabel": "Mitglieder hinzufรผgen durch Eingabe von Name oder E-Mail",
+ "searchPlaceholder": "Name oder E-Mail eingeben",
+ "inviteAsAMember": "Als Mitglied einladen",
+ "inviteNewMemberByEmail": "Neues Mitglied per E-Mail einladen"
+}
diff --git a/worklenz-backend/src/public/locales/de/project-view/project-view-header.json b/worklenz-backend/src/public/locales/de/project-view/project-view-header.json
new file mode 100644
index 00000000..c52c6052
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/project-view/project-view-header.json
@@ -0,0 +1,30 @@
+{
+ "importTasks": "Aufgaben importieren",
+ "importTask": "Aufgabe importieren",
+ "createTask": "Aufgabe erstellen",
+ "settings": "Einstellungen",
+ "subscribe": "Abonnieren",
+ "unsubscribe": "Abonnement beenden",
+ "deleteProject": "Projekt lรถschen",
+ "startDate": "Startdatum",
+ "endDate": "Enddatum",
+ "projectSettings": "Projekteinstellungen",
+ "projectSummary": "Projektzusammenfassung",
+ "receiveProjectSummary": "Erhalten Sie jeden Abend eine Projektzusammenfassung.",
+ "refreshProject": "Projekt aktualisieren",
+ "saveAsTemplate": "Als Vorlage speichern",
+ "invite": "Einladen",
+ "share": "Teilen",
+ "subscribeTooltip": "Projektbenachrichtigungen abonnieren",
+ "unsubscribeTooltip": "Projektbenachrichtigungen beenden",
+ "refreshTooltip": "Projektdaten aktualisieren",
+ "settingsTooltip": "Projekteinstellungen รถffnen",
+ "saveAsTemplateTooltip": "Dieses Projekt als Vorlage speichern",
+ "inviteTooltip": "Teammitglieder zu diesem Projekt einladen",
+ "createTaskTooltip": "Neue Aufgabe erstellen",
+ "importTaskTooltip": "Aufgabe aus Vorlage importieren",
+ "navigateBackTooltip": "Zurรผck zur Projektliste",
+ "projectStatusTooltip": "Projektstatus",
+ "projectDatesInfo": "Informationen zum Projektzeitraum",
+ "projectCategoryTooltip": "Projektkategorie"
+}
diff --git a/worklenz-backend/src/public/locales/de/project-view/save-as-template.json b/worklenz-backend/src/public/locales/de/project-view/save-as-template.json
new file mode 100644
index 00000000..7b732962
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/project-view/save-as-template.json
@@ -0,0 +1,27 @@
+{
+ "title": "Als Vorlage speichern",
+ "templateName": "Vorlagenname",
+ "includes": "Was soll aus dem Projekt in die Vorlage aufgenommen werden?",
+ "includesOptions": {
+ "statuses": "Status",
+ "phases": "Phasen",
+ "labels": "Labels"
+ },
+ "taskIncludes": "Was soll aus den Aufgaben in die Vorlage aufgenommen werden?",
+ "taskIncludesOptions": {
+ "statuses": "Status",
+ "phases": "Phasen",
+ "labels": "Labels",
+ "name": "Name",
+ "priority": "Prioritรคt",
+ "status": "Status",
+ "phase": "Phase",
+ "label": "Label",
+ "timeEstimate": "Zeitschรคtzung",
+ "description": "Beschreibung",
+ "subTasks": "Unteraufgaben"
+ },
+ "cancel": "Abbrechen",
+ "save": "Speichern",
+ "templateNamePlaceholder": "Vorlagennamen eingeben"
+}
diff --git a/worklenz-backend/src/public/locales/de/reporting-members-drawer.json b/worklenz-backend/src/public/locales/de/reporting-members-drawer.json
new file mode 100644
index 00000000..807f43c7
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/reporting-members-drawer.json
@@ -0,0 +1,90 @@
+{
+ "exportButton": "Exportieren",
+ "timeLogsButton": "Zeiterfassungen",
+ "activityLogsButton": "Aktivitรคtsprotokolle",
+ "tasksButton": "Aufgaben",
+ "searchByNameInputPlaceholder": "Nach Namen suchen",
+
+ "overviewTab": "รbersicht",
+ "timeLogsTab": "Zeiterfassungen",
+ "activityLogsTab": "Aktivitรคtsprotokolle",
+ "tasksTab": "Aufgaben",
+
+ "projectsText": "Projekte",
+ "totalTasksText": "Gesamtaufgaben",
+ "assignedTasksText": "Zugewiesene Aufgaben",
+ "completedTasksText": "Abgeschlossene Aufgaben",
+ "ongoingTasksText": "Laufende Aufgaben",
+ "overdueTasksText": "รberfรคllige Aufgaben",
+ "loggedHoursText": "Erfasste Stunden",
+
+ "tasksText": "Aufgaben",
+ "allText": "Alle",
+
+ "tasksByProjectsText": "Aufgaben nach Projekten",
+ "tasksByStatusText": "Aufgaben nach Status",
+ "tasksByPriorityText": "Aufgaben nach Prioritรคt",
+
+ "todoText": "Zu erledigen",
+ "doingText": "Tun",
+ "doneText": "Erledigt",
+ "lowText": "Niedrig",
+ "mediumText": "Mittel",
+ "highText": "Hoch",
+
+ "billableButton": "Abrechenbar",
+ "billableText": "Abrechenbar",
+ "nonBillableText": "Nicht abrechenbar",
+
+ "timeLogsEmptyPlaceholder": "Keine Zeiterfassungen vorhanden",
+ "loggedText": "Erfasst",
+ "forText": "fรผr",
+ "inText": "in",
+ "updatedText": "Aktualisiert",
+ "fromText": "Von",
+ "toText": "bis",
+ "withinText": "innerhalb",
+
+ "activityLogsEmptyPlaceholder": "Keine Aktivitรคtsprotokolle vorhanden",
+
+ "filterByText": "Filtern nach:",
+ "selectProjectPlaceholder": "Projekt auswรคhlen",
+
+ "taskColumn": "Aufgabe",
+ "nameColumn": "Name",
+ "projectColumn": "Projekt",
+ "statusColumn": "Status",
+ "priorityColumn": "Prioritรคt",
+ "dueDateColumn": "Fรคlligkeitsdatum",
+ "completedDateColumn": "Abschlussdatum",
+ "estimatedTimeColumn": "Geschรคtzte Zeit",
+ "loggedTimeColumn": "Erfasste Zeit",
+ "overloggedTimeColumn": "รbererfasste Zeit",
+ "daysLeftColumn": "Tage รผbrig/รผberfรคllig",
+ "startDateColumn": "Startdatum",
+ "endDateColumn": "Enddatum",
+ "actualTimeColumn": "Tatsรคchliche Zeit",
+ "projectHealthColumn": "Projektstatus",
+ "categoryColumn": "Kategorie",
+ "projectManagerColumn": "Projektleiter",
+
+ "tasksStatsOverviewDrawerTitle": "Aufgaben von",
+ "projectsStatsOverviewDrawerTitle": "Projekte von",
+
+ "cancelledText": "Abgebrochen",
+ "blockedText": "Blockiert",
+ "onHoldText": "Pausiert",
+ "proposedText": "Vorgeschlagen",
+ "inPlanningText": "In Planung",
+ "inProgressText": "In Bearbeitung",
+ "completedText": "Abgeschlossen",
+ "continuousText": "Kontinuierlich",
+
+ "daysLeftText": "Tage รผbrig",
+ "daysOverdueText": "Tage รผberfรคllig",
+
+ "notSetText": "Nicht festgelegt",
+ "needsAttentionText": "Benรถtigt Aufmerksamkeit",
+ "atRiskText": "Gefรคhrdet",
+ "goodText": "Gut"
+}
diff --git a/worklenz-backend/src/public/locales/de/reporting-members.json b/worklenz-backend/src/public/locales/de/reporting-members.json
new file mode 100644
index 00000000..5454d2a8
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/reporting-members.json
@@ -0,0 +1,35 @@
+{
+ "yesterdayText": "Gestern",
+ "lastSevenDaysText": "Letzte 7 Tage",
+ "lastWeekText": "Letzte Woche",
+ "lastThirtyDaysText": "Letzte 30 Tage",
+ "lastMonthText": "Letzter Monat",
+ "lastThreeMonthsText": "Letzte 3 Monate",
+ "allTimeText": "Gesamter Zeitraum",
+ "customRangeText": "Benutzerdefinierter Bereich",
+ "startDateInputPlaceholder": "Startdatum",
+ "EndDateInputPlaceholder": "Enddatum",
+ "filterButton": "Filtern",
+
+ "membersTitle": "Mitglieder",
+ "includeArchivedButton": "Archivierte Projekte einschlieรen",
+ "exportButton": "Exportieren",
+ "excelButton": "Excel",
+ "searchByNameInputPlaceholder": "Nach Namen suchen",
+
+ "memberColumn": "Mitglied",
+ "tasksProgressColumn": "Aufgabenfortschritt",
+ "tasksAssignedColumn": "Zugewiesene Aufgaben",
+ "completedTasksColumn": "Abgeschlossene Aufgaben",
+ "overdueTasksColumn": "รberfรคllige Aufgaben",
+ "ongoingTasksColumn": "Laufende Aufgaben",
+
+ "tasksAssignedColumnTooltip": "Im ausgewรคhlten Zeitraum zugewiesene Aufgaben",
+ "overdueTasksColumnTooltip": "Zum Ende des ausgewรคhlten Zeitraums รผberfรคllige Aufgaben",
+ "completedTasksColumnTooltip": "Im ausgewรคhlten Zeitraum abgeschlossene Aufgaben",
+ "ongoingTasksColumnTooltip": "Begonnene, aber noch nicht abgeschlossene Aufgaben",
+
+ "todoText": "Zu erledigen",
+ "doingText": "Tun",
+ "doneText": "Erledigt"
+}
diff --git a/worklenz-backend/src/public/locales/de/reporting-overview-drawer.json b/worklenz-backend/src/public/locales/de/reporting-overview-drawer.json
new file mode 100644
index 00000000..6bf4678a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/reporting-overview-drawer.json
@@ -0,0 +1,39 @@
+{
+ "exportButton": "Exportieren",
+ "projectsButton": "Projekte",
+ "membersButton": "Mitglieder",
+ "searchByNameInputPlaceholder": "Nach Namen suchen",
+
+ "overviewTab": "รbersicht",
+ "projectsTab": "Projekte",
+ "membersTab": "Mitglieder",
+
+ "projectsByStatusText": "Projekte nach Status",
+ "projectsByCategoryText": "Projekte nach Kategorie",
+ "projectsByHealthText": "Projekte nach Gesundheit",
+
+ "projectsText": "Projekte",
+ "allText": "Alle",
+
+ "cancelledText": "Abgebrochen",
+ "blockedText": "Blockiert",
+ "onHoldText": "Pausiert",
+ "proposedText": "Vorgeschlagen",
+ "inPlanningText": "In Planung",
+ "inProgressText": "In Bearbeitung",
+ "completedText": "Abgeschlossen",
+ "continuousText": "Kontinuierlich",
+
+ "notSetText": "Nicht festgelegt",
+ "needsAttentionText": "Benรถtigt Aufmerksamkeit",
+ "atRiskText": "Gefรคhrdet",
+ "goodText": "Gut",
+
+ "nameColumn": "Name",
+ "emailColumn": "E-Mail",
+ "projectsColumn": "Projekte",
+ "tasksColumn": "Aufgaben",
+ "overdueTasksColumn": "รberfรคllige Aufgaben",
+ "completedTasksColumn": "Abgeschlossene Aufgaben",
+ "ongoingTasksColumn": "Laufende Aufgaben"
+}
diff --git a/worklenz-backend/src/public/locales/de/reporting-overview.json b/worklenz-backend/src/public/locales/de/reporting-overview.json
new file mode 100644
index 00000000..411ec83a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/reporting-overview.json
@@ -0,0 +1,25 @@
+{
+ "overviewTitle": "รbersicht",
+ "includeArchivedButton": "Archivierte Projekte einschlieรen",
+
+ "teamCount": "Team",
+ "teamCountPlural": "Teams",
+ "projectCount": "Projekt",
+ "projectCountPlural": "Projekte",
+ "memberCount": "Mitglied",
+ "memberCountPlural": "Mitglieder",
+ "activeProjectCount": "Aktives Projekt",
+ "activeProjectCountPlural": "Aktive Projekte",
+ "overdueProjectCount": "รberfรคlliges Projekt",
+ "overdueProjectCountPlural": "รberfรคllige Projekte",
+ "unassignedMemberCount": "Nicht zugewiesenes Mitglied",
+ "unassignedMemberCountPlural": "Nicht zugewiesene Mitglieder",
+ "memberWithOverdueTaskCount": "Mitglied mit รผberfรคlliger Aufgabe",
+ "memberWithOverdueTaskCountPlural": "Mitglieder mit รผberfรคlligen Aufgaben",
+
+ "teamsText": "Teams",
+
+ "nameColumn": "Name",
+ "projectsColumn": "Projekte",
+ "membersColumn": "Mitglieder"
+}
diff --git a/worklenz-backend/src/public/locales/de/reporting-projects-drawer.json b/worklenz-backend/src/public/locales/de/reporting-projects-drawer.json
new file mode 100644
index 00000000..3f335a6c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/reporting-projects-drawer.json
@@ -0,0 +1,59 @@
+{
+ "exportButton": "Exportieren",
+ "membersButton": "Mitglieder",
+ "tasksButton": "Aufgaben",
+ "searchByNameInputPlaceholder": "Nach Namen suchen",
+
+ "overviewTab": "รbersicht",
+ "membersTab": "Mitglieder",
+ "tasksTab": "Aufgaben",
+
+ "completedTasksText": "Abgeschlossene Aufgaben",
+ "incompleteTasksText": "Unvollstรคndige Aufgaben",
+ "overdueTasksText": "รberfรคllige Aufgaben",
+ "allocatedHoursText": "Zugewiesene Stunden",
+ "loggedHoursText": "Erfasste Stunden",
+
+ "tasksText": "Aufgaben",
+ "allText": "Alle",
+
+ "tasksByStatusText": "Aufgaben nach Status",
+ "tasksByPriorityText": "Aufgaben nach Prioritรคt",
+ "tasksByDueDateText": "Aufgaben nach Fรคlligkeit",
+
+ "todoText": "Zu erledigen",
+ "doingText": "Tun",
+ "doneText": "Erledigt",
+ "lowText": "Niedrig",
+ "mediumText": "Mittel",
+ "highText": "Hoch",
+ "completedText": "Abgeschlossen",
+ "upcomingText": "Bevorstehend",
+ "overdueText": "รberfรคllig",
+ "noDueDateText": "Kein Fรคlligkeitsdatum",
+
+ "nameColumn": "Name",
+ "tasksCountColumn": "Anzahl Aufgaben",
+ "completedTasksColumn": "Abgeschlossene Aufgaben",
+ "incompleteTasksColumn": "Unvollstรคndige Aufgaben",
+ "overdueTasksColumn": "รberfรคllige Aufgaben",
+ "contributionColumn": "Beitrag",
+ "progressColumn": "Fortschritt",
+ "loggedTimeColumn": "Erfasste Zeit",
+ "taskColumn": "Aufgabe",
+ "projectColumn": "Projekt",
+ "statusColumn": "Status",
+ "priorityColumn": "Prioritรคt",
+ "phaseColumn": "Phase",
+ "dueDateColumn": "Fรคlligkeitsdatum",
+ "completedDateColumn": "Abschlussdatum",
+ "estimatedTimeColumn": "Geschรคtzte Zeit",
+ "overloggedTimeColumn": "รbererfasste Zeit",
+ "completedOnColumn": "Abgeschlossen am",
+ "daysOverdueColumn": "Tage รผberfรคllig",
+
+ "groupByText": "Gruppieren nach:",
+ "statusText": "Status",
+ "priorityText": "Prioritรคt",
+ "phaseText": "Phase"
+}
diff --git a/worklenz-backend/src/public/locales/de/reporting-projects-filters.json b/worklenz-backend/src/public/locales/de/reporting-projects-filters.json
new file mode 100644
index 00000000..c48fa256
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/reporting-projects-filters.json
@@ -0,0 +1,35 @@
+{
+ "searchByNamePlaceholder": "Nach Namen suchen",
+ "searchByCategoryPlaceholder": "Nach Kategorie suchen",
+
+ "statusText": "Status",
+ "healthText": "Gesundheit",
+ "categoryText": "Kategorie",
+ "projectManagerText": "Projektleiter",
+ "showFieldsText": "Felder anzeigen",
+
+ "cancelledText": "Abgebrochen",
+ "blockedText": "Blockiert",
+ "onHoldText": "Pausiert",
+ "proposedText": "Vorgeschlagen",
+ "inPlanningText": "In Planung",
+ "inProgressText": "In Bearbeitung",
+ "completedText": "Abgeschlossen",
+ "continuousText": "Kontinuierlich",
+
+ "notSetText": "Nicht festgelegt",
+ "needsAttentionText": "Benรถtigt Aufmerksamkeit",
+ "atRiskText": "Gefรคhrdet",
+ "goodText": "Gut",
+
+ "nameText": "Projekt",
+ "estimatedVsActualText": "Geplant vs. Tatsรคchlich",
+ "tasksProgressText": "Aufgabenfortschritt",
+ "lastActivityText": "Letzte Aktivitรคt",
+ "datesText": "Start-/Enddatum",
+ "daysLeftText": "Tage รผbrig/รผberfรคllig",
+ "projectHealthText": "Projektstatus",
+ "projectUpdateText": "Projektupdate",
+ "clientText": "Kunde",
+ "teamText": "Team"
+}
diff --git a/worklenz-backend/src/public/locales/de/reporting-projects.json b/worklenz-backend/src/public/locales/de/reporting-projects.json
new file mode 100644
index 00000000..0f63310b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/reporting-projects.json
@@ -0,0 +1,52 @@
+{
+ "projectCount": "Projekt",
+ "projectCountPlural": "Projekte",
+ "includeArchivedButton": "Archivierte Projekte einschlieรen",
+ "exportButton": "Exportieren",
+ "excelButton": "Excel",
+
+ "projectColumn": "Projekt",
+ "estimatedVsActualColumn": "Geschรคtzt vs. Tatsรคchlich",
+ "tasksProgressColumn": "Aufgabenfortschritt",
+ "lastActivityColumn": "Letzte Aktivitรคt",
+ "statusColumn": "Status",
+ "datesColumn": "Start-/Enddatum",
+ "daysLeftColumn": "Tage รผbrig/รผberfรคllig",
+ "projectHealthColumn": "Projektzustand",
+ "categoryColumn": "Kategorie",
+ "projectUpdateColumn": "Projektupdate",
+ "clientColumn": "Kunde",
+ "teamColumn": "Team",
+ "projectManagerColumn": "Projektleiter",
+
+ "openButton": "รffnen",
+
+ "estimatedText": "Geschรคtzt",
+ "actualText": "Tatsรคchlich",
+
+ "todoText": "Zu erledigen",
+ "doingText": "Tun",
+ "doneText": "Erledigt",
+
+ "cancelledText": "Abgebrochen",
+ "blockedText": "Blockiert",
+ "onHoldText": "Pausiert",
+ "proposedText": "Vorgeschlagen",
+ "inPlanningText": "In Planung",
+ "inProgressText": "In Bearbeitung",
+ "completedText": "Abgeschlossen",
+ "continuousText": "Kontinuierlich",
+
+ "daysLeftText": "Tage รผbrig",
+ "dayLeftText": "Tag รผbrig",
+ "daysOverdueText": "Tage รผberfรคllig",
+
+ "notSetText": "Nicht festgelegt",
+ "needsAttentionText": "Benรถtigt Aufmerksamkeit",
+ "atRiskText": "Gefรคhrdet",
+ "goodText": "Gut",
+
+ "setCategoryText": "Kategorie festlegen",
+ "searchByNameInputPlaceholder": "Nach Namen suchen",
+ "todayText": "Heute"
+}
diff --git a/worklenz-backend/src/public/locales/de/reporting-sidebar.json b/worklenz-backend/src/public/locales/de/reporting-sidebar.json
new file mode 100644
index 00000000..74d6bfb9
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/reporting-sidebar.json
@@ -0,0 +1,8 @@
+{
+ "overview": "รbersicht",
+ "projects": "Projekte",
+ "members": "Mitglieder",
+ "timeReports": "Zeitberichte",
+ "estimateVsActual": "Schรคtzen vs. Tatsรคchlich",
+ "currentOrganizationTooltip": "Aktuelle Organisation"
+}
diff --git a/worklenz-backend/src/public/locales/de/schedule.json b/worklenz-backend/src/public/locales/de/schedule.json
new file mode 100644
index 00000000..046c7bb0
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/schedule.json
@@ -0,0 +1,39 @@
+{
+ "today": "Heute",
+ "week": "Woche",
+ "month": "Monat",
+
+ "settings": "Einstellungen",
+ "workingDays": "Arbeitstage",
+ "monday": "Montag",
+ "tuesday": "Dienstag",
+ "wednesday": "Mittwoch",
+ "thursday": "Donnerstag",
+ "friday": "Freitag",
+ "saturday": "Samstag",
+ "sunday": "Sonntag",
+ "workingHours": "Arbeitsstunden",
+ "hours": "Stunden",
+ "saveButton": "Speichern",
+
+ "totalAllocation": "Gesamtzuteilung",
+ "timeLogged": "Zeiterfassung",
+ "remainingTime": "Verbleibende Zeit",
+ "total": "Gesamt",
+ "perDay": "Pro Tag",
+ "tasks": "Aufgaben",
+ "startDate": "Startdatum",
+ "endDate": "Enddatum",
+
+ "hoursPerDay": "Stunden pro Tag",
+ "totalHours": "Gesamtstunden",
+ "deleteButton": "Lรถschen",
+ "cancelButton": "Abbrechen",
+
+ "tabTitle": "Aufgaben ohne Start- & Enddatum",
+
+ "allocatedTime": "Zugewiesene Zeit",
+ "totalLogged": "Gesamterfasst",
+ "loggedBillable": "Abrechenbar erfasst",
+ "loggedNonBillable": "Nicht abrechenbar erfasst"
+}
diff --git a/worklenz-backend/src/public/locales/de/settings/categories.json b/worklenz-backend/src/public/locales/de/settings/categories.json
new file mode 100644
index 00000000..5694d11d
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/settings/categories.json
@@ -0,0 +1,10 @@
+{
+ "categoryColumn": "Kategorie",
+ "deleteConfirmationTitle": "Sind Sie sicher?",
+ "deleteConfirmationOk": "Ja",
+ "deleteConfirmationCancel": "Abbrechen",
+ "associatedTaskColumn": "Zugehรถrige Projekte",
+ "searchPlaceholder": "Nach Namen suchen",
+ "emptyText": "Kategorien kรถnnen beim Aktualisieren oder Erstellen von Projekten angelegt werden.",
+ "colorChangeTooltip": "Zum Farbwechsel klicken"
+}
diff --git a/worklenz-backend/src/public/locales/de/settings/change-password.json b/worklenz-backend/src/public/locales/de/settings/change-password.json
new file mode 100644
index 00000000..6b65a8cf
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/settings/change-password.json
@@ -0,0 +1,15 @@
+{
+ "title": "Passwort รคndern",
+ "currentPassword": "Aktuelles Passwort",
+ "newPassword": "Neues Passwort",
+ "confirmPassword": "Passwort bestรคtigen",
+ "currentPasswordPlaceholder": "Aktuelles Passwort eingeben",
+ "newPasswordPlaceholder": "Neues Passwort",
+ "confirmPasswordPlaceholder": "Passwort bestรคtigen",
+ "currentPasswordRequired": "Bitte geben Sie Ihr aktuelles Passwort ein!",
+ "newPasswordRequired": "Bitte geben Sie Ihr neues Passwort ein!",
+ "passwordValidationError": "Das Passwort muss mindestens 8 Zeichen lang sein und einen Groรbuchstaben, eine Zahl und ein Sonderzeichen enthalten.",
+ "passwordMismatch": "Die Passwรถrter stimmen nicht รผberein!",
+ "passwordRequirements": "Das neue Passwort muss mindestens 8 Zeichen lang sein und einen Groรbuchstaben, eine Zahl und ein Sonderzeichen enthalten.",
+ "updateButton": "Passwort aktualisieren"
+}
diff --git a/worklenz-backend/src/public/locales/de/settings/clients.json b/worklenz-backend/src/public/locales/de/settings/clients.json
new file mode 100644
index 00000000..d2982bdb
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/settings/clients.json
@@ -0,0 +1,22 @@
+{
+ "nameColumn": "Name",
+ "projectColumn": "Projekt",
+ "noProjectsAvailable": "Keine Projekte verfรผgbar",
+ "deleteConfirmationTitle": "Sind Sie sicher?",
+ "deleteConfirmationOk": "Ja",
+ "deleteConfirmationCancel": "Abbrechen",
+ "searchPlaceholder": "Nach Namen suchen",
+ "createClient": "Kunde anlegen",
+ "pinTooltip": "Zum Anheften an das Hauptmenรผ klicken",
+ "createClientDrawerTitle": "Kunde anlegen",
+ "updateClientDrawerTitle": "Kunde aktualisieren",
+ "nameLabel": "Name",
+ "namePlaceholder": "Name",
+ "nameRequiredError": "Bitte geben Sie einen Namen ein",
+ "createButton": "Anlegen",
+ "updateButton": "Aktualisieren",
+ "createClientSuccessMessage": "Kunde erfolgreich angelegt!",
+ "createClientErrorMessage": "Anlegen des Kunden fehlgeschlagen!",
+ "updateClientSuccessMessage": "Kunde erfolgreich aktualisiert!",
+ "updateClientErrorMessage": "Aktualisierung des Kunden fehlgeschlagen!"
+}
diff --git a/worklenz-backend/src/public/locales/de/settings/job-titles.json b/worklenz-backend/src/public/locales/de/settings/job-titles.json
new file mode 100644
index 00000000..f4403ad1
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/settings/job-titles.json
@@ -0,0 +1,20 @@
+{
+ "nameColumn": "Name",
+ "deleteConfirmationTitle": "Sind Sie sicher?",
+ "deleteConfirmationOk": "Ja",
+ "deleteConfirmationCancel": "Abbrechen",
+ "searchPlaceholder": "Nach Namen suchen",
+ "createJobTitleButton": "Jobtitel erstellen",
+ "pinTooltip": "Zum Anheften an das Hauptmenรผ klicken",
+ "createJobTitleDrawerTitle": "Jobtitel erstellen",
+ "updateJobTitleDrawerTitle": "Jobtitel aktualisieren",
+ "nameLabel": "Name",
+ "namePlaceholder": "Name",
+ "nameRequiredError": "Bitte geben Sie einen Namen ein",
+ "createButton": "Erstellen",
+ "updateButton": "Aktualisieren",
+ "createJobTitleSuccessMessage": "Jobtitel erfolgreich erstellt!",
+ "createJobTitleErrorMessage": "Erstellung des Jobtitels fehlgeschlagen!",
+ "updateJobTitleSuccessMessage": "Jobtitel erfolgreich aktualisiert!",
+ "updateJobTitleErrorMessage": "Aktualisierung des Jobtitels fehlgeschlagen!"
+}
diff --git a/worklenz-backend/src/public/locales/de/settings/labels.json b/worklenz-backend/src/public/locales/de/settings/labels.json
new file mode 100644
index 00000000..18b6a021
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/settings/labels.json
@@ -0,0 +1,11 @@
+{
+ "labelColumn": "Label",
+ "deleteConfirmationTitle": "Sind Sie sicher?",
+ "deleteConfirmationOk": "Ja",
+ "deleteConfirmationCancel": "Abbrechen",
+ "associatedTaskColumn": "Zugeordnete Aufgabenanzahl",
+ "searchPlaceholder": "Nach Name suchen",
+ "emptyText": "Labels kรถnnen beim Aktualisieren oder Erstellen von Aufgaben erstellt werden.",
+ "pinTooltip": "Zum Anheften an das Hauptmenรผ klicken",
+ "colorChangeTooltip": "Zum รndern der Farbe klicken"
+}
diff --git a/worklenz-backend/src/public/locales/de/settings/language.json b/worklenz-backend/src/public/locales/de/settings/language.json
new file mode 100644
index 00000000..9e6bc27d
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/settings/language.json
@@ -0,0 +1,7 @@
+{
+ "language": "Sprache",
+ "language_required": "Sprache ist erforderlich",
+ "time_zone": "Zeitzone",
+ "time_zone_required": "Zeitzone ist erforderlich",
+ "save_changes": "รnderungen speichern"
+}
diff --git a/worklenz-backend/src/public/locales/de/settings/notifications.json b/worklenz-backend/src/public/locales/de/settings/notifications.json
new file mode 100644
index 00000000..272542a0
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/settings/notifications.json
@@ -0,0 +1,11 @@
+{
+ "title": "Benachrichtigungseinstellungen",
+ "emailTitle": "E-Mail-Benachrichtigungen erhalten",
+ "emailDescription": "Dies beinhaltet neue Aufgaben-Zuweisungen",
+ "dailyDigestTitle": "Tรคgliche รbersicht erhalten",
+ "dailyDigestDescription": "Jeden Abend erhalten Sie eine Zusammenfassung der letzten Aktivitรคten in Aufgaben.",
+ "popupTitle": "Popup-Benachrichtigungen auf meinem Computer anzeigen, wenn Worklenz geรถffnet ist",
+ "popupDescription": "Popup-Benachrichtigungen kรถnnen von Ihrem Browser blockiert werden. รndern Sie Ihre Browser-Einstellungen, um diese zu erlauben.",
+ "unreadItemsTitle": "Anzahl ungelesener Elemente anzeigen",
+ "unreadItemsDescription": "Sie sehen Zรคhler fรผr jede Benachrichtigung."
+}
diff --git a/worklenz-backend/src/public/locales/de/settings/profile.json b/worklenz-backend/src/public/locales/de/settings/profile.json
new file mode 100644
index 00000000..4d7fc4cd
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/settings/profile.json
@@ -0,0 +1,14 @@
+{
+ "uploadError": "Sie kรถnnen nur JPG/PNG-Dateien hochladen!",
+ "uploadSizeError": "Bilder mรผssen kleiner als 2MB sein!",
+ "upload": "Hochladen",
+ "nameLabel": "Name",
+ "nameRequiredError": "Name ist erforderlich",
+ "emailLabel": "E-Mail",
+ "emailRequiredError": "E-Mail ist erforderlich",
+ "saveChanges": "รnderungen speichern",
+ "profileJoinedText": "Vor einem Monat beigetreten",
+ "profileLastUpdatedText": "Vor einem Monat aktualisiert",
+ "avatarTooltip": "Klicken Sie zum Hochladen eines Avatars",
+ "title": "Profil-Einstellungen"
+}
diff --git a/worklenz-backend/src/public/locales/de/settings/project-templates.json b/worklenz-backend/src/public/locales/de/settings/project-templates.json
new file mode 100644
index 00000000..6c6e23ca
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/settings/project-templates.json
@@ -0,0 +1,8 @@
+{
+ "nameColumn": "Name",
+ "editToolTip": "Bearbeiten",
+ "deleteToolTip": "Lรถschen",
+ "confirmText": "Sind Sie sicher?",
+ "okText": "Ja",
+ "cancelText": "Abbrechen"
+}
diff --git a/worklenz-backend/src/public/locales/de/settings/sidebar.json b/worklenz-backend/src/public/locales/de/settings/sidebar.json
new file mode 100644
index 00000000..d4d8754d
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/settings/sidebar.json
@@ -0,0 +1,14 @@
+{
+ "profile": "Profil",
+ "notifications": "Benachrichtigungen",
+ "clients": "Kunden",
+ "job-titles": "Jobbezeichnungen",
+ "labels": "Labels",
+ "categories": "Kategorien",
+ "project-templates": "Projektvorlagen",
+ "task-templates": "Aufgabenvorlagen",
+ "team-members": "Teammitglieder",
+ "teams": "Teams",
+ "change-password": "Passwort รคndern",
+ "language-and-region": "Sprache und Region"
+}
diff --git a/worklenz-backend/src/public/locales/de/settings/task-templates.json b/worklenz-backend/src/public/locales/de/settings/task-templates.json
new file mode 100644
index 00000000..ffe93318
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/settings/task-templates.json
@@ -0,0 +1,9 @@
+{
+ "nameColumn": "Name",
+ "createdColumn": "Erstellt",
+ "editToolTip": "Bearbeiten",
+ "deleteToolTip": "Lรถschen",
+ "confirmText": "Sind Sie sicher?",
+ "okText": "Ja",
+ "cancelText": "Abbrechen"
+}
diff --git a/worklenz-backend/src/public/locales/de/settings/team-members.json b/worklenz-backend/src/public/locales/de/settings/team-members.json
new file mode 100644
index 00000000..d223f08e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/settings/team-members.json
@@ -0,0 +1,47 @@
+{
+ "title": "Teammitglieder",
+ "nameColumn": "Name",
+ "projectsColumn": "Projekte",
+ "emailColumn": "E-Mail",
+ "teamAccessColumn": "Team-Zugriff",
+ "memberCount": "Mitglied",
+ "membersCountPlural": "Mitglieder",
+ "searchPlaceholder": "Mitglieder nach Namen suchen",
+ "pinTooltip": "Mitgliederliste aktualisieren",
+ "addMemberButton": "Neues Mitglied hinzufรผgen",
+ "editTooltip": "Mitglied bearbeiten",
+ "deactivateTooltip": "Mitglied deaktivieren",
+ "activateTooltip": "Mitglied aktivieren",
+ "deleteTooltip": "Mitglied lรถschen",
+ "confirmDeleteTitle": "Sind Sie sicher, dass Sie dieses Mitglied lรถschen mรถchten?",
+ "confirmActivateTitle": "Sind Sie sicher, dass Sie den Status dieses Mitglieds รคndern mรถchten?",
+ "okText": "Ja, fortfahren",
+ "cancelText": "Nein, abbrechen",
+ "deactivatedText": "(Aktuell deaktiviert)",
+ "pendingInvitationText": "(Einladung ausstehend)",
+ "addMemberDrawerTitle": "Neues Teammitglied hinzufรผgen",
+ "updateMemberDrawerTitle": "Teammitglied aktualisieren",
+ "addMemberEmailHint": "Mitglieder werden dem Team hinzugefรผgt, unabhรคngig vom Status der Einladungsannahme",
+ "memberEmailLabel": "E-Mail(s)",
+ "memberEmailPlaceholder": "E-Mail-Adresse des Teammitglieds eingeben",
+ "memberEmailRequiredError": "Bitte geben Sie eine gรผltige E-Mail-Adresse ein",
+ "jobTitleLabel": "Jobtitel",
+ "jobTitlePlaceholder": "Jobtitel auswรคhlen oder suchen (optional)",
+ "memberAccessLabel": "Zugriffslevel",
+ "addToTeamButton": "Mitglied zum Team hinzufรผgen",
+ "updateButton": "รnderungen speichern",
+ "resendInvitationButton": "Einladungs-E-Mail erneut senden",
+ "invitationSentSuccessMessage": "Team-Einladung erfolgreich versendet!",
+ "createMemberSuccessMessage": "Neues Teammitglied erfolgreich hinzugefรผgt!",
+ "createMemberErrorMessage": "Hinzufรผgen des Teammitglieds fehlgeschlagen. Bitte versuchen Sie es erneut.",
+ "updateMemberSuccessMessage": "Teammitglied erfolgreich aktualisiert!",
+ "updateMemberErrorMessage": "Aktualisierung des Teammitglieds fehlgeschlagen. Bitte versuchen Sie es erneut.",
+ "memberText": "Mitglied",
+ "adminText": "Administrator",
+ "ownerText": "Team-Besitzer",
+ "addedText": "Hinzugefรผgt",
+ "updatedText": "Aktualisiert",
+ "noResultFound": "Geben Sie eine E-Mail-Adresse ein und drรผcken Sie Enter...",
+ "jobTitlesFetchError": "Fehler beim Abrufen der Jobtitel",
+ "invitationResent": "Einladung erfolgreich erneut gesendet!"
+}
diff --git a/worklenz-backend/src/public/locales/de/settings/teams.json b/worklenz-backend/src/public/locales/de/settings/teams.json
new file mode 100644
index 00000000..bf39215d
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/settings/teams.json
@@ -0,0 +1,16 @@
+{
+ "title": "Teams",
+ "team": "Team",
+ "teams": "Teams",
+ "name": "Name",
+ "created": "Erstellt",
+ "ownsBy": "Gehรถrt zu",
+ "edit": "Bearbeiten",
+ "editTeam": "Team bearbeiten",
+ "pinTooltip": "Klicken Sie hier, um dies im Hauptmenรผ zu fixieren",
+ "editTeamName": "Team-Name bearbeiten",
+ "updateName": "Name aktualisieren",
+ "namePlaceholder": "Name",
+ "nameRequired": "Bitte geben Sie einen Namen ein",
+ "updateFailed": "รnderung des Team-Namens fehlgeschlagen!"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/de/task-drawer/task-drawer-info-tab.json b/worklenz-backend/src/public/locales/de/task-drawer/task-drawer-info-tab.json
new file mode 100644
index 00000000..aece79f0
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/task-drawer/task-drawer-info-tab.json
@@ -0,0 +1,29 @@
+{
+ "details": {
+ "task-key": "Aufgabenschlรผssel",
+ "phase": "Phase",
+ "assignees": "Zugewiesene",
+ "due-date": "Fรคlligkeitsdatum",
+ "time-estimation": "Zeitschรคtzung",
+ "priority": "Prioritรคt",
+ "labels": "Labels",
+ "billable": "Abrechenbar",
+ "notify": "Benachrichtigen",
+ "when-done-notify": "Bei Fertigstellung benachrichtigen",
+ "start-date": "Startdatum",
+ "end-date": "Enddatum",
+ "hide-start-date": "Startdatum ausblenden",
+ "show-start-date": "Startdatum anzeigen",
+ "hours": "Stunden",
+ "minutes": "Minuten"
+ },
+ "description": {
+ "title": "Beschreibung",
+ "placeholder": "Fรผgen Sie eine detailliertere Beschreibung hinzu..."
+ },
+ "subTasks": {
+ "title": "Unteraufgaben",
+ "add-sub-task": "+ Unteraufgabe hinzufรผgen",
+ "refresh-sub-tasks": "Unteraufgaben aktualisieren"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/de/task-drawer/task-drawer.json b/worklenz-backend/src/public/locales/de/task-drawer/task-drawer.json
new file mode 100644
index 00000000..62e3f881
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/task-drawer/task-drawer.json
@@ -0,0 +1,123 @@
+{
+ "taskHeader": {
+ "taskNamePlaceholder": "Geben Sie Ihre Aufgabe ein",
+ "deleteTask": "Aufgabe lรถschen"
+ },
+ "taskInfoTab": {
+ "title": "Info",
+ "details": {
+ "title": "Details",
+ "task-key": "Aufgaben-Schlรผssel",
+ "phase": "Phase",
+ "assignees": "Beauftragte",
+ "due-date": "Fรคlligkeitsdatum",
+ "time-estimation": "Zeitschรคtzung",
+ "priority": "Prioritรคt",
+ "labels": "Labels",
+ "billable": "Abrechenbar",
+ "notify": "Benachrichtigen",
+ "when-done-notify": "Bei Abschluss benachrichtigen",
+ "start-date": "Startdatum",
+ "end-date": "Enddatum",
+ "hide-start-date": "Startdatum ausblenden",
+ "show-start-date": "Startdatum anzeigen",
+ "hours": "Stunden",
+ "minutes": "Minuten",
+ "progressValue": "Fortschrittswert",
+ "progressValueTooltip": "Fortschritt in Prozent einstellen (0-100%)",
+ "progressValueRequired": "Bitte geben Sie einen Fortschrittswert ein",
+ "progressValueRange": "Fortschritt muss zwischen 0 und 100 liegen",
+ "taskWeight": "Aufgabengewicht",
+ "taskWeightTooltip": "Gewicht dieser Teilaufgabe festlegen (Prozent)",
+ "taskWeightRequired": "Bitte geben Sie ein Aufgabengewicht ein",
+ "taskWeightRange": "Gewicht muss zwischen 0 und 100 liegen",
+ "recurring": "Wiederkehrend"
+ },
+ "labels": {
+ "labelInputPlaceholder": "Suchen oder erstellen",
+ "labelsSelectorInputTip": "Enter drรผcken zum Erstellen"
+ },
+ "description": {
+ "title": "Beschreibung",
+ "placeholder": "Detailliertere Beschreibung hinzufรผgen..."
+ },
+ "subTasks": {
+ "title": "Teilaufgaben",
+ "addSubTask": "Teilaufgabe hinzufรผgen",
+ "addSubTaskInputPlaceholder": "Geben Sie Ihre Aufgabe ein und drรผcken Sie Enter",
+ "refreshSubTasks": "Teilaufgaben aktualisieren",
+ "edit": "Bearbeiten",
+ "delete": "Lรถschen",
+ "confirmDeleteSubTask": "Sind Sie sicher, dass Sie diese Teilaufgabe lรถschen mรถchten?",
+ "deleteSubTask": "Teilaufgabe lรถschen"
+ },
+ "dependencies": {
+ "title": "Abhรคngigkeiten",
+ "addDependency": "+ Neue Abhรคngigkeit hinzufรผgen",
+ "blockedBy": "Blockiert von",
+ "searchTask": "Aufgabe suchen",
+ "noTasksFound": "Keine Aufgaben gefunden",
+ "confirmDeleteDependency": "Sind Sie sicher, dass Sie lรถschen mรถchten?"
+ },
+ "attachments": {
+ "title": "Anhรคnge",
+ "chooseOrDropFileToUpload": "Datei zum Hochladen wรคhlen oder ablegen",
+ "uploading": "Wird hochgeladen..."
+ },
+ "comments": {
+ "title": "Kommentare",
+ "addComment": "+ Neuen Kommentar hinzufรผgen",
+ "noComments": "Noch keine Kommentare. Seien Sie der Erste!",
+ "delete": "Lรถschen",
+ "confirmDeleteComment": "Sind Sie sicher, dass Sie diesen Kommentar lรถschen mรถchten?",
+ "addCommentPlaceholder": "Kommentar hinzufรผgen...",
+ "cancel": "Abbrechen",
+ "commentButton": "Kommentieren",
+ "attachFiles": "Dateien anhรคngen",
+ "addMoreFiles": "Weitere Dateien hinzufรผgen",
+ "selectedFiles": "Ausgewรคhlte Dateien (Bis zu 25MB, Maximum {count})",
+ "maxFilesError": "Sie kรถnnen maximal {count} Dateien hochladen",
+ "processFilesError": "Fehler beim Verarbeiten der Dateien",
+ "addCommentError": "Bitte fรผgen Sie einen Kommentar hinzu oder hรคngen Sie Dateien an",
+ "createdBy": "Erstellt {{time}} von {{user}}",
+ "updatedTime": "Aktualisiert {{time}}"
+ },
+ "searchInputPlaceholder": "Nach Name suchen",
+ "pendingInvitation": "Ausstehende Einladung"
+ },
+ "taskTimeLogTab": {
+ "title": "Zeiterfassung",
+ "addTimeLog": "Neuen Zeiteintrag hinzufรผgen",
+ "totalLogged": "Gesamt erfasst",
+ "exportToExcel": "Nach Excel exportieren",
+ "noTimeLogsFound": "Keine Zeiteintrรคge gefunden",
+ "timeLogForm": {
+ "date": "Datum",
+ "startTime": "Startzeit",
+ "endTime": "Endzeit",
+ "workDescription": "Arbeitsbeschreibung",
+ "descriptionPlaceholder": "Beschreibung hinzufรผgen",
+ "logTime": "Zeit erfassen",
+ "updateTime": "Zeit aktualisieren",
+ "cancel": "Abbrechen",
+ "selectDateError": "Bitte wรคhlen Sie ein Datum",
+ "selectStartTimeError": "Bitte wรคhlen Sie eine Startzeit",
+ "selectEndTimeError": "Bitte wรคhlen Sie eine Endzeit",
+ "endTimeAfterStartError": "Endzeit muss nach der Startzeit liegen"
+ }
+ },
+ "taskActivityLogTab": {
+ "title": "Aktivitรคtsprotokoll",
+ "add": "HINZUFรGEN",
+ "remove": "ENTFERNEN",
+ "none": "Keine",
+ "weight": "Gewicht",
+ "createdTask": "hat die Aufgabe erstellt."
+ },
+ "taskProgress": {
+ "markAsDoneTitle": "Aufgabe als erledigt markieren?",
+ "confirmMarkAsDone": "Ja, als erledigt markieren",
+ "cancelMarkAsDone": "Nein, aktuellen Status beibehalten",
+ "markAsDoneDescription": "Sie haben den Fortschritt auf 100% gesetzt. Mรถchten Sie den Aufgabenstatus auf \"Erledigt\" aktualisieren?"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/de/task-list-filters.json b/worklenz-backend/src/public/locales/de/task-list-filters.json
new file mode 100644
index 00000000..0854c34f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/task-list-filters.json
@@ -0,0 +1,85 @@
+{
+ "searchButton": "Suchen",
+ "resetButton": "Zurรผcksetzen",
+ "searchInputPlaceholder": "Nach Namen suchen",
+
+ "sortText": "Sortieren",
+ "statusText": "Status",
+ "phaseText": "Phase",
+ "memberText": "Mitglieder",
+ "assigneesText": "Zugewiesene",
+ "priorityText": "Prioritรคt",
+ "labelsText": "Labels",
+ "membersText": "Mitglieder",
+ "groupByText": "Gruppieren nach",
+ "showArchivedText": "Archivierte anzeigen",
+ "showFieldsText": "Felder anzeigen",
+ "keyText": "Schlรผssel",
+ "taskText": "Aufgabe",
+ "descriptionText": "Beschreibung",
+ "phasesText": "Phasen",
+ "listText": "Liste",
+ "progressText": "Fortschritt",
+ "timeTrackingText": "Zeiterfassung",
+ "timetrackingText": "Zeiterfassung",
+ "estimationText": "Schรคtzung",
+ "startDateText": "Startdatum",
+ "startdateText": "Startdatum",
+ "endDateText": "Enddatum",
+ "dueDateText": "Fรคlligkeitsdatum",
+ "duedateText": "Fรคlligkeitsdatum",
+ "completedDateText": "Abschlussdatum",
+ "completeddateText": "Abschlussdatum",
+ "createdDateText": "Erstellungsdatum",
+ "createddateText": "Erstellungsdatum",
+ "lastUpdatedText": "Zuletzt aktualisiert",
+ "lastupdatedText": "Zuletzt aktualisiert",
+ "reporterText": "Melder",
+ "dueTimeText": "Fรคllige Zeit",
+ "duetimeText": "Fรคllige Zeit",
+
+ "lowText": "Niedrig",
+ "mediumText": "Mittel",
+ "highText": "Hoch",
+
+ "createStatusButtonTooltip": "Status-Einstellungen",
+ "configPhaseButtonTooltip": "Phasen-Einstellungen",
+ "noLabelsFound": "Keine Labels gefunden",
+
+ "addStatusButton": "Status hinzufรผgen",
+ "addPhaseButton": "Phase hinzufรผgen",
+
+ "createStatus": "Status erstellen",
+ "name": "Name",
+ "category": "Kategorie",
+ "selectCategory": "Kategorie auswรคhlen",
+ "pleaseEnterAName": "Bitte geben Sie einen Namen ein",
+ "pleaseSelectACategory": "Bitte wรคhlen Sie eine Kategorie aus",
+ "create": "Erstellen",
+
+ "searchTasks": "Aufgaben suchen...",
+ "searchPlaceholder": "Suchen...",
+ "fieldsText": "Felder",
+ "loadingFilters": "Filter werden geladen...",
+ "noOptionsFound": "Keine Optionen gefunden",
+ "filtersActive": "Filter aktiv",
+ "filterActive": "Filter aktiv",
+ "clearAll": "Alle lรถschen",
+ "clearing": "Wird gelรถscht...",
+ "cancel": "Stornieren",
+ "search": "Suchen",
+ "groupedBy": "Gruppiert nach",
+ "manageStatuses": "Status verwalten",
+ "managePhases": "Phasen verwalten",
+ "dragToReorderStatuses": "Ziehen Sie Status, um sie neu zu ordnen. Jeder Status kann eine andere Kategorie haben.",
+ "enterNewStatusName": "Neuen Statusnamen eingeben...",
+ "addStatus": "Status hinzufรผgen",
+ "noStatusesFound": "Keine Status gefunden. Erstellen Sie Ihren ersten Status oben.",
+ "deleteStatus": "Status lรถschen",
+ "deleteStatusConfirm": "Sind Sie sicher, dass Sie diesen Status lรถschen mรถchten? Diese Aktion kann nicht rรผckgรคngig gemacht werden.",
+ "rename": "Umbenennen",
+ "delete": "Lรถschen",
+ "enterStatusName": "Statusnamen eingeben",
+ "selectCategory": "Kategorie auswรคhlen",
+ "close": "Schlieรen"
+}
diff --git a/worklenz-backend/src/public/locales/de/task-list-table.json b/worklenz-backend/src/public/locales/de/task-list-table.json
new file mode 100644
index 00000000..9c2ff314
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/task-list-table.json
@@ -0,0 +1,136 @@
+{
+ "keyColumn": "Schlรผssel",
+ "taskColumn": "Aufgabe",
+ "descriptionColumn": "Beschreibung",
+ "progressColumn": "Fortschritt",
+ "membersColumn": "Mitglieder",
+ "assigneesColumn": "Zugewiesene",
+ "labelsColumn": "Labels",
+ "phasesColumn": "Phasen",
+ "phaseColumn": "Phase",
+ "statusColumn": "Status",
+ "priorityColumn": "Prioritรคt",
+ "timeTrackingColumn": "Zeiterfassung",
+ "timetrackingColumn": "Zeiterfassung",
+ "estimationColumn": "Schรคtzung",
+ "startDateColumn": "Startdatum",
+ "startdateColumn": "Startdatum",
+ "dueDateColumn": "Fรคlligkeitsdatum",
+ "duedateColumn": "Fรคlligkeitsdatum",
+ "completedDateColumn": "Abschlussdatum",
+ "completeddateColumn": "Abschlussdatum",
+ "createdDateColumn": "Erstellungsdatum",
+ "createddateColumn": "Erstellungsdatum",
+ "lastUpdatedColumn": "Zuletzt aktualisiert",
+ "lastupdatedColumn": "Zuletzt aktualisiert",
+ "reporterColumn": "Melder",
+ "dueTimeColumn": "Fรคllige Zeit",
+ "todoSelectorText": "Zu erledigen",
+ "doingSelectorText": "Tun",
+ "doneSelectorText": "Erledigt",
+
+ "lowSelectorText": "Niedrig",
+ "mediumSelectorText": "Mittel",
+ "highSelectorText": "Hoch",
+
+ "selectText": "Auswรคhlen",
+ "labelsSelectorInputTip": "Enter drรผcken zum Erstellen!",
+
+ "addTaskText": "Aufgabe hinzufรผgen",
+ "addSubTaskText": "+ Unteraufgabe hinzufรผgen",
+ "addTaskInputPlaceholder": "Aufgabe eingeben und Enter drรผcken",
+ "noTasksInGroup": "Keine Aufgaben in dieser Gruppe",
+
+ "openButton": "รffnen",
+ "okButton": "OK",
+
+ "noLabelsFound": "Keine Labels gefunden",
+ "searchInputPlaceholder": "Suchen oder erstellen",
+ "assigneeSelectorInviteButton": "Neues Mitglied per E-Mail einladen",
+ "labelInputPlaceholder": "Suchen oder erstellen",
+ "searchLabelsPlaceholder": "Labels suchen...",
+ "createLabelButton": "\"{{name}}\" erstellen",
+ "manageLabelsPath": "Einstellungen โ Labels",
+
+ "pendingInvitation": "Einladung ausstehend",
+
+ "contextMenu": {
+ "assignToMe": "Mir zuweisen",
+ "moveTo": "Verschieben nach",
+ "unarchive": "Dearchivieren",
+ "archive": "Archivieren",
+ "convertToSubTask": "In Unteraufgabe umwandeln",
+ "convertToTask": "In Aufgabe umwandeln",
+ "delete": "Lรถschen",
+ "searchByNameInputPlaceholder": "Nach Namen suchen"
+ },
+ "setDueDate": "Fรคlligkeitsdatum festlegen",
+ "setStartDate": "Startdatum festlegen",
+ "clearDueDate": "Fรคlligkeitsdatum lรถschen",
+ "clearStartDate": "Startdatum lรถschen",
+ "dueDatePlaceholder": "Fรคlligkeitsdatum",
+ "startDatePlaceholder": "Startdatum",
+
+ "emptyStates": {
+ "noTaskGroups": "Keine Aufgabengruppen gefunden",
+ "noTaskGroupsDescription": "Aufgaben werden hier angezeigt, wenn sie erstellt oder Filter angewendet werden.",
+ "errorPrefix": "Fehler:",
+ "dragTaskFallback": "Aufgabe"
+ },
+
+ "customColumns": {
+ "addCustomColumn": "Benutzerdefinierte Spalte hinzufรผgen",
+ "customColumnHeader": "Benutzerdefinierte Spalte",
+ "customColumnSettings": "Einstellungen fรผr benutzerdefinierte Spalte",
+ "noCustomValue": "Kein Wert",
+ "peopleField": "Personenfeld",
+ "noDate": "Kein Datum",
+ "unsupportedField": "Nicht unterstรผtzter Feldtyp",
+
+ "modal": {
+ "addFieldTitle": "Feld hinzufรผgen",
+ "editFieldTitle": "Feld bearbeiten",
+ "fieldTitle": "Feldtitel",
+ "fieldTitleRequired": "Feldtitel ist erforderlich",
+ "columnTitlePlaceholder": "Spaltentitel",
+ "type": "Typ",
+ "deleteConfirmTitle": "Sind Sie sicher, dass Sie diese benutzerdefinierte Spalte lรถschen mรถchten?",
+ "deleteConfirmDescription": "Diese Aktion kann nicht rรผckgรคngig gemacht werden. Alle mit dieser Spalte verbundenen Daten werden dauerhaft gelรถscht.",
+ "deleteButton": "Lรถschen",
+ "cancelButton": "Abbrechen",
+ "createButton": "Erstellen",
+ "updateButton": "Aktualisieren",
+ "createSuccessMessage": "Benutzerdefinierte Spalte erfolgreich erstellt",
+ "updateSuccessMessage": "Benutzerdefinierte Spalte erfolgreich aktualisiert",
+ "deleteSuccessMessage": "Benutzerdefinierte Spalte erfolgreich gelรถscht",
+ "deleteErrorMessage": "Fehler beim Lรถschen der benutzerdefinierten Spalte",
+ "createErrorMessage": "Fehler beim Erstellen der benutzerdefinierten Spalte",
+ "updateErrorMessage": "Fehler beim Aktualisieren der benutzerdefinierten Spalte"
+ },
+
+ "fieldTypes": {
+ "people": "Personen",
+ "number": "Zahl",
+ "date": "Datum",
+ "selection": "Auswahl",
+ "checkbox": "Kontrollkรคstchen",
+ "labels": "Etiketten",
+ "key": "Schlรผssel",
+ "formula": "Formel"
+ }
+ },
+
+ "indicators": {
+ "tooltips": {
+ "subtasks": "{{count}} Unteraufgabe",
+ "subtasks_plural": "{{count}} Unteraufgaben",
+ "comments": "{{count}} Kommentar",
+ "comments_plural": "{{count}} Kommentare",
+ "attachments": "{{count}} Anhang",
+ "attachments_plural": "{{count}} Anhรคnge",
+ "subscribers": "Aufgabe hat Abonnenten",
+ "dependencies": "Aufgabe hat Abhรคngigkeiten",
+ "recurring": "Wiederkehrende Aufgabe"
+ }
+ }
+}
diff --git a/worklenz-backend/src/public/locales/de/task-management.json b/worklenz-backend/src/public/locales/de/task-management.json
new file mode 100644
index 00000000..b20d94a4
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/task-management.json
@@ -0,0 +1,21 @@
+{
+ "noTasksInGroup": "Keine Aufgaben in dieser Gruppe",
+ "noTasksInGroupDescription": "Fรผgen Sie eine Aufgabe hinzu, um zu beginnen",
+ "addFirstTask": "Fรผgen Sie Ihre erste Aufgabe hinzu",
+ "openTask": "รffnen",
+ "subtask": "Unteraufgabe",
+ "subtasks": "Unteraufgaben",
+ "comment": "Kommentar",
+ "comments": "Kommentare",
+ "attachment": "Anhang",
+ "attachments": "Anhรคnge",
+ "enterSubtaskName": "Unteraufgabenname eingeben...",
+ "add": "Hinzufรผgen",
+ "cancel": "Abbrechen",
+ "renameGroup": "Gruppe umbenennen",
+ "renameStatus": "Status umbenennen",
+ "renamePhase": "Phase umbenennen",
+ "changeCategory": "Kategorie รคndern",
+ "clickToEditGroupName": "Klicken Sie, um den Gruppennamen zu bearbeiten",
+ "enterGroupName": "Gruppennamen eingeben"
+}
diff --git a/worklenz-backend/src/public/locales/de/task-template-drawer.json b/worklenz-backend/src/public/locales/de/task-template-drawer.json
new file mode 100644
index 00000000..21dbe369
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/task-template-drawer.json
@@ -0,0 +1,11 @@
+{
+ "createTaskTemplate": "Aufgabenvorlage erstellen",
+ "editTaskTemplate": "Aufgabenvorlage bearbeiten",
+ "cancelText": "Abbrechen",
+ "saveText": "Speichern",
+ "templateNameText": "Vorlagenname",
+ "selectedTasks": "Ausgewรคhlte Aufgaben",
+ "removeTask": "Entfernen",
+ "cancelButton": "Abbrechen",
+ "saveButton": "Speichern"
+}
diff --git a/worklenz-backend/src/public/locales/de/tasks/task-table-bulk-actions.json b/worklenz-backend/src/public/locales/de/tasks/task-table-bulk-actions.json
new file mode 100644
index 00000000..e8b039f2
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/tasks/task-table-bulk-actions.json
@@ -0,0 +1,41 @@
+{
+ "taskSelected": "Aufgabe ausgewรคhlt",
+ "tasksSelected": "Aufgaben ausgewรคhlt",
+ "changeStatus": "Status/Prioritรคt/Phase รคndern",
+ "changeLabel": "Label รคndern",
+ "assignToMe": "Mir zuweisen",
+ "changeAssignees": "Zustรคndige รคndern",
+ "archive": "Archivieren",
+ "unarchive": "Dearchivieren",
+ "delete": "Lรถschen",
+ "moreOptions": "Weitere Optionen",
+ "deselectAll": "Alle abwรคhlen",
+ "status": "Status",
+ "priority": "Prioritรคt",
+ "phase": "Phase",
+ "member": "Mitglied",
+ "createTaskTemplate": "Aufgabenvorlage erstellen",
+ "apply": "Anwenden",
+ "createLabel": "+ Label erstellen",
+ "searchOrCreateLabel": "Label suchen oder erstellen...",
+ "hitEnterToCreate": "Enter drรผcken zum Erstellen",
+ "labelExists": "Label existiert bereits",
+ "pendingInvitation": "Einladung ausstehend",
+ "noMatchingLabels": "Keine passenden Labels",
+ "noLabels": "Keine Labels",
+ "CHANGE_STATUS": "Status รคndern",
+ "CHANGE_PRIORITY": "Prioritรคt รคndern",
+ "CHANGE_PHASE": "Phase รคndern",
+ "ADD_LABELS": "Labels hinzufรผgen",
+ "ASSIGN_TO_ME": "Mir zuweisen",
+ "ASSIGN_MEMBERS": "Mitglieder zuweisen",
+ "ARCHIVE": "Archivieren",
+ "DELETE": "Lรถschen",
+ "CANCEL": "Abbrechen",
+ "CLEAR_SELECTION": "Auswahl lรถschen",
+ "TASKS_SELECTED": "{{count}} Aufgabe ausgewรคhlt",
+ "TASKS_SELECTED_plural": "{{count}} Aufgaben ausgewรคhlt",
+ "DELETE_TASKS_CONFIRM": "{{count}} Aufgabe lรถschen?",
+ "DELETE_TASKS_CONFIRM_plural": "{{count}} Aufgaben lรถschen?",
+ "DELETE_TASKS_WARNING": "Diese Aktion kann nicht rรผckgรคngig gemacht werden."
+}
diff --git a/worklenz-backend/src/public/locales/de/template-drawer.json b/worklenz-backend/src/public/locales/de/template-drawer.json
new file mode 100644
index 00000000..8655504d
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/template-drawer.json
@@ -0,0 +1,19 @@
+{
+ "title": "Aufgabenvorlage bearbeiten",
+ "cancelText": "Abbrechen",
+ "saveText": "Speichern",
+ "templateNameText": "Vorlagenname",
+ "selectedTasks": "Ausgewรคhlte Aufgaben",
+ "removeTask": "Entfernen",
+ "description": "Beschreibung",
+ "phase": "Phase",
+ "statuses": "Status",
+ "priorities": "Prioritรคten",
+ "labels": "Labels",
+ "tasks": "Aufgaben",
+ "noTemplateSelected": "Keine Vorlage ausgewรคhlt",
+ "noDescription": "Keine Beschreibung",
+ "worklenzTemplates": "Worklenz-Vorlagen",
+ "yourTemplatesLibrary": "Ihre Bibliothek",
+ "searchTemplates": "Vorlagen durchsuchen"
+}
diff --git a/worklenz-backend/src/public/locales/de/templateDrawer.json b/worklenz-backend/src/public/locales/de/templateDrawer.json
new file mode 100644
index 00000000..571ed15f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/templateDrawer.json
@@ -0,0 +1,23 @@
+{
+ "bugTracking": "Fehlerverfolgung",
+ "construction": "Bauwesen",
+ "designCreative": "Design & Kreatives",
+ "education": "Bildung",
+ "finance": "Finanzen",
+ "hrRecruiting": "Personalwesen & Recruiting",
+ "informationTechnology": "Informationstechnologie",
+ "legal": "Rechtliches",
+ "manufacturing": "Produktion",
+ "marketing": "Marketing",
+ "nonprofit": "Gemeinnรผtzig",
+ "personalUse": "Persรถnliche Nutzung",
+ "salesCRM": "Vertrieb & CRM",
+ "serviceConsulting": "Dienstleistungen & Beratung",
+ "softwareDevelopment": "Softwareentwicklung",
+ "description": "Beschreibung",
+ "phase": "Phase",
+ "statuses": "Status",
+ "priorities": "Prioritรคten",
+ "labels": "Labels",
+ "tasks": "Aufgaben"
+}
diff --git a/worklenz-backend/src/public/locales/de/time-report.json b/worklenz-backend/src/public/locales/de/time-report.json
new file mode 100644
index 00000000..efadbb8a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/time-report.json
@@ -0,0 +1,44 @@
+{
+ "includeArchivedProjects": "Archivierte Projekte einschlieรen",
+ "export": "Exportieren",
+ "timeSheet": "Stundenzettel",
+
+ "searchByName": "Nach Namen suchen",
+ "selectAll": "Alle auswรคhlen",
+ "teams": "Teams",
+
+ "searchByProject": "Nach Projektnamen suchen",
+ "projects": "Projekte",
+
+ "searchByCategory": "Nach Kategorienamen suchen",
+ "categories": "Kategorien",
+
+ "billable": "Abrechenbar",
+ "nonBillable": "Nicht abrechenbar",
+
+ "total": "Gesamt",
+
+ "projectsTimeSheet": "Projekt-Zeiterfassung",
+
+ "loggedTime": "Erfasste Zeit (Stunden)",
+
+ "exportToExcel": "Nach Excel exportieren",
+ "logged": "erfasst",
+ "for": "fรผr",
+
+ "membersTimeSheet": "Mitglieder-Zeiterfassung",
+ "member": "Mitglied",
+
+ "estimatedVsActual": "Geschรคtzt vs. Tatsรคchlich",
+ "workingDays": "Arbeitstage",
+ "manDays": "Manntage",
+ "days": "Tage",
+ "estimatedDays": "Geschรคtzt Tage",
+ "actualDays": "Tatsรคchliche Tage",
+
+ "noCategories": "Keine Kategorien gefunden",
+ "noCategory": "Keine Kategorie",
+ "noProjects": "Keine Projekte gefunden",
+ "noTeams": "Keine Teams gefunden",
+ "noData": "Keine Daten gefunden"
+}
diff --git a/worklenz-backend/src/public/locales/de/unauthorized.json b/worklenz-backend/src/public/locales/de/unauthorized.json
new file mode 100644
index 00000000..4384ad80
--- /dev/null
+++ b/worklenz-backend/src/public/locales/de/unauthorized.json
@@ -0,0 +1,5 @@
+{
+ "title": "Unbefugt!",
+ "subtitle": "Sie sind nicht berechtigt, auf diese Seite zuzugreifen",
+ "button": "Zur Startseite"
+}
diff --git a/worklenz-backend/src/public/locales/en/404-page.json b/worklenz-backend/src/public/locales/en/404-page.json
new file mode 100644
index 00000000..a93627f1
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/404-page.json
@@ -0,0 +1,4 @@
+{
+ "doesNotExistText": "Sorry, the page you visited does not exist.",
+ "backHomeButton": "Back Home"
+}
diff --git a/worklenz-backend/src/public/locales/en/account-setup.json b/worklenz-backend/src/public/locales/en/account-setup.json
new file mode 100644
index 00000000..5e71ca40
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/account-setup.json
@@ -0,0 +1,31 @@
+{
+ "continue": "Continue",
+
+ "setupYourAccount": "Setup Your Worklenz Account.",
+ "organizationStepTitle": "Name Your Organization",
+ "organizationStepLabel": "Pick a name for your Worklenz account.",
+
+ "projectStepTitle": "Create your first project",
+ "projectStepLabel": "What project are you working on right now?",
+ "projectStepPlaceholder": "e.g. Marketing Plan",
+
+ "tasksStepTitle": "Create your first tasks",
+ "tasksStepLabel": "Type a few tasks that you are going to do in",
+ "tasksStepAddAnother": "Add another",
+
+ "emailPlaceholder": "Email address",
+ "invalidEmail": "Please enter a valid email address",
+ "or": "or",
+ "templateButton": "Import from template",
+ "goBack": "Go Back",
+ "cancel": "Cancel",
+ "create": "Create",
+ "templateDrawerTitle": "Select from templates",
+ "step3InputLabel": "Invite with email",
+ "addAnother": "Add another",
+ "skipForNow": "Skip for now",
+ "formTitle": "Create your first task.",
+ "step3Title": "Invite your team to work with",
+ "maxMembers": " (You can invite up to 5 members)",
+ "maxTasks": " (You can create up to 5 tasks)"
+}
diff --git a/worklenz-backend/src/public/locales/en/admin-center/current-bill.json b/worklenz-backend/src/public/locales/en/admin-center/current-bill.json
new file mode 100644
index 00000000..fe840789
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/admin-center/current-bill.json
@@ -0,0 +1,121 @@
+{
+ "title": "Billings",
+ "currentBill": "Current Bill",
+ "configuration": "Configuration",
+ "currentPlanDetails": "Current Plan Details",
+ "upgradePlan": "Upgrade Plan",
+ "cardBodyText01": "Free trial",
+ "cardBodyText02": "(Your trial plan expires in 1 month 19 days)",
+ "redeemCode": "Redeem Code",
+ "accountStorage": "Account Storage",
+ "used": "Used:",
+ "remaining": "Remaining:",
+ "charges": "Charges",
+ "tooltip": "Charges for the current billing cycle",
+ "description": "Description",
+ "billingPeriod": "Billing Period",
+ "billStatus": "Bill Status",
+ "perUserValue": "Per User Value",
+ "users": "Users",
+
+ "amount": "Amount",
+ "invoices": "Invoices",
+ "transactionId": "Transaction ID",
+ "transactionDate": "Transaction Date",
+ "paymentMethod": "Payment Method",
+ "status": "Status",
+ "ltdUsers": "You can add up to {{ltd_users}} users.",
+
+ "totalSeats": "Total seats",
+ "availableSeats": "Available seats",
+ "addMoreSeats": "Add more seats",
+
+ "drawerTitle": "Redeem Code",
+ "label": "Redeem Code",
+ "drawerPlaceholder": "Enter your redeem code",
+ "redeemSubmit": "Submit",
+
+ "modalTitle": "Select the best plan for your team",
+ "seatLabel": "No of seats",
+ "freePlan": "Free Plan",
+ "startup": "Startup",
+ "business": "Business",
+ "tag": "Most Popular",
+ "enterprise": "Enterprise",
+
+ "freeSubtitle": "free forever",
+ "freeUsers": "Best for personal use",
+ "freeText01": "100MB storage",
+ "freeText02": "3 projects",
+ "freeText03": "5 team members",
+
+ "startupSubtitle": "FLAT RATE / month",
+ "startupUsers": "Upto 15 users",
+ "startupText01": "25GB storage",
+ "startupText02": "Unlimited active projects",
+ "startupText03": "Schedule",
+ "startupText04": "Reporting",
+ "startupText05": "Subscribe to projects",
+
+ "businessSubtitle": "user / month",
+ "businessUsers": "16 - 200 users",
+
+ "enterpriseUsers": "200 - 500+ users",
+
+ "footerTitle": "Please provide us with a contact number we can use to reach you.",
+ "footerLabel": "Contact Number",
+ "footerButton": "Contact us",
+
+ "redeemCodePlaceHolder": "Enter your redeem code",
+ "submit": "Submit",
+
+ "trialPlan": "Free Trial",
+ "trialExpireDate": "Valid until {{trial_expire_date}}",
+ "trialExpired": "Your free trial expired {{trial_expire_string}}",
+ "trialInProgress": "Your free trial expires {{trial_expire_string}}",
+
+ "required": "This field is required",
+ "invalidCode": "Invalid code",
+
+ "selectPlan": "Select the best plan for your team",
+ "changeSubscriptionPlan": "Change your subscription plan",
+ "noOfSeats": "Number of seats",
+ "annualPlan": "Pro - Annual",
+ "monthlyPlan": "Pro - Monthly",
+ "freeForever": "Free Forever",
+ "bestForPersonalUse": "Best for personal use",
+ "storage": "Storage",
+ "projects": "Projects",
+ "teamMembers": "Team Members",
+ "unlimitedTeamMembers": "Unlimited Team Members",
+ "unlimitedActiveProjects": "Unlimited active projects",
+ "schedule": "Schedule",
+ "reporting": "Reporting",
+ "subscribeToProjects": "Subscribe to projects",
+ "billedAnnually": "Billed Annually",
+ "billedMonthly": "Billed Monthly",
+
+ "pausePlan": "Pause Plan",
+ "resumePlan": "Resume Plan",
+ "changePlan": "Change Plan",
+ "cancelPlan": "Cancel Plan",
+
+ "perMonthPerUser": "per user/month",
+ "viewInvoice": "View Invoice",
+ "switchToFreePlan": "Switch to Free Plan",
+
+ "expirestoday": "today",
+ "expirestomorrow": "tomorrow",
+ "expiredDaysAgo": "{{days}} days ago",
+
+ "continueWith": "Continue with {{plan}}",
+ "changeToPlan": "Change to {{plan}}",
+ "creditPlan": "Credit Plan",
+ "customPlan": "Custom Plan",
+ "planValidTill": "Your plan is valid till {{date}}",
+ "purchaseSeatsText": "To continue, you'll need to purchase additional seats.",
+ "currentSeatsText": "You currently have {{seats}} seats available.",
+ "selectSeatsText": "Please select the number of additional seats to purchase.",
+ "purchase": "Purchase",
+ "contactSales": "Contact sales"
+}
diff --git a/worklenz-backend/src/public/locales/en/admin-center/overview.json b/worklenz-backend/src/public/locales/en/admin-center/overview.json
new file mode 100644
index 00000000..efc42855
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/admin-center/overview.json
@@ -0,0 +1,8 @@
+{
+ "overview": "Overview",
+ "name": "Organization Name",
+ "owner": "Organization Owner",
+ "admins": "Organization Admins",
+ "contactNumber": "Add Contact Number",
+ "edit": "Edit"
+}
diff --git a/worklenz-backend/src/public/locales/en/admin-center/projects.json b/worklenz-backend/src/public/locales/en/admin-center/projects.json
new file mode 100644
index 00000000..4e491d73
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/admin-center/projects.json
@@ -0,0 +1,12 @@
+{
+ "membersCount": "Members Count",
+ "createdAt": "Created at",
+ "projectName": "Project Name",
+ "teamName": "Team Name",
+ "refreshProjects": "Refresh projects",
+ "searchPlaceholder": "Search by project name",
+ "deleteProject": "Are you sure you want to delete this project?",
+ "confirm": "Confirm",
+ "cancel": "Cancel",
+ "delete": "Delete Project"
+}
diff --git a/worklenz-backend/src/public/locales/en/admin-center/sidebar.json b/worklenz-backend/src/public/locales/en/admin-center/sidebar.json
new file mode 100644
index 00000000..3b03d499
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/admin-center/sidebar.json
@@ -0,0 +1,8 @@
+{
+ "overview": "Overview",
+ "users": "Users",
+ "teams": "Teams",
+ "billing": "Billing",
+ "projects": "Projects",
+ "adminCenter": "Admin Center"
+}
diff --git a/worklenz-backend/src/public/locales/en/admin-center/teams.json b/worklenz-backend/src/public/locales/en/admin-center/teams.json
new file mode 100644
index 00000000..bf829a87
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/admin-center/teams.json
@@ -0,0 +1,35 @@
+{
+ "title": "Teams",
+ "subtitle": "teams",
+ "tooltip": "Refresh teams",
+ "placeholder": "Search by name",
+ "addTeam": "Add Team",
+ "team": "Team",
+ "membersCount": "Members Count",
+ "members": "Members",
+ "drawerTitle": "Create New Team",
+ "label": "Team Name",
+ "drawerPlaceholder": "Name",
+ "create": "Create",
+ "delete": "Delete",
+ "settings": "Settings",
+ "popTitle": "Are you sure?",
+ "message": "Please enter a Name",
+ "teamSettings": "Team Settings",
+ "teamName": "Team Name",
+ "teamDescription": "Team Description",
+ "teamMembers": "Team Members",
+ "teamMembersCount": "Team Members Count",
+ "teamMembersPlaceholder": "Search by name",
+ "addMember": "Add Member",
+ "add": "Add",
+ "update": "Update",
+ "teamNamePlaceholder": "Name of the team",
+ "user": "User",
+ "role": "Role",
+ "owner": "Owner",
+ "admin": "Admin",
+ "member": "Member",
+ "cannotChangeOwnerRole": "Owner role cannot be changed",
+ "pendingInvitation": "Pending invitation"
+}
diff --git a/worklenz-backend/src/public/locales/en/admin-center/users.json b/worklenz-backend/src/public/locales/en/admin-center/users.json
new file mode 100644
index 00000000..7e462ef6
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/admin-center/users.json
@@ -0,0 +1,9 @@
+{
+ "title": "Users",
+ "subTitle": "users",
+ "placeholder": "Search by name",
+ "user": "User",
+ "email": "Email",
+ "lastActivity": "Last Activity",
+ "refresh": "Refresh users"
+}
diff --git a/worklenz-backend/src/public/locales/en/all-project-list.json b/worklenz-backend/src/public/locales/en/all-project-list.json
new file mode 100644
index 00000000..ab98cb6b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/all-project-list.json
@@ -0,0 +1,34 @@
+{
+ "name": "Name",
+ "client": "Client",
+ "category": "Category",
+ "status": "Status",
+ "tasksProgress": "Tasks Progress",
+ "updated_at": "Last Updated",
+ "members": "Members",
+ "setting": "Settings",
+ "projects": "Projects",
+ "refreshProjects": "Refresh projects",
+ "all": "All",
+ "favorites": "Favorites",
+ "archived": "Archived",
+ "placeholder": "Search by name",
+ "archive": "Archive",
+ "unarchive": "Unarchive",
+ "archiveConfirm": "Are you sure you want to archive this project?",
+ "unarchiveConfirm": "Are you sure you want to unarchive this project?",
+ "yes": "Yes",
+ "no": "No",
+ "clickToFilter": "Click to filter by",
+ "noProjects": "No projects found",
+ "addToFavourites": "Add to favourites",
+ "list": "List",
+ "group": "Group",
+ "listView": "List View",
+ "groupView": "Group View",
+ "groupBy": {
+ "category": "Category",
+ "client": "Client"
+ },
+ "noPermission": "You don't have permission to perform this action"
+}
diff --git a/worklenz-backend/src/public/locales/en/auth/auth-common.json b/worklenz-backend/src/public/locales/en/auth/auth-common.json
new file mode 100644
index 00000000..94803a12
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/auth/auth-common.json
@@ -0,0 +1,5 @@
+{
+ "loggingOut": "Logging out...",
+ "authenticating": "Authenticating...",
+ "gettingThingsReady": "Getting things ready for you..."
+}
diff --git a/worklenz-backend/src/public/locales/en/auth/forgot-password.json b/worklenz-backend/src/public/locales/en/auth/forgot-password.json
new file mode 100644
index 00000000..3534c388
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/auth/forgot-password.json
@@ -0,0 +1,12 @@
+{
+ "headerDescription": "Reset your password",
+ "emailLabel": "Email",
+ "emailPlaceholder": "Enter your email",
+ "emailRequired": "Please enter your Email!",
+ "resetPasswordButton": "Reset Password",
+ "returnToLoginButton": "Return to Login",
+ "passwordResetSuccessMessage": "A password reset link has been sent to your email.",
+ "orText": "OR",
+ "successTitle": "Reset instruction sent!",
+ "successMessage": "Reset information has been sent to your email. Please check your email."
+}
diff --git a/worklenz-backend/src/public/locales/en/auth/login.json b/worklenz-backend/src/public/locales/en/auth/login.json
new file mode 100644
index 00000000..b77e7fba
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/auth/login.json
@@ -0,0 +1,27 @@
+{
+ "headerDescription": "Login to your account",
+ "emailLabel": "Email",
+ "emailPlaceholder": "Enter your email",
+ "emailRequired": "Please enter your Email!",
+ "passwordLabel": "Password",
+ "passwordPlaceholder": "Enter your password",
+ "passwordRequired": "Please enter your Password!",
+ "rememberMe": "Remember me",
+ "loginButton": "Log in",
+ "signupButton": "Sign up",
+ "forgotPasswordButton": "Forgot password?",
+ "signInWithGoogleButton": "Sign in with Google",
+ "dontHaveAccountText": "Donโt have an account?",
+ "orText": "OR",
+ "successMessage": "You have successfully logged in!",
+ "loginError": "Login failed",
+ "googleLoginError": "Google login failed",
+ "validationMessages": {
+ "email": "Please enter a valid email address",
+ "password": "Password must be at least 8 characters long"
+ },
+ "errorMessages": {
+ "loginErrorTitle": "Login failed",
+ "loginErrorMessage": "Please check your email and password and try again"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/en/auth/signup.json b/worklenz-backend/src/public/locales/en/auth/signup.json
new file mode 100644
index 00000000..af4611ba
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/auth/signup.json
@@ -0,0 +1,29 @@
+{
+ "headerDescription": "Sign up to get started",
+ "nameLabel": "Full Name",
+ "namePlaceholder": "Enter your full name",
+ "nameRequired": "Please enter your full name!",
+ "nameMinCharacterRequired": "Full name must be at least 4 characters!",
+ "emailLabel": "Email",
+ "emailPlaceholder": "Enter your email",
+ "emailRequired": "Please enter your Email!",
+ "passwordLabel": "Password",
+ "passwordPlaceholder": "Enter your password",
+ "passwordRequired": "Please enter your Password!",
+ "passwordMinCharacterRequired": "Password must be at least 8 characters!",
+ "passwordPatternRequired": "Password does not meet the requirements!",
+ "strongPasswordPlaceholder": "Enter a stronger password",
+ "passwordValidationAltText": "Password must include at least 8 characters with upper and lower case letters, a number, and a symbol.",
+ "signupSuccessMessage": "You have successfully signed up!",
+ "privacyPolicyLink": "Privacy Policy",
+ "termsOfUseLink": "Terms of Use",
+ "bySigningUpText": "By signing up, you agree to our",
+ "andText": "and",
+ "signupButton": "Sign up",
+ "signInWithGoogleButton": "Sign in with Google",
+ "alreadyHaveAccountText": "Already have an account?",
+ "loginButton": "Login",
+ "orText": "OR",
+ "reCAPTCHAVerificationError": "reCAPTCHA Verification Error",
+ "reCAPTCHAVerificationErrorMessage": "We were unable to verify your reCAPTCHA. Please try again."
+}
diff --git a/worklenz-backend/src/public/locales/en/auth/verify-reset-email.json b/worklenz-backend/src/public/locales/en/auth/verify-reset-email.json
new file mode 100644
index 00000000..e685e193
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/auth/verify-reset-email.json
@@ -0,0 +1,14 @@
+{
+ "title": "Verify Reset Email",
+ "description": "Enter your new password",
+ "placeholder": "Enter your new password",
+ "confirmPasswordPlaceholder": "Confirm your new password",
+ "passwordHint": "Minimum of 8 characters, with upper and lowercase and a number and a symbol.",
+ "resetPasswordButton": "Reset password",
+ "orText": "Or",
+ "resendResetEmail": "Resend reset email",
+ "passwordRequired": "Please enter your new password",
+ "returnToLoginButton": "Return to Login",
+ "confirmPasswordRequired": "Please confirm your new password",
+ "passwordMismatch": "The two passwords do not match"
+}
diff --git a/worklenz-backend/src/public/locales/en/common.json b/worklenz-backend/src/public/locales/en/common.json
new file mode 100644
index 00000000..815560be
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/common.json
@@ -0,0 +1,9 @@
+{
+ "login-success": "Login successful!",
+ "login-failed": "Login failed. Please check your credentials and try again.",
+ "signup-success": "Signup successful! Welcome aboard.",
+ "signup-failed": "Signup failed. Please ensure all required fields are filled and try again.",
+ "reconnecting": "Disconnected from server.",
+ "connection-lost": "Failed to connect to server. Please check your internet connection.",
+ "connection-restored": "Connected to server successfully"
+}
diff --git a/worklenz-backend/src/public/locales/en/create-first-project-form.json b/worklenz-backend/src/public/locales/en/create-first-project-form.json
new file mode 100644
index 00000000..337f4a10
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/create-first-project-form.json
@@ -0,0 +1,13 @@
+{
+ "formTitle": "Create your first project",
+ "inputLabel": "What project are you working on right now?",
+ "or": "or",
+ "templateButton": "Import from template",
+ "createFromTemplate": "Create from template",
+ "goBack": "Go Back",
+ "continue": "Continue",
+ "cancel": "Cancel",
+ "create": "Create",
+ "templateDrawerTitle": "Select from templates",
+ "createProject": "Create Project"
+}
diff --git a/worklenz-backend/src/public/locales/en/create-first-tasks.json b/worklenz-backend/src/public/locales/en/create-first-tasks.json
new file mode 100644
index 00000000..1447f355
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/create-first-tasks.json
@@ -0,0 +1,7 @@
+{
+ "formTitle": "Create your first task.",
+ "inputLable": "Type a few tasks that you are going to do in",
+ "addAnother": "Add another",
+ "goBack": "Go back",
+ "continue": "Continue"
+}
diff --git a/worklenz-backend/src/public/locales/en/home.json b/worklenz-backend/src/public/locales/en/home.json
new file mode 100644
index 00000000..ccf40936
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/home.json
@@ -0,0 +1,46 @@
+{
+ "todoList": {
+ "title": "To do list",
+ "refreshTasks": "Refresh tasks",
+ "addTask": "+ Add Task",
+ "noTasks": "No tasks",
+ "pressEnter": "Press",
+ "toCreate": "to create.",
+ "markAsDone": "Mark as done"
+ },
+ "projects": {
+ "title": "Projects",
+ "refreshProjects": "Refresh projects",
+ "noRecentProjects": "You are currently not assigned to any project.",
+ "noFavouriteProjects": "No projects have been marked as favorites.",
+ "recent": "Recent",
+ "favourites": "Favourites"
+ },
+ "tasks": {
+ "assignedToMe": "Assigned to me",
+ "assignedByMe": "Assigned by me",
+ "all": "All",
+ "today": "Today",
+ "upcoming": "Upcoming",
+ "overdue": "Overdue",
+ "noDueDate": "No due date",
+ "noTasks": "No tasks to show.",
+ "addTask": "+ Add task",
+ "name": "Name",
+ "project": "Project",
+ "status": "Status",
+ "dueDate": "Due Date",
+ "dueDatePlaceholder": "Set Due Date",
+ "tomorrow": "Tomorrow",
+ "nextWeek": "Next Week",
+ "nextMonth": "Next Month",
+ "projectRequired": "Please select a project",
+ "pressTabToSelectDueDateAndProject": "Press Tab to select a due date and a project",
+ "dueOn": "Tasks due on",
+ "taskRequired": "Please add a task",
+ "list": "List",
+ "calendar": "Calendar",
+ "tasks": "Tasks",
+ "refresh": "Refresh"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/en/invite-initial-team-members.json b/worklenz-backend/src/public/locales/en/invite-initial-team-members.json
new file mode 100644
index 00000000..09f23e87
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/invite-initial-team-members.json
@@ -0,0 +1,8 @@
+{
+ "formTitle": "Invite your team to work with",
+ "inputLable": "Invite with email",
+ "addAnother": "Add another",
+ "goBack": "Go back",
+ "continue": "Continue",
+ "skipForNow": "Skip for now"
+}
diff --git a/worklenz-backend/src/public/locales/en/kanban-board.json b/worklenz-backend/src/public/locales/en/kanban-board.json
new file mode 100644
index 00000000..e295a6c6
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/kanban-board.json
@@ -0,0 +1,33 @@
+{
+ "rename": "Rename",
+ "delete": "Delete",
+ "addTask": "Add Task",
+ "addSectionButton": "Add Section",
+ "changeCategory": "Change category",
+
+ "deleteTooltip": "Delete",
+ "deleteConfirmationTitle": "Are you sure?",
+ "deleteConfirmationOk": "Yes",
+ "deleteConfirmationCancel": "Cancel",
+
+ "dueDate": "Due date",
+ "cancel": "Cancel",
+
+ "today": "Today",
+ "tomorrow": "Tomorrow",
+ "assignToMe": "Assign to me",
+ "archive": "Archive",
+
+ "newTaskNamePlaceholder": "Write a task Name",
+ "newSubtaskNamePlaceholder": "Write a subtask Name",
+ "untitledSection": "Untitled section",
+ "unmapped": "Unmapped",
+ "clickToChangeDate": "Click to change date",
+ "noDueDate": "No due date",
+ "save": "Save",
+ "clear": "Clear",
+ "nextWeek": "Next week",
+ "noSubtasks": "No subtasks",
+ "showSubtasks": "Show subtasks",
+ "hideSubtasks": "Hide subtasks"
+}
diff --git a/worklenz-backend/src/public/locales/en/license-expired.json b/worklenz-backend/src/public/locales/en/license-expired.json
new file mode 100644
index 00000000..e4556064
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/license-expired.json
@@ -0,0 +1,6 @@
+{
+ "title": "Your Worklenz trial has expired!",
+ "subtitle": "Please upgrade now.",
+ "button": "Upgrade now",
+ "checking": "Checking subscription status..."
+}
diff --git a/worklenz-backend/src/public/locales/en/navbar.json b/worklenz-backend/src/public/locales/en/navbar.json
new file mode 100644
index 00000000..e7e22cb3
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/navbar.json
@@ -0,0 +1,31 @@
+{
+ "logoAlt": "Worklenz Logo",
+ "home": "Home",
+ "projects": "Projects",
+ "schedule": "Schedule",
+ "reporting": "Reporting",
+ "clients": "Clients",
+ "teams": "Teams",
+ "labels": "Labels",
+ "jobTitles": "Job Titles",
+ "upgradePlan": "Upgrade Plan",
+ "upgradePlanTooltip": "Upgrade Plan",
+ "invite": "Invite",
+ "inviteTooltip": "Invite team members to join",
+ "switchTeamTooltip": "Switch team",
+ "help": "Help",
+ "notificationTooltip": "View notifications",
+ "profileTooltip": "View profile",
+ "adminCenter": "Admin Center",
+ "settings": "Settings",
+ "logOut": "Log Out",
+ "notificationsDrawer": {
+ "read": "Read notifications",
+ "unread": "Unread notifications",
+ "markAsRead": "Mark as read",
+ "readAndJoin": "Read & Join",
+ "accept": "Accept",
+ "acceptAndJoin": "Accept & Join",
+ "noNotifications": "No notifications"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/en/organization-name-form.json b/worklenz-backend/src/public/locales/en/organization-name-form.json
new file mode 100644
index 00000000..26ffa973
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/organization-name-form.json
@@ -0,0 +1,5 @@
+{
+ "nameYourOrganization": "Name your organization.",
+ "worklenzAccountTitle": "Pick a name for your Worklenz account.",
+ "continue": "Continue"
+}
diff --git a/worklenz-backend/src/public/locales/en/phases-drawer.json b/worklenz-backend/src/public/locales/en/phases-drawer.json
new file mode 100644
index 00000000..10ad78a4
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/phases-drawer.json
@@ -0,0 +1,19 @@
+{
+ "configurePhases": "Configure Phases",
+ "phaseLabel": "Phase Label",
+ "enterPhaseName": "Enter a name for phase label",
+ "addOption": "Add Option",
+ "phaseOptions": "Phase Options:",
+ "dragToReorderPhases": "Drag phases to reorder them. Each phase can have a different color.",
+ "enterNewPhaseName": "Enter new phase name...",
+ "addPhase": "Add Phase",
+ "noPhasesFound": "No phases found. Create your first phase above.",
+ "deletePhase": "Delete Phase",
+ "deletePhaseConfirm": "Are you sure you want to delete this phase? This action cannot be undone.",
+ "rename": "Rename",
+ "delete": "Delete",
+ "enterPhaseName": "Enter phase name",
+ "selectColor": "Select color",
+ "managePhases": "Manage Phases",
+ "close": "Close"
+}
diff --git a/worklenz-backend/src/public/locales/en/project-drawer.json b/worklenz-backend/src/public/locales/en/project-drawer.json
new file mode 100644
index 00000000..be553a01
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/project-drawer.json
@@ -0,0 +1,52 @@
+{
+ "createProject": "Create Project",
+ "editProject": "Edit Project",
+ "enterCategoryName": "Enter a name for the category",
+ "hitEnterToCreate": "Hit enter to create!",
+ "enterNotes": "Notes",
+ "youCanManageClientsUnderSettings": "You can manage clients under Settings",
+ "addCategory": "Add a category to the project",
+ "newCategory": "New Category",
+ "notes": "Notes",
+ "startDate": "Start Date",
+ "endDate": "End Date",
+ "estimateWorkingDays": "Estimate working days",
+ "estimateManDays": "Estimate man days",
+ "hoursPerDay": "Hours per day",
+ "create": "Create",
+ "update": "Update",
+ "delete": "Delete",
+ "typeToSearchClients": "Type to search clients",
+ "projectColor": "Project Color",
+ "pleaseEnterAName": "Please enter a name",
+ "enterProjectName": "Enter project name",
+ "name": "Name",
+ "status": "Status",
+ "health": "Health",
+ "category": "Category",
+ "projectManager": "Project Manager",
+ "client": "Client",
+ "deleteConfirmation": "Are you sure you want to delete?",
+ "deleteConfirmationDescription": "This will remove all associated data and cannot be undone.",
+ "yes": "Yes",
+ "no": "No",
+ "createdAt": "Created",
+ "updatedAt": "Updated",
+ "by": "by",
+ "add": "Add",
+ "asClient": "as client",
+ "createClient": "Create client",
+ "searchInputPlaceholder": "Search by name or email",
+ "hoursPerDayValidationMessage": "Hours per day must be a number between 1 and 24",
+ "workingDaysValidationMessage": "Working days must be a positive number",
+ "manDaysValidationMessage": "Man days must be a positive number",
+ "noPermission": "No permission",
+ "progressSettings": "Progress Settings",
+ "manualProgress": "Manual Progress",
+ "manualProgressTooltip": "Allow manual progress updates for tasks without subtasks",
+ "weightedProgress": "Weighted Progress",
+ "weightedProgressTooltip": "Calculate progress based on subtask weights",
+ "timeProgress": "Time-based Progress",
+ "timeProgressTooltip": "Calculate progress based on estimated time",
+ "enterProjectKey": "Enter project key"
+}
diff --git a/worklenz-backend/src/public/locales/en/project-view-files.json b/worklenz-backend/src/public/locales/en/project-view-files.json
new file mode 100644
index 00000000..12672620
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/project-view-files.json
@@ -0,0 +1,14 @@
+{
+ "nameColumn": "Name",
+ "attachedTaskColumn": "Attached Task",
+ "sizeColumn": "Size",
+ "uploadedByColumn": "Uploaded By",
+ "uploadedAtColumn": "Uploaded At",
+ "fileIconAlt": "File icon",
+ "titleDescriptionText": "All attachments to tasks in this project will appear here.",
+ "deleteConfirmationTitle": "Are you sure?",
+ "deleteConfirmationOk": "Yes",
+ "deleteConfirmationCancel": "Cancel",
+ "segmentedTooltip": "Coming soon! Switch between list view and thumbnail view.",
+ "emptyText": "There are no attachments in the project."
+}
diff --git a/worklenz-backend/src/public/locales/en/project-view-insights.json b/worklenz-backend/src/public/locales/en/project-view-insights.json
new file mode 100644
index 00000000..1b174a85
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/project-view-insights.json
@@ -0,0 +1,41 @@
+{
+ "overview": {
+ "title": "Overview",
+ "statusOverview": "Status Overview",
+ "priorityOverview": "Priority Overview",
+ "lastUpdatedTasks": "Last Updated Tasks"
+ },
+ "members": {
+ "title": "Members",
+ "tooltip": "Members",
+ "tasksByMembers": "Tasks by members",
+ "tasksByMembersTooltip": "Tasks by members",
+ "name": "Name",
+ "taskCount": "Task Count",
+ "contribution": "Contribution",
+ "completed": "Completed",
+ "incomplete": "Incomplete",
+ "overdue": "Overdue",
+ "progress": "Progress"
+ },
+ "tasks": {
+ "overdueTasks": "Overdue Tasks",
+ "overLoggedTasks": "Over logged Tasks",
+ "tasksCompletedEarly": "Tasks completed early",
+ "tasksCompletedLate": "Tasks completed late",
+ "overLoggedTasksTooltip": "Tasks that has time logged past their estimated time",
+ "overdueTasksTooltip": "Tasks that are past their due date"
+ },
+ "common": {
+ "seeAll": "See all",
+ "totalLoggedHours": "Total logged hours",
+ "totalEstimation": "Total estimation",
+ "completedTasks": "Completed tasks",
+ "incompleteTasks": "Incomplete tasks",
+ "overdueTasks": "Overdue tasks",
+ "overdueTasksTooltip": "Tasks that are past their due date",
+ "totalLoggedHoursTooltip": "Task estimation and logged time for tasks.",
+ "includeArchivedTasks": "Include Archived Tasks",
+ "export": "Export"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/en/project-view-members.json b/worklenz-backend/src/public/locales/en/project-view-members.json
new file mode 100644
index 00000000..6ed8ddf0
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/project-view-members.json
@@ -0,0 +1,17 @@
+{
+ "nameColumn": "Name",
+ "jobTitleColumn": "Job Title",
+ "emailColumn": "Email",
+ "tasksColumn": "Tasks",
+ "taskProgressColumn": "Task Progress",
+ "accessColumn": "Access",
+ "fileIconAlt": "File icon",
+ "deleteConfirmationTitle": "Are you sure?",
+ "deleteConfirmationOk": "Yes",
+ "deleteConfirmationCancel": "Cancel",
+ "refreshButtonTooltip": "Refresh members",
+ "deleteButtonTooltip": "Remove from project",
+ "memberCount": "Member",
+ "membersCountPlural": "Members",
+ "emptyText": "There are no attachments in the project."
+}
diff --git a/worklenz-backend/src/public/locales/en/project-view-updates.json b/worklenz-backend/src/public/locales/en/project-view-updates.json
new file mode 100644
index 00000000..d7140ad8
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/project-view-updates.json
@@ -0,0 +1,6 @@
+{
+ "inputPlaceholder": "Add a comment..",
+ "addButton": "Add",
+ "cancelButton": "Cancel",
+ "deleteButton": "Delete"
+}
diff --git a/worklenz-backend/src/public/locales/en/project-view.json b/worklenz-backend/src/public/locales/en/project-view.json
new file mode 100644
index 00000000..82ab21f2
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/project-view.json
@@ -0,0 +1,14 @@
+{
+ "taskList": "Task List",
+ "board": "Board",
+ "insights": "Insights",
+ "files": "Files",
+ "members": "Members",
+ "updates": "Updates",
+ "projectView": "Project View",
+ "loading": "Loading project...",
+ "error": "Error loading project",
+ "pinnedTab": "Pinned as default tab",
+ "pinTab": "Pin as default tab",
+ "unpinTab": "Unpin default tab"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/en/project-view/import-task-templates.json b/worklenz-backend/src/public/locales/en/project-view/import-task-templates.json
new file mode 100644
index 00000000..d732aa08
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/project-view/import-task-templates.json
@@ -0,0 +1,11 @@
+{
+ "importTaskTemplate": "Import Task Template",
+ "templateName": "Template Name",
+ "templateDescription": "Template Description",
+ "selectedTasks": "Selected Tasks",
+ "tasks": "Tasks",
+ "templates": "Templates",
+ "remove": "Remove",
+ "cancel": "Cancel",
+ "import": "Import"
+}
diff --git a/worklenz-backend/src/public/locales/en/project-view/project-member-drawer.json b/worklenz-backend/src/public/locales/en/project-view/project-member-drawer.json
new file mode 100644
index 00000000..ad2d60c8
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/project-view/project-member-drawer.json
@@ -0,0 +1,7 @@
+{
+ "title": "Project Members",
+ "searchLabel": "Add members by adding their name or email",
+ "searchPlaceholder": "Type name or email",
+ "inviteAsAMember": "Invite as a member",
+ "inviteNewMemberByEmail": "Invite new member by email"
+}
diff --git a/worklenz-backend/src/public/locales/en/project-view/project-view-header.json b/worklenz-backend/src/public/locales/en/project-view/project-view-header.json
new file mode 100644
index 00000000..1bbb6c15
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/project-view/project-view-header.json
@@ -0,0 +1,30 @@
+{
+ "importTasks": "Import tasks",
+ "importTask": "Import task",
+ "createTask": "Create task",
+ "settings": "Settings",
+ "subscribe": "Subscribe",
+ "unsubscribe": "Unsubscribe",
+ "deleteProject": "Delete project",
+ "startDate": "Start date",
+ "endDate": "End date",
+ "projectSettings": "Project settings",
+ "projectSummary": "Project summary",
+ "receiveProjectSummary": "Receive a project summary every evening.",
+ "refreshProject": "Refresh project",
+ "saveAsTemplate": "Save as template",
+ "invite": "Invite",
+ "share": "Share",
+ "subscribeTooltip": "Subscribe to project notifications",
+ "unsubscribeTooltip": "Unsubscribe from project notifications",
+ "refreshTooltip": "Refresh project data",
+ "settingsTooltip": "Open project settings",
+ "saveAsTemplateTooltip": "Save this project as a template",
+ "inviteTooltip": "Invite team members to this project",
+ "createTaskTooltip": "Create a new task",
+ "importTaskTooltip": "Import task from template",
+ "navigateBackTooltip": "Go back to projects list",
+ "projectStatusTooltip": "Project status",
+ "projectDatesInfo": "Project timeline information",
+ "projectCategoryTooltip": "Project category"
+}
diff --git a/worklenz-backend/src/public/locales/en/project-view/save-as-template.json b/worklenz-backend/src/public/locales/en/project-view/save-as-template.json
new file mode 100644
index 00000000..2b3e7564
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/project-view/save-as-template.json
@@ -0,0 +1,27 @@
+{
+ "title": "Save as Template",
+ "templateName": "Template Name",
+ "includes": "What should be included in the template from the project ?",
+ "includesOptions": {
+ "statuses": "Statuses",
+ "phases": "Phases",
+ "labels": "Labels"
+ },
+ "taskIncludes": "What should be included in the template from the tasks ?",
+ "taskIncludesOptions": {
+ "statuses": "Statuses",
+ "phases": "Phases",
+ "labels": "Labels",
+ "name": "Name",
+ "priority": "Priority",
+ "status": "Status",
+ "phase": "Phase",
+ "label": "Label",
+ "timeEstimate": "Time Estimate",
+ "description": "Description",
+ "subTasks": "Sub Tasks"
+ },
+ "cancel": "Cancel",
+ "save": "Save",
+ "templateNamePlaceholder": "Enter template name"
+}
diff --git a/worklenz-backend/src/public/locales/en/reporting-members-drawer.json b/worklenz-backend/src/public/locales/en/reporting-members-drawer.json
new file mode 100644
index 00000000..cca01177
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/reporting-members-drawer.json
@@ -0,0 +1,90 @@
+{
+ "exportButton": "Export",
+ "timeLogsButton": "TimeLogs",
+ "activityLogsButton": "Activity Logs",
+ "tasksButton": "Tasks",
+ "searchByNameInputPlaceholder": "Search by name",
+
+ "overviewTab": "Overview",
+ "timeLogsTab": "Time Logs",
+ "activityLogsTab": "Activity Logs",
+ "tasksTab": "Tasks",
+
+ "projectsText": "Projects",
+ "totalTasksText": "Total Tasks",
+ "assignedTasksText": "Assigned Tasks",
+ "completedTasksText": "Completed Tasks",
+ "ongoingTasksText": "Ongoing Tasks",
+ "overdueTasksText": "Overdue Tasks",
+ "loggedHoursText": "Logged Hours",
+
+ "tasksText": "Tasks",
+ "allText": "All",
+
+ "tasksByProjectsText": "Tasks By Projects",
+ "tasksByStatusText": "Tasks By Status",
+ "tasksByPriorityText": "Tasks By Priority",
+
+ "todoText": "To Do",
+ "doingText": "Doing",
+ "doneText": "Done",
+ "lowText": "Low",
+ "mediumText": "Medium",
+ "highText": "High",
+
+ "billableButton": "Billable",
+ "billableText": "Billable",
+ "nonBillableText": "Non Billable",
+
+ "timeLogsEmptyPlaceholder": "No time logs to show",
+ "loggedText": "Logged",
+ "forText": "for",
+ "inText": "in",
+ "updatedText": "Updated",
+ "fromText": "From",
+ "toText": "to",
+ "withinText": "within",
+
+ "activityLogsEmptyPlaceholder": "No activity logs to show",
+
+ "filterByText": "Filter by:",
+ "selectProjectPlaceholder": "Select Project",
+
+ "taskColumn": "Task",
+ "nameColumn": "Name",
+ "projectColumn": "Project",
+ "statusColumn": "Status",
+ "priorityColumn": "Priority",
+ "dueDateColumn": "Due Date",
+ "completedDateColumn": "Completed Date",
+ "estimatedTimeColumn": "Estimated Time",
+ "loggedTimeColumn": "Logged Time",
+ "overloggedTimeColumn": "Overlogged Time",
+ "daysLeftColumn": "Days Left/Overdue",
+ "startDateColumn": "Start Date",
+ "endDateColumn": "End Date",
+ "actualTimeColumn": "Actual Time",
+ "projectHealthColumn": "Project Health",
+ "categoryColumn": "Category",
+ "projectManagerColumn": "Project Manager",
+
+ "tasksStatsOverviewDrawerTitle": "'s Tasks",
+ "projectsStatsOverviewDrawerTitle": "'s Projects",
+
+ "cancelledText": "Cancelled",
+ "blockedText": "Blocked",
+ "onHoldText": "On Hold",
+ "proposedText": "Proposed",
+ "inPlanningText": "In Planning",
+ "inProgressText": "In Progress",
+ "completedText": "Completed",
+ "continuousText": "Continuous",
+
+ "daysLeftText": "days left",
+ "daysOverdueText": "days overdue",
+
+ "notSetText": "NotSet",
+ "needsAttentionText": "Needs Attention",
+ "atRiskText": "At Risk",
+ "goodText": "Good"
+}
diff --git a/worklenz-backend/src/public/locales/en/reporting-members.json b/worklenz-backend/src/public/locales/en/reporting-members.json
new file mode 100644
index 00000000..a8035dcd
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/reporting-members.json
@@ -0,0 +1,35 @@
+{
+ "yesterdayText": "Yesterday",
+ "lastSevenDaysText": "Last 7 Days",
+ "lastWeekText": "Last Week",
+ "lastThirtyDaysText": "Last 30 Days",
+ "lastMonthText": "Last Month",
+ "lastThreeMonthsText": "Last 3 Months",
+ "allTimeText": "All Time",
+ "customRangeText": "Custom range",
+ "startDateInputPlaceholder": "Start date",
+ "EndDateInputPlaceholder": "End date",
+ "filterButton": "Filter",
+
+ "membersTitle": "Members",
+ "includeArchivedButton": "Include Archived Projects",
+ "exportButton": "Export",
+ "excelButton": "Excel",
+ "searchByNameInputPlaceholder": "Search by name",
+
+ "memberColumn": "Member",
+ "tasksProgressColumn": "Tasks Progress",
+ "tasksAssignedColumn": "Tasks Assigned",
+ "completedTasksColumn": "Completed Tasks",
+ "overdueTasksColumn": "Overdue Tasks",
+ "ongoingTasksColumn": "Ongoing Tasks",
+
+ "tasksAssignedColumnTooltip": "Tasks assigned on selected date range",
+ "overdueTasksColumnTooltip": "Tasks overdue for end of the selected date range",
+ "completedTasksColumnTooltip": "Tasks completed on selected date range",
+ "ongoingTasksColumnTooltip": "Started tasks not completed yet",
+
+ "todoText": "To Do",
+ "doingText": "Doing",
+ "doneText": "Done"
+}
diff --git a/worklenz-backend/src/public/locales/en/reporting-overview-drawer.json b/worklenz-backend/src/public/locales/en/reporting-overview-drawer.json
new file mode 100644
index 00000000..84fab1b8
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/reporting-overview-drawer.json
@@ -0,0 +1,39 @@
+{
+ "exportButton": "Export",
+ "projectsButton": "Projects",
+ "membersButton": "Members",
+ "searchByNameInputPlaceholder": "Search by name",
+
+ "overviewTab": "Overview",
+ "projectsTab": "Projects",
+ "membersTab": "Members",
+
+ "projectsByStatusText": "Projects By Status",
+ "projectsByCategoryText": "Projects By Category",
+ "projectsByHealthText": "Projects By Health",
+
+ "projectsText": "Projects",
+ "allText": "All",
+
+ "cancelledText": "Cancelled",
+ "blockedText": "Blocked",
+ "onHoldText": "On Hold",
+ "proposedText": "Proposed",
+ "inPlanningText": "In Planning",
+ "inProgressText": "In Progress",
+ "completedText": "Completed",
+ "continuousText": "Continuous",
+
+ "notSetText": "Not Set",
+ "needsAttentionText": "Needs Attention",
+ "atRiskText": "At Risk",
+ "goodText": "Good",
+
+ "nameColumn": "Name",
+ "emailColumn": "Email",
+ "projectsColumn": "Projects",
+ "tasksColumn": "Tasks",
+ "overdueTasksColumn": "Overdue Tasks",
+ "completedTasksColumn": "Completed Tasks",
+ "ongoingTasksColumn": "Ongoing Tasks"
+}
diff --git a/worklenz-backend/src/public/locales/en/reporting-overview.json b/worklenz-backend/src/public/locales/en/reporting-overview.json
new file mode 100644
index 00000000..73faffd3
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/reporting-overview.json
@@ -0,0 +1,25 @@
+{
+ "overviewTitle": "Overview",
+ "includeArchivedButton": "Include Archived Projects",
+
+ "teamCount": "Team",
+ "teamCountPlural": "Teams",
+ "projectCount": "Project",
+ "projectCountPlural": "Projects",
+ "memberCount": "Member",
+ "memberCountPlural": "Members",
+ "activeProjectCount": "Active Project",
+ "activeProjectCountPlural": "Active Projects",
+ "overdueProjectCount": "Overdue Project",
+ "overdueProjectCountPlural": "Overdue Projects",
+ "unassignedMemberCount": "Unassigned Member",
+ "unassignedMemberCountPlural": "Unassigned Members",
+ "memberWithOverdueTaskCount": "Member With Overdue Task",
+ "memberWithOverdueTaskCountPlural": "Member With Overdue Tasks",
+
+ "teamsText": "Teams",
+
+ "nameColumn": "Name",
+ "projectsColumn": "Projects",
+ "membersColumn": "Members"
+}
diff --git a/worklenz-backend/src/public/locales/en/reporting-projects-drawer.json b/worklenz-backend/src/public/locales/en/reporting-projects-drawer.json
new file mode 100644
index 00000000..243bb411
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/reporting-projects-drawer.json
@@ -0,0 +1,59 @@
+{
+ "exportButton": "Export",
+ "membersButton": "Members",
+ "tasksButton": "Tasks",
+ "searchByNameInputPlaceholder": "Search by name",
+
+ "overviewTab": "Overview",
+ "membersTab": "Members",
+ "tasksTab": "Tasks",
+
+ "completedTasksText": "Completed Tasks",
+ "incompleteTasksText": "Incomplete Tasks",
+ "overdueTasksText": "Overdue Tasks",
+ "allocatedHoursText": "Allocated Hours",
+ "loggedHoursText": "Logged Hours",
+
+ "tasksText": "Tasks",
+ "allText": "All",
+
+ "tasksByStatusText": "Tasks By Status",
+ "tasksByPriorityText": "Tasks By Priority",
+ "tasksByDueDateText": "Tasks By Due Date",
+
+ "todoText": "To Do",
+ "doingText": "Doing",
+ "doneText": "Done",
+ "lowText": "Low",
+ "mediumText": "Medium",
+ "highText": "High",
+ "completedText": "Completed",
+ "upcomingText": "Upcoming",
+ "overdueText": "Overdue",
+ "noDueDateText": "No Due Date",
+
+ "nameColumn": "Name",
+ "tasksCountColumn": "Tasks Count",
+ "completedTasksColumn": "Completed Tasks",
+ "incompleteTasksColumn": "Incomplete Tasks",
+ "overdueTasksColumn": "Overdue Tasks",
+ "contributionColumn": "Contribution",
+ "progressColumn": "Progress",
+ "loggedTimeColumn": "Logged Time",
+ "taskColumn": "Task",
+ "projectColumn": "Project",
+ "statusColumn": "Status",
+ "priorityColumn": "Priority",
+ "phaseColumn": "Phase",
+ "dueDateColumn": "Due Date",
+ "completedDateColumn": "Completed Date",
+ "estimatedTimeColumn": "Estimated Time",
+ "overloggedTimeColumn": "Overlogged Time",
+ "completedOnColumn": "Completed On",
+ "daysOverdueColumn": "Days overdue",
+
+ "groupByText": "Group By:",
+ "statusText": "Status",
+ "priorityText": "Priority",
+ "phaseText": "Phase"
+}
diff --git a/worklenz-backend/src/public/locales/en/reporting-projects-filters.json b/worklenz-backend/src/public/locales/en/reporting-projects-filters.json
new file mode 100644
index 00000000..7d9afccd
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/reporting-projects-filters.json
@@ -0,0 +1,35 @@
+{
+ "searchByNamePlaceholder": "Search by name",
+ "searchByCategoryPlaceholder": "Search by category",
+
+ "statusText": "Status",
+ "healthText": "Health",
+ "categoryText": "Category",
+ "projectManagerText": "Project Manager",
+ "showFieldsText": "Show fields",
+
+ "cancelledText": "Cancelled",
+ "blockedText": "Blocked",
+ "onHoldText": "On Hold",
+ "proposedText": "Proposed",
+ "inPlanningText": "In Planning",
+ "inProgressText": "In Progress",
+ "completedText": "Completed",
+ "continuousText": "Continuous",
+
+ "notSetText": "NotSet",
+ "needsAttentionText": "Needs Attention",
+ "atRiskText": "At Risk",
+ "goodText": "Good",
+
+ "nameText": "Project",
+ "estimatedVsActualText": "Estimated Vs Actual",
+ "tasksProgressText": "Tasks Progress",
+ "lastActivityText": "Last Activity",
+ "datesText": "Start/End Dates",
+ "daysLeftText": "Days Left/Overdue",
+ "projectHealthText": "Project Health",
+ "projectUpdateText": "Project Update",
+ "clientText": "Client",
+ "teamText": "Team"
+}
diff --git a/worklenz-backend/src/public/locales/en/reporting-projects.json b/worklenz-backend/src/public/locales/en/reporting-projects.json
new file mode 100644
index 00000000..8dd472c4
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/reporting-projects.json
@@ -0,0 +1,52 @@
+{
+ "projectCount": "Project",
+ "projectCountPlural": "Projects",
+ "includeArchivedButton": "Include Archived Projects",
+ "exportButton": "Export",
+ "excelButton": "Excel",
+
+ "projectColumn": "Project",
+ "estimatedVsActualColumn": "Estimated Vs Actual",
+ "tasksProgressColumn": "Tasks Progress",
+ "lastActivityColumn": "Last Activity",
+ "statusColumn": "Status",
+ "datesColumn": "Start/End Dates",
+ "daysLeftColumn": "Days Left/Overdue",
+ "projectHealthColumn": "Project Health",
+ "categoryColumn": "Category",
+ "projectUpdateColumn": "Project Update",
+ "clientColumn": "Client",
+ "teamColumn": "Team",
+ "projectManagerColumn": "Project Manager",
+
+ "openButton": "Open",
+
+ "estimatedText": "Estimated",
+ "actualText": "Actual",
+
+ "todoText": "To Do",
+ "doingText": "Doing",
+ "doneText": "Done",
+
+ "cancelledText": "Cancelled",
+ "blockedText": "Blocked",
+ "onHoldText": "On Hold",
+ "proposedText": "Proposed",
+ "inPlanningText": "In Planning",
+ "inProgressText": "In Progress",
+ "completedText": "Completed",
+ "continuousText": "Continuous",
+
+ "daysLeftText": "days left",
+ "dayLeftText": "day left",
+ "daysOverdueText": "days overdue",
+
+ "notSetText": "Not Set",
+ "needsAttentionText": "Needs Attention",
+ "atRiskText": "At Risk",
+ "goodText": "Good",
+
+ "setCategoryText": "Set Category",
+ "searchByNameInputPlaceholder": "Search by name",
+ "todayText": "Today"
+}
diff --git a/worklenz-backend/src/public/locales/en/reporting-sidebar.json b/worklenz-backend/src/public/locales/en/reporting-sidebar.json
new file mode 100644
index 00000000..8e82224d
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/reporting-sidebar.json
@@ -0,0 +1,8 @@
+{
+ "overview": "Overview",
+ "projects": "Projects",
+ "members": "Members",
+ "timeReports": "Time Reports",
+ "estimateVsActual": "Estimate Vs Actual",
+ "currentOrganizationTooltip": "Current organization"
+}
diff --git a/worklenz-backend/src/public/locales/en/schedule.json b/worklenz-backend/src/public/locales/en/schedule.json
new file mode 100644
index 00000000..9e30c04b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/schedule.json
@@ -0,0 +1,39 @@
+{
+ "today": "Today",
+ "week": "Week",
+ "month": "Month",
+
+ "settings": "Settings",
+ "workingDays": "Working days",
+ "monday": "Monday",
+ "tuesday": "Tuesday",
+ "wednesday": "Wednesday",
+ "thursday": "Thursday",
+ "friday": "Friday",
+ "saturday": "Saturday",
+ "sunday": "Sunday",
+ "workingHours": "Working hours",
+ "hours": "hours",
+ "saveButton": "Save",
+
+ "totalAllocation": "Total Allocation",
+ "timeLogged": "Time Logged",
+ "remainingTime": "Remaining Time",
+ "total": "Total",
+ "perDay": "Per Day",
+ "tasks": "tasks",
+ "startDate": "Start Date",
+ "endDate": "End Date",
+
+ "hoursPerDay": "Hours Per Day",
+ "totalHours": "Total Hours",
+ "deleteButton": "Delete",
+ "cancelButton": "Cancel",
+
+ "tabTitle": "Task without Start & End dates",
+
+ "allocatedTime": "Allocated time",
+ "totalLogged": "Total Logged",
+ "loggedBillable": "Logged Billable",
+ "loggedNonBillable": "Logged Non Billable"
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/appearance.json b/worklenz-backend/src/public/locales/en/settings/appearance.json
new file mode 100644
index 00000000..9ce8de64
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/appearance.json
@@ -0,0 +1,5 @@
+{
+ "title": "Appearance",
+ "darkMode": "Dark Mode",
+ "darkModeDescription": "Switch between light and dark mode to customize your viewing experience."
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/categories.json b/worklenz-backend/src/public/locales/en/settings/categories.json
new file mode 100644
index 00000000..716cb5c3
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/categories.json
@@ -0,0 +1,10 @@
+{
+ "categoryColumn": "Category",
+ "deleteConfirmationTitle": "Are you sure?",
+ "deleteConfirmationOk": "Yes",
+ "deleteConfirmationCancel": "Cancel",
+ "associatedTaskColumn": "Associated Projects",
+ "searchPlaceholder": "Search by name",
+ "emptyText": "Categories can be created while updating or creating projects.",
+ "colorChangeTooltip": "Click to change color"
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/change-password.json b/worklenz-backend/src/public/locales/en/settings/change-password.json
new file mode 100644
index 00000000..ad39088b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/change-password.json
@@ -0,0 +1,15 @@
+{
+ "title": "Change Password",
+ "currentPassword": "Current Password",
+ "newPassword": "New Password",
+ "confirmPassword": "Confirm Password",
+ "currentPasswordPlaceholder": "Enter your current password",
+ "newPasswordPlaceholder": "New Password",
+ "confirmPasswordPlaceholder": "Confirm Password",
+ "currentPasswordRequired": "Please input your current password!",
+ "newPasswordRequired": "Please input your new password!",
+ "passwordValidationError": "Password must be at least 8 characters with an uppercase letter, a number, and a symbol.",
+ "passwordMismatch": "Passwords do not match!",
+ "passwordRequirements": "New password should be a minimum of 8 characters, with an uppercase letter, a number, and a symbol.",
+ "updateButton": "Update Password"
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/clients.json b/worklenz-backend/src/public/locales/en/settings/clients.json
new file mode 100644
index 00000000..b7fa4dac
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/clients.json
@@ -0,0 +1,22 @@
+{
+ "nameColumn": "Name",
+ "projectColumn": "Project",
+ "noProjectsAvailable": "No projects available",
+ "deleteConfirmationTitle": "Are you sure?",
+ "deleteConfirmationOk": "Yes",
+ "deleteConfirmationCancel": "Cancel",
+ "searchPlaceholder": "Search by name",
+ "createClient": "Create Client",
+ "pinTooltip": "Click to pin this into the main menu",
+ "createClientDrawerTitle": "Create Client",
+ "updateClientDrawerTitle": "Update Client",
+ "nameLabel": "Name",
+ "namePlaceholder": "Name",
+ "nameRequiredError": "Please enter a Name",
+ "createButton": "Create",
+ "updateButton": "Update",
+ "createClientSuccessMessage": "Create client success!",
+ "createClientErrorMessage": "Create client failed!",
+ "updateClientSuccessMessage": "Update client success!",
+ "updateClientErrorMessage": "Update client failed!"
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/job-titles.json b/worklenz-backend/src/public/locales/en/settings/job-titles.json
new file mode 100644
index 00000000..9ec54f98
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/job-titles.json
@@ -0,0 +1,20 @@
+{
+ "nameColumn": "Name",
+ "deleteConfirmationTitle": "Are you sure?",
+ "deleteConfirmationOk": "Yes",
+ "deleteConfirmationCancel": "Cancel",
+ "searchPlaceholder": "Search by name",
+ "createJobTitleButton": "Create Job Title",
+ "pinTooltip": "Click to pin this into the main menu",
+ "createJobTitleDrawerTitle": "Create Job Title",
+ "updateJobTitleDrawerTitle": "Update Job Title",
+ "nameLabel": "Name",
+ "namePlaceholder": "Name",
+ "nameRequiredError": "Please enter a Name",
+ "createButton": "Create",
+ "updateButton": "Update",
+ "createJobTitleSuccessMessage": "Create job title success!",
+ "createJobTitleErrorMessage": "Create job title failed!",
+ "updateJobTitleSuccessMessage": "Update job title success!",
+ "updateJobTitleErrorMessage": "Update job title failed!"
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/labels.json b/worklenz-backend/src/public/locales/en/settings/labels.json
new file mode 100644
index 00000000..5c3d2479
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/labels.json
@@ -0,0 +1,11 @@
+{
+ "labelColumn": "Label",
+ "deleteConfirmationTitle": "Are you sure?",
+ "deleteConfirmationOk": "Yes",
+ "deleteConfirmationCancel": "Cancel",
+ "associatedTaskColumn": "Associated Task Count",
+ "searchPlaceholder": "Search by name",
+ "emptyText": "Labels can be created while updating or creating tasks.",
+ "pinTooltip": "Click to pin this into the main menu",
+ "colorChangeTooltip": "Click to change color"
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/language.json b/worklenz-backend/src/public/locales/en/settings/language.json
new file mode 100644
index 00000000..331cb7df
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/language.json
@@ -0,0 +1,7 @@
+{
+ "language": "Language",
+ "language_required": "Language is required",
+ "time_zone": "Time zone",
+ "time_zone_required": "Time zone is required",
+ "save_changes": "Save Changes"
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/notifications.json b/worklenz-backend/src/public/locales/en/settings/notifications.json
new file mode 100644
index 00000000..7cc1eb47
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/notifications.json
@@ -0,0 +1,11 @@
+{
+ "title": "Notifications Settings",
+ "emailTitle": "Send me email notifications",
+ "emailDescription": "This includes new task assignments",
+ "dailyDigestTitle": "Send me a daily digest",
+ "dailyDigestDescription": "Every evening, you will receive a summary of recent activity in tasks.",
+ "popupTitle": "Pop up notifications on my computer when Worklenz is open",
+ "popupDescription": "Pop up notifications can be disabled by your browser. Change your browser settings to allow them.",
+ "unreadItemsTitle": "Show the number of unread items",
+ "unreadItemsDescription": "You'll see counts for each notification."
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/profile.json b/worklenz-backend/src/public/locales/en/settings/profile.json
new file mode 100644
index 00000000..43ce2f41
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/profile.json
@@ -0,0 +1,14 @@
+{
+ "uploadError": "You can only upload JPG/PNG file!",
+ "uploadSizeError": "Image must be smaller than 2MB!",
+ "upload": "Upload",
+ "nameLabel": "Name",
+ "nameRequiredError": "Name is required",
+ "emailLabel": "Email",
+ "emailRequiredError": "Email is required",
+ "saveChanges": "Save Changes",
+ "profileJoinedText": "Joined a month ago",
+ "profileLastUpdatedText": "Last updated a month ago",
+ "avatarTooltip": "Click to upload an avatar",
+ "title": "Profile Settings"
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/project-templates.json b/worklenz-backend/src/public/locales/en/settings/project-templates.json
new file mode 100644
index 00000000..802e017b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/project-templates.json
@@ -0,0 +1,8 @@
+{
+ "nameColumn": "Name",
+ "editToolTip": "Edit",
+ "deleteToolTip": "Delete",
+ "confirmText": "Are you sure?",
+ "okText": "Yes",
+ "cancelText": "Cancel"
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/sidebar.json b/worklenz-backend/src/public/locales/en/settings/sidebar.json
new file mode 100644
index 00000000..d0b64829
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/sidebar.json
@@ -0,0 +1,15 @@
+{
+ "profile": "Profile",
+ "notifications": "Notifications",
+ "clients": "Clients",
+ "job-titles": "Job Titles",
+ "labels": "Labels",
+ "categories": "Categories",
+ "project-templates": "Project Templates",
+ "task-templates": "Task Templates",
+ "team-members": "Team Members",
+ "teams": "Teams",
+ "change-password": "Change Password",
+ "language-and-region": "Language and Region",
+ "appearance": "Appearance"
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/task-templates.json b/worklenz-backend/src/public/locales/en/settings/task-templates.json
new file mode 100644
index 00000000..b40bed2d
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/task-templates.json
@@ -0,0 +1,9 @@
+{
+ "nameColumn": "Name",
+ "createdColumn": "Created",
+ "editToolTip": "Edit",
+ "deleteToolTip": "Delete",
+ "confirmText": "Are you sure?",
+ "okText": "Yes",
+ "cancelText": "Cancel"
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/team-members.json b/worklenz-backend/src/public/locales/en/settings/team-members.json
new file mode 100644
index 00000000..36918b90
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/team-members.json
@@ -0,0 +1,47 @@
+{
+ "title": "Team Members",
+ "nameColumn": "Name",
+ "projectsColumn": "Projects",
+ "emailColumn": "Email",
+ "teamAccessColumn": "Team Access",
+ "memberCount": "Member",
+ "membersCountPlural": "Members",
+ "searchPlaceholder": "Search members by name",
+ "pinTooltip": "Refresh member list",
+ "addMemberButton": "Add New Member",
+ "editTooltip": "Edit member",
+ "deactivateTooltip": "Deactivate member",
+ "activateTooltip": "Activate member",
+ "deleteTooltip": "Delete member",
+ "confirmDeleteTitle": "Are you sure you want to delete this member?",
+ "confirmActivateTitle": "Are you sure you want to change this member's status?",
+ "okText": "Yes, proceed",
+ "cancelText": "No, cancel",
+ "deactivatedText": "(Currently deactivated)",
+ "pendingInvitationText": "(Invitation pending)",
+ "addMemberDrawerTitle": "Add New Team Member",
+ "updateMemberDrawerTitle": "Update Team Member",
+ "addMemberEmailHint": "Members will be added to the team regardless of invitation acceptance status",
+ "memberEmailLabel": "Email(s)",
+ "memberEmailPlaceholder": "Enter team member email address",
+ "memberEmailRequiredError": "Please enter a valid email address",
+ "jobTitleLabel": "Job Title",
+ "jobTitlePlaceholder": "Select or search job title (Optional)",
+ "memberAccessLabel": "Access Level",
+ "addToTeamButton": "Add Member to Team",
+ "updateButton": "Save Changes",
+ "resendInvitationButton": "Resend Invitation Email",
+ "invitationSentSuccessMessage": "Team invitation sent successfully!",
+ "createMemberSuccessMessage": "New team member added successfully!",
+ "createMemberErrorMessage": "Failed to add team member. Please try again.",
+ "updateMemberSuccessMessage": "Team member updated successfully!",
+ "updateMemberErrorMessage": "Failed to update team member. Please try again.",
+ "memberText": "Member",
+ "adminText": "Admin",
+ "ownerText": "Team Owner",
+ "addedText": "Added",
+ "updatedText": "Updated",
+ "noResultFound": "Type an email address and hit enter...",
+ "jobTitlesFetchError": "Failed to fetch job titles",
+ "invitationResent": "Invitation resent successfully!"
+}
diff --git a/worklenz-backend/src/public/locales/en/settings/teams.json b/worklenz-backend/src/public/locales/en/settings/teams.json
new file mode 100644
index 00000000..57a1df51
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/settings/teams.json
@@ -0,0 +1,16 @@
+{
+ "title": "Teams",
+ "team": "Team",
+ "teams": "Teams",
+ "name": "Name",
+ "created": "Created",
+ "ownsBy": "Owns By",
+ "edit": "Edit",
+ "editTeam": "Edit Team",
+ "pinTooltip": "Click to pin this into the main menu",
+ "editTeamName": "Edit Team Name",
+ "updateName": "Update Name",
+ "namePlaceholder": "Name",
+ "nameRequired": "Please enter a Name",
+ "updateFailed": "Team name change failed!"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/en/task-drawer/task-drawer-info-tab.json b/worklenz-backend/src/public/locales/en/task-drawer/task-drawer-info-tab.json
new file mode 100644
index 00000000..f88ecde9
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/task-drawer/task-drawer-info-tab.json
@@ -0,0 +1,30 @@
+{
+ "details": {
+ "task-key": "Task Key",
+ "phase": "Phase",
+ "assignees": "Assignees",
+ "due-date": "Due Date",
+ "time-estimation": "Time Estimation",
+ "priority": "Priority",
+ "labels": "Labels",
+ "billable": "Billable",
+ "notify": "Notify",
+ "when-done-notify": "When done, notify",
+ "start-date": "Start Date",
+ "end-date": "End Date",
+ "hide-start-date": "Hide Start Date",
+ "show-start-date": "Show Start Date",
+ "hours": "Hours",
+ "minutes": "Minutes",
+ "recurring": "Recurring"
+ },
+ "description": {
+ "title": "Description",
+ "placeholder": "Add a more detailed description..."
+ },
+ "subTasks": {
+ "title": "Sub Tasks",
+ "add-sub-task": "Add Sub Task",
+ "refresh-sub-tasks": "Refresh Sub Tasks"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/en/task-drawer/task-drawer-recurring-config.json b/worklenz-backend/src/public/locales/en/task-drawer/task-drawer-recurring-config.json
new file mode 100644
index 00000000..1d22e41b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/task-drawer/task-drawer-recurring-config.json
@@ -0,0 +1,34 @@
+{
+ "recurring": "Recurring",
+ "recurringTaskConfiguration": "Recurring task configuration",
+ "repeats": "Repeats",
+ "daily": "Daily",
+ "weekly": "Weekly",
+ "everyXDays": "Every X Days",
+ "everyXWeeks": "Every X Weeks",
+ "everyXMonths": "Every X Months",
+ "monthly": "Monthly",
+ "selectDaysOfWeek": "Select Days of the Week",
+ "mon": "Mon",
+ "tue": "Tue",
+ "wed": "Wed",
+ "thu": "Thu",
+ "fri": "Fri",
+ "sat": "Sat",
+ "sun": "Sun",
+ "monthlyRepeatType": "Monthly repeat type",
+ "onSpecificDate": "On a specific date",
+ "onSpecificDay": "On a specific day",
+ "dateOfMonth": "Date of the month",
+ "weekOfMonth": "Week of the month",
+ "dayOfWeek": "Day of the week",
+ "first": "First",
+ "second": "Second",
+ "third": "Third",
+ "fourth": "Fourth",
+ "last": "Last",
+ "intervalDays": "Interval (days)",
+ "intervalWeeks": "Interval (weeks)",
+ "intervalMonths": "Interval (months)",
+ "saveChanges": "Save Changes"
+}
diff --git a/worklenz-backend/src/public/locales/en/task-drawer/task-drawer.json b/worklenz-backend/src/public/locales/en/task-drawer/task-drawer.json
new file mode 100644
index 00000000..b5147324
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/task-drawer/task-drawer.json
@@ -0,0 +1,123 @@
+{
+ "taskHeader": {
+ "taskNamePlaceholder": "Type your Task",
+ "deleteTask": "Delete Task"
+ },
+ "taskInfoTab": {
+ "title": "Info",
+ "details": {
+ "title": "Details",
+ "task-key": "Task Key",
+ "phase": "Phase",
+ "assignees": "Assignees",
+ "due-date": "Due Date",
+ "time-estimation": "Time Estimation",
+ "priority": "Priority",
+ "labels": "Labels",
+ "billable": "Billable",
+ "notify": "Notify",
+ "when-done-notify": "When done, notify",
+ "start-date": "Start Date",
+ "end-date": "End Date",
+ "hide-start-date": "Hide Start Date",
+ "show-start-date": "Show Start Date",
+ "hours": "Hours",
+ "minutes": "Minutes",
+ "progressValue": "Progress Value",
+ "progressValueTooltip": "Set the progress percentage (0-100%)",
+ "progressValueRequired": "Please enter a progress value",
+ "progressValueRange": "Progress must be between 0 and 100",
+ "taskWeight": "Task Weight",
+ "taskWeightTooltip": "Set the weight of this subtask (percentage)",
+ "taskWeightRequired": "Please enter a task weight",
+ "taskWeightRange": "Weight must be between 0 and 100",
+ "recurring": "Recurring"
+ },
+ "labels": {
+ "labelInputPlaceholder": "Search or create",
+ "labelsSelectorInputTip": "Hit Enter to create"
+ },
+ "description": {
+ "title": "Description",
+ "placeholder": "Add a more detailed description..."
+ },
+ "subTasks": {
+ "title": "Sub Tasks",
+ "addSubTask": "Add Sub Task",
+ "addSubTaskInputPlaceholder": "Type your task and hit enter",
+ "refreshSubTasks": "Refresh Sub Tasks",
+ "edit": "Edit",
+ "delete": "Delete",
+ "confirmDeleteSubTask": "Are you sure you want to delete this subtask?",
+ "deleteSubTask": "Delete Sub Task"
+ },
+ "dependencies": {
+ "title": "Dependencies",
+ "addDependency": "+ Add new dependency",
+ "blockedBy": "Blocked By",
+ "searchTask": "Type to search task",
+ "noTasksFound": "No tasks found",
+ "confirmDeleteDependency": "Are you sure you want to delete?"
+ },
+ "attachments": {
+ "title": "Attachments",
+ "chooseOrDropFileToUpload": "Choose or drop file to upload",
+ "uploading": "Uploading..."
+ },
+ "comments": {
+ "title": "Comments",
+ "addComment": "+ Add new comment",
+ "noComments": "No comments yet. Be the first to comment!",
+ "delete": "Delete",
+ "confirmDeleteComment": "Are you sure you want to delete this comment?",
+ "addCommentPlaceholder": "Add a comment...",
+ "cancel": "Cancel",
+ "commentButton": "Comment",
+ "attachFiles": "Attach files",
+ "addMoreFiles": "Add more files",
+ "selectedFiles": "Selected Files (Up to 25MB, Maximum of {count})",
+ "maxFilesError": "You can only upload a maximum of {count} files",
+ "processFilesError": "Failed to process files",
+ "addCommentError": "Please add a comment or attach files",
+ "createdBy": "Created {{time}} by {{user}}",
+ "updatedTime": "Updated {{time}}"
+ },
+ "searchInputPlaceholder": "Search by name",
+ "pendingInvitation": "Pending Invitation"
+ },
+ "taskTimeLogTab": {
+ "title": "Time Log",
+ "addTimeLog": "Add new time log",
+ "totalLogged": "Total Logged",
+ "exportToExcel": "Export to Excel",
+ "noTimeLogsFound": "No time logs found",
+ "timeLogForm": {
+ "date": "Date",
+ "startTime": "Start Time",
+ "endTime": "End Time",
+ "workDescription": "Work Description",
+ "descriptionPlaceholder": "Add a description",
+ "logTime": "Log time",
+ "updateTime": "Update time",
+ "cancel": "Cancel",
+ "selectDateError": "Please select a date",
+ "selectStartTimeError": "Please select start time",
+ "selectEndTimeError": "Please select end time",
+ "endTimeAfterStartError": "End time must be after start time"
+ }
+ },
+ "taskActivityLogTab": {
+ "title": "Activity Log",
+ "add": "ADD",
+ "remove": "REMOVE",
+ "none": "None",
+ "weight": "Weight",
+ "createdTask": "created the task."
+ },
+ "taskProgress": {
+ "markAsDoneTitle": "Mark Task as Done?",
+ "confirmMarkAsDone": "Yes, mark as done",
+ "cancelMarkAsDone": "No, keep current status",
+ "markAsDoneDescription": "You've set the progress to 100%. Would you like to update the task status to \"Done\"?"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/en/task-list-filters.json b/worklenz-backend/src/public/locales/en/task-list-filters.json
new file mode 100644
index 00000000..a38356c6
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/task-list-filters.json
@@ -0,0 +1,85 @@
+{
+ "searchButton": "Search",
+ "resetButton": "Reset",
+ "searchInputPlaceholder": "Search by name",
+
+ "sortText": "Sort",
+ "statusText": "Status",
+ "phaseText": "Phase",
+ "memberText": "Members",
+ "assigneesText": "Assignees",
+ "priorityText": "Priority",
+ "labelsText": "Labels",
+ "membersText": "Members",
+ "groupByText": "Group by",
+ "showArchivedText": "Show archived",
+ "showFieldsText": "Show fields",
+ "keyText": "Key",
+ "taskText": "Task",
+ "descriptionText": "Description",
+ "phasesText": "Phases",
+ "listText": "List",
+ "progressText": "Progress",
+ "timeTrackingText": "Time Tracking",
+ "timetrackingText": "Time Tracking",
+ "estimationText": "Estimation",
+ "startDateText": "Start Date",
+ "startdateText": "Start Date",
+ "endDateText": "End Date",
+ "dueDateText": "Due Date",
+ "duedateText": "Due Date",
+ "completedDateText": "Completed Date",
+ "completeddateText": "Completed Date",
+ "createdDateText": "Created Date",
+ "createddateText": "Created Date",
+ "lastUpdatedText": "Last Updated",
+ "lastupdatedText": "Last Updated",
+ "reporterText": "Reporter",
+ "dueTimeText": "Due Time",
+ "duetimeText": "Due Time",
+
+ "lowText": "Low",
+ "mediumText": "Medium",
+ "highText": "High",
+
+ "createStatusButtonTooltip": "Status settings",
+ "configPhaseButtonTooltip": "Phase settings",
+ "noLabelsFound": "No labels found",
+
+ "addStatusButton": "Add Status",
+ "addPhaseButton": "Add Phase",
+
+ "createStatus": "Create Status",
+ "name": "Name",
+ "category": "Category",
+ "selectCategory": "Select a category",
+ "pleaseEnterAName": "Please enter a name",
+ "pleaseSelectACategory": "Please select a category",
+ "create": "Create",
+
+ "searchTasks": "Search tasks...",
+ "searchPlaceholder": "Search...",
+ "fieldsText": "Fields",
+ "loadingFilters": "Loading filters...",
+ "noOptionsFound": "No options found",
+ "filtersActive": "filters active",
+ "filterActive": "filter active",
+ "clearAll": "Clear all",
+ "clearing": "Clearing...",
+ "cancel": "Cancel",
+ "search": "Search",
+ "groupedBy": "Grouped by",
+ "manageStatuses": "Manage Statuses",
+ "managePhases": "Manage Phases",
+ "dragToReorderStatuses": "Drag statuses to reorder them. Each status can have a different category.",
+ "enterNewStatusName": "Enter new status name...",
+ "addStatus": "Add Status",
+ "noStatusesFound": "No statuses found. Create your first status above.",
+ "deleteStatus": "Delete Status",
+ "deleteStatusConfirm": "Are you sure you want to delete this status? This action cannot be undone.",
+ "rename": "Rename",
+ "delete": "Delete",
+ "enterStatusName": "Enter status name",
+ "selectCategory": "Select category",
+ "close": "Close"
+}
diff --git a/worklenz-backend/src/public/locales/en/task-list-table.json b/worklenz-backend/src/public/locales/en/task-list-table.json
new file mode 100644
index 00000000..5c03f203
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/task-list-table.json
@@ -0,0 +1,136 @@
+{
+ "keyColumn": "Key",
+ "taskColumn": "Task",
+ "descriptionColumn": "Description",
+ "progressColumn": "Progress",
+ "membersColumn": "Members",
+ "assigneesColumn": "Assignees",
+ "labelsColumn": "Labels",
+ "phasesColumn": "Phases",
+ "phaseColumn": "Phase",
+ "statusColumn": "Status",
+ "priorityColumn": "Priority",
+ "timeTrackingColumn": "Time Tracking",
+ "timetrackingColumn": "Time Tracking",
+ "estimationColumn": "Estimation",
+ "startDateColumn": "Start Date",
+ "startdateColumn": "Start Date",
+ "dueDateColumn": "Due Date",
+ "duedateColumn": "Due Date",
+ "completedDateColumn": "Completed Date",
+ "completeddateColumn": "Completed Date",
+ "createdDateColumn": "Created Date",
+ "createddateColumn": "Created Date",
+ "lastUpdatedColumn": "Last Updated",
+ "lastupdatedColumn": "Last Updated",
+ "reporterColumn": "Reporter",
+ "dueTimeColumn": "Due Time",
+ "todoSelectorText": "To Do",
+ "doingSelectorText": "Doing",
+ "doneSelectorText": "Done",
+
+ "lowSelectorText": "Low",
+ "mediumSelectorText": "Medium",
+ "highSelectorText": "High",
+
+ "selectText": "Select",
+ "labelsSelectorInputTip": "Hit enter to create!",
+
+ "addTaskText": "Add Task",
+ "addSubTaskText": "Add Sub Task",
+ "addTaskInputPlaceholder": "Type your task and hit enter",
+ "noTasksInGroup": "No tasks in this group",
+
+ "openButton": "Open",
+ "okButton": "Ok",
+
+ "noLabelsFound": "No labels found",
+ "searchInputPlaceholder": "Search or create",
+ "assigneeSelectorInviteButton": "Invite a new member by email",
+ "labelInputPlaceholder": "Search or create",
+ "searchLabelsPlaceholder": "Search labels...",
+ "createLabelButton": "Create \"{{name}}\"",
+ "manageLabelsPath": "Settings โ Labels",
+
+ "pendingInvitation": "Pending Invitation",
+
+ "contextMenu": {
+ "assignToMe": "Assign to me",
+ "moveTo": "Move to",
+ "unarchive": "Unarchive",
+ "archive": "Archive",
+ "convertToSubTask": "Convert to Sub task",
+ "convertToTask": "Convert to Task",
+ "delete": "Delete",
+ "searchByNameInputPlaceholder": "Search by name"
+ },
+ "setDueDate": "Set due date",
+ "setStartDate": "Set start date",
+ "clearDueDate": "Clear due date",
+ "clearStartDate": "Clear start date",
+ "dueDatePlaceholder": "Due Date",
+ "startDatePlaceholder": "Start Date",
+
+ "emptyStates": {
+ "noTaskGroups": "No task groups found",
+ "noTaskGroupsDescription": "Tasks will appear here when they are created or when filters are applied.",
+ "errorPrefix": "Error:",
+ "dragTaskFallback": "Task"
+ },
+
+ "customColumns": {
+ "addCustomColumn": "Add a custom column",
+ "customColumnHeader": "Custom Column",
+ "customColumnSettings": "Custom column settings",
+ "noCustomValue": "No value",
+ "peopleField": "People field",
+ "noDate": "No date",
+ "unsupportedField": "Unsupported field type",
+
+ "modal": {
+ "addFieldTitle": "Add field",
+ "editFieldTitle": "Edit field",
+ "fieldTitle": "Field title",
+ "fieldTitleRequired": "Field title is required",
+ "columnTitlePlaceholder": "Column title",
+ "type": "Type",
+ "deleteConfirmTitle": "Are you sure you want to delete this custom column?",
+ "deleteConfirmDescription": "This action cannot be undone. All data associated with this column will be permanently deleted.",
+ "deleteButton": "Delete",
+ "cancelButton": "Cancel",
+ "createButton": "Create",
+ "updateButton": "Update",
+ "createSuccessMessage": "Custom column created successfully",
+ "updateSuccessMessage": "Custom column updated successfully",
+ "deleteSuccessMessage": "Custom column deleted successfully",
+ "deleteErrorMessage": "Failed to delete custom column",
+ "createErrorMessage": "Failed to create custom column",
+ "updateErrorMessage": "Failed to update custom column"
+ },
+
+ "fieldTypes": {
+ "people": "People",
+ "number": "Number",
+ "date": "Date",
+ "selection": "Selection",
+ "checkbox": "Checkbox",
+ "labels": "Labels",
+ "key": "Key",
+ "formula": "Formula"
+ }
+ },
+
+ "indicators": {
+ "tooltips": {
+ "subtasks": "{{count}} subtask",
+ "subtasks_plural": "{{count}} subtasks",
+ "comments": "{{count}} comment",
+ "comments_plural": "{{count}} comments",
+ "attachments": "{{count}} attachment",
+ "attachments_plural": "{{count}} attachments",
+ "subscribers": "Task has subscribers",
+ "dependencies": "Task has dependencies",
+ "recurring": "Recurring task"
+ }
+ }
+}
diff --git a/worklenz-backend/src/public/locales/en/task-management.json b/worklenz-backend/src/public/locales/en/task-management.json
new file mode 100644
index 00000000..2d21c746
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/task-management.json
@@ -0,0 +1,35 @@
+{
+ "noTasksInGroup": "No tasks in this group",
+ "noTasksInGroupDescription": "Add a task to get started",
+ "addFirstTask": "Add your first task",
+ "openTask": "Open",
+ "subtask": "subtask",
+ "subtasks": "subtasks",
+ "comment": "comment",
+ "comments": "comments",
+ "attachment": "attachment",
+ "attachments": "attachments",
+ "enterSubtaskName": "Enter subtask name...",
+ "add": "Add",
+ "cancel": "Cancel",
+ "renameGroup": "Rename Group",
+ "renameStatus": "Rename Status",
+ "renamePhase": "Rename Phase",
+ "changeCategory": "Change Category",
+ "clickToEditGroupName": "Click to edit group name",
+ "enterGroupName": "Enter group name",
+
+ "indicators": {
+ "tooltips": {
+ "subtasks": "{{count}} subtask",
+ "subtasks_plural": "{{count}} subtasks",
+ "comments": "{{count}} comment",
+ "comments_plural": "{{count}} comments",
+ "attachments": "{{count}} attachment",
+ "attachments_plural": "{{count}} attachments",
+ "subscribers": "Task has subscribers",
+ "dependencies": "Task has dependencies",
+ "recurring": "Recurring task"
+ }
+ }
+}
diff --git a/worklenz-backend/src/public/locales/en/task-template-drawer.json b/worklenz-backend/src/public/locales/en/task-template-drawer.json
new file mode 100644
index 00000000..9bc59126
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/task-template-drawer.json
@@ -0,0 +1,12 @@
+{
+ "createTaskTemplate": "Create Task Template",
+ "editTaskTemplate": "Edit Task Template",
+ "cancelText": "Cancel",
+ "saveText": "Save",
+ "templateNameText": "Template Name",
+ "templateNameRequired": "Template name is required",
+ "selectedTasks": "Selected Tasks",
+ "removeTask": "Remove",
+ "cancelButton": "Cancel",
+ "saveButton": "Save"
+}
diff --git a/worklenz-backend/src/public/locales/en/tasks/task-table-bulk-actions.json b/worklenz-backend/src/public/locales/en/tasks/task-table-bulk-actions.json
new file mode 100644
index 00000000..42fcc024
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/tasks/task-table-bulk-actions.json
@@ -0,0 +1,41 @@
+{
+ "taskSelected": "task selected",
+ "tasksSelected": "tasks selected",
+ "changeStatus": "Change Status/ Prioriy/ Phases",
+ "changeLabel": "Change Label",
+ "assignToMe": "Assign to me",
+ "changeAssignees": "Change Assignees",
+ "archive": "Archive",
+ "unarchive": "Unarchive",
+ "delete": "Delete",
+ "moreOptions": "More options",
+ "deselectAll": "Deselect all",
+ "status": "Status",
+ "priority": "Priority",
+ "phase": "Phase",
+ "member": "Member",
+ "createTaskTemplate": "Create Task Template",
+ "apply": "Apply",
+ "createLabel": "+ Create Label",
+ "searchOrCreateLabel": "Search or create label...",
+ "hitEnterToCreate": "Press Enter to create",
+ "labelExists": "Label already exists",
+ "pendingInvitation": "Pending Invitation",
+ "noMatchingLabels": "No matching labels",
+ "noLabels": "No labels",
+ "CHANGE_STATUS": "Change Status",
+ "CHANGE_PRIORITY": "Change Priority",
+ "CHANGE_PHASE": "Change Phase",
+ "ADD_LABELS": "Add Labels",
+ "ASSIGN_TO_ME": "Assign to Me",
+ "ASSIGN_MEMBERS": "Assign Members",
+ "ARCHIVE": "Archive",
+ "DELETE": "Delete",
+ "CANCEL": "Cancel",
+ "CLEAR_SELECTION": "Clear Selection",
+ "TASKS_SELECTED": "{{count}} task selected",
+ "TASKS_SELECTED_plural": "{{count}} tasks selected",
+ "DELETE_TASKS_CONFIRM": "Delete {{count}} task?",
+ "DELETE_TASKS_CONFIRM_plural": "Delete {{count}} tasks?",
+ "DELETE_TASKS_WARNING": "This action cannot be undone."
+}
diff --git a/worklenz-backend/src/public/locales/en/template-drawer.json b/worklenz-backend/src/public/locales/en/template-drawer.json
new file mode 100644
index 00000000..55364835
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/template-drawer.json
@@ -0,0 +1,19 @@
+{
+ "title": "Edit Task Template",
+ "cancelText": "Cancel",
+ "saveText": "Save",
+ "templateNameText": "Template Name",
+ "selectedTasks": "Selected Tasks",
+ "removeTask": "Remove",
+ "description": "Description",
+ "phase": "Phase",
+ "statuses": "Statuses",
+ "priorities": "Priorities",
+ "labels": "Labels",
+ "tasks": "Tasks",
+ "noTemplateSelected": "No template selected",
+ "noDescription": "No description",
+ "worklenzTemplates": "Worklenz Templates",
+ "yourTemplatesLibrary": "Your Library",
+ "searchTemplates": "Search Templates"
+}
diff --git a/worklenz-backend/src/public/locales/en/templateDrawer.json b/worklenz-backend/src/public/locales/en/templateDrawer.json
new file mode 100644
index 00000000..70bf2b0c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/templateDrawer.json
@@ -0,0 +1,23 @@
+{
+ "bugTracking": "Bug Tracking",
+ "construction": "Construction",
+ "designCreative": "Design & Creative",
+ "education": "Education",
+ "finance": "Finance",
+ "hrRecruiting": "HR & Recruiting",
+ "informationTechnology": "Information Technology",
+ "legal": "Legal",
+ "manufacturing": "Manufacturing",
+ "marketing": "Marketing",
+ "nonprofit": "Nonprofit",
+ "personalUse": "Personal use",
+ "salesCRM": "Sales & CRM",
+ "serviceConsulting": "Service & Consulting",
+ "softwareDevelopment": "Software Development",
+ "description": "Description",
+ "phase": "Phase",
+ "statuses": "Statuses",
+ "priorities": "Priorities",
+ "labels": "Labels",
+ "tasks": "Tasks"
+}
diff --git a/worklenz-backend/src/public/locales/en/time-report.json b/worklenz-backend/src/public/locales/en/time-report.json
new file mode 100644
index 00000000..00aa3c7f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/time-report.json
@@ -0,0 +1,57 @@
+{
+ "includeArchivedProjects": "Include Archived Projects",
+ "export": "Export",
+ "timeSheet": "Time Sheet",
+
+ "searchByName": "Search by name",
+ "selectAll": "Select All",
+ "teams": "Teams",
+
+ "searchByProject": "Search by project name",
+ "projects": "Projects",
+
+ "searchByCategory": "Search by category name",
+ "categories": "Categories",
+
+ "billable": "Billable",
+ "nonBillable": "Non Billable",
+
+ "total": "Total",
+
+ "projectsTimeSheet": "Projects Time Sheet",
+
+ "loggedTime": "Logged Time(hours)",
+
+ "exportToExcel": "Export to Excel",
+ "logged": "logged",
+ "for": "for",
+
+ "membersTimeSheet": "Members Time Sheet",
+ "member": "Member",
+
+ "estimatedVsActual": "Estimated vs Actual",
+ "workingDays": "Working Days",
+ "manDays": "Man Days",
+ "days": "Days",
+ "estimatedDays": "Estimated Days",
+ "actualDays": "Actual Days",
+
+ "noCategories": "No categories found",
+ "noCategory": "No Category",
+ "noProjects": "No projects found",
+ "noTeams": "No teams found",
+ "noData": "No data found",
+
+ "groupBy": "Group by",
+ "groupByCategory": "Category",
+ "groupByTeam": "Team",
+ "groupByStatus": "Status",
+ "groupByNone": "None",
+ "clearSearch": "Clear search",
+ "selectedProjects": "Selected Projects",
+ "projectsSelected": "projects selected",
+ "showSelected": "Show Selected Only",
+ "expandAll": "Expand All",
+ "collapseAll": "Collapse All",
+ "ungrouped": "Ungrouped"
+}
diff --git a/worklenz-backend/src/public/locales/en/unauthorized.json b/worklenz-backend/src/public/locales/en/unauthorized.json
new file mode 100644
index 00000000..5233250a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/en/unauthorized.json
@@ -0,0 +1,5 @@
+{
+ "title": "Unauthorized!",
+ "subtitle": "You are not authorized to access this page",
+ "button": "Go to Home"
+}
diff --git a/worklenz-backend/src/public/locales/es/404-page.json b/worklenz-backend/src/public/locales/es/404-page.json
new file mode 100644
index 00000000..9413ae9e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/404-page.json
@@ -0,0 +1,4 @@
+{
+ "doesNotExistText": "Lo sentimos, la pรกgina que visitaste no existe.",
+ "backHomeButton": "Volver al inicio"
+}
diff --git a/worklenz-backend/src/public/locales/es/account-setup.json b/worklenz-backend/src/public/locales/es/account-setup.json
new file mode 100644
index 00000000..3f7b013e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/account-setup.json
@@ -0,0 +1,32 @@
+{
+ "continue": "Continuar",
+
+ "setupYourAccount": "Configura tu cuenta.",
+ "organizationStepTitle": "Nombra tu organizaciรณn",
+ "organizationStepLabel": "Elige un nombre para tu cuenta de Worklenz.",
+
+ "projectStepTitle": "Crea tu primer proyecto",
+ "projectStepLabel": "ยฟEn quรฉ proyecto estรกs trabajando ahora?",
+ "projectStepPlaceholder": "e.g. Plan de Marketing",
+
+ "step2Title": "Crea tus primeras tareas",
+ "step2InputLabel": "Escribe algunas tareas que vas a hacer en",
+ "step2AddAnother": "Agregar otro",
+
+ "emailPlaceholder": "Direcciรณn de correo electrรณnico",
+ "invalidEmail": "Por favor, introduce una direcciรณn de correo electrรณnico vรกlida",
+ "or": "o",
+ "templateButton": "Importar desde plantilla",
+ "goBack": "Volver",
+ "cancel": "Cancelar",
+ "create": "Crear",
+ "templateDrawerTitle": "Seleccionar de plantillas",
+ "step3InputLabel": "Invitar por correo electrรณnico",
+ "addAnother": "Agregar otro",
+ "skipForNow": "Omitir por ahora",
+ "formTitle": "Crea tu primera tarea.",
+ "step3Title": "Invita a tu equipo a trabajar",
+
+ "maxMembers": " (Puedes invitar hasta 5 miembros)",
+ "maxTasks": " (Puedes crear hasta 5 tareas)"
+}
diff --git a/worklenz-backend/src/public/locales/es/admin-center/current-bill.json b/worklenz-backend/src/public/locales/es/admin-center/current-bill.json
new file mode 100644
index 00000000..52a4bdbb
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/admin-center/current-bill.json
@@ -0,0 +1,113 @@
+{
+ "title": "Facturaciรณn",
+ "currentBill": "Factura Actual",
+ "configuration": "Configuraciรณn",
+ "currentPlanDetails": "Detalles del Plan Actual",
+ "upgradePlan": "Actualizar Plan",
+ "cardBodyText01": "Prueba gratuita",
+ "cardBodyText02": "(Tu plan de prueba expira en 1 mes 19 dรญas)",
+ "redeemCode": "Canjear Cรณdigo",
+ "accountStorage": "Almacenamiento de la Cuenta",
+ "used": "Usado:",
+ "remaining": "Restante:",
+ "charges": "Cargos",
+ "tooltip": "Cargos para el ciclo de facturaciรณn actual",
+ "description": "Descripciรณn",
+ "billingPeriod": "Periodo de Facturaciรณn",
+ "billStatus": "Estado de la Factura",
+ "perUserValue": "Valor por Usuario",
+ "users": "Usuarios",
+ "amount": "Cantidad",
+ "invoices": "Facturas",
+ "transactionId": "ID de Transacciรณn",
+ "transactionDate": "Fecha de Transacciรณn",
+ "paymentMethod": "Mรฉtodo de Pago",
+ "status": "Estado",
+ "ltdUsers": "Puedes agregar hasta {{ltd_users}} usuarios.",
+
+ "drawerTitle": "Canjear Cรณdigo",
+ "label": "Canjear Cรณdigo",
+ "drawerPlaceholder": "Ingrese su cรณdigo de canje",
+ "redeemSubmit": "Enviar",
+
+ "modalTitle": "Seleccione el mejor plan para su equipo",
+ "seatLabel": "Nรบmero de asientos",
+ "freePlan": "Plan Gratuito",
+ "startup": "Startup",
+ "business": "Negocio",
+ "tag": "Mรกs Popular",
+ "enterprise": "Empresa",
+
+ "freeSubtitle": "gratis para siempre",
+ "freeUsers": "Mejor para uso personal",
+ "freeText01": "100MB de almacenamiento",
+ "freeText02": "3 proyectos",
+ "freeText03": "5 miembros del equipo",
+
+ "startupSubtitle": "TARIFA PLANa / mes",
+ "startupUsers": "Hasta 15 usuarios",
+ "startupText01": "25GB de almacenamiento",
+ "startupText02": "Proyectos activos ilimitados",
+ "startupText03": "Programaciรณn",
+ "startupText04": "Informes",
+ "startupText05": "Suscribirse a proyectos",
+
+ "businessSubtitle": "usuario / mes",
+ "businessUsers": "16 - 200 usuarios",
+
+ "enterpriseUsers": "200 - 500+ usuarios",
+
+ "footerTitle": "Por favor, proporciรณnenos un nรบmero de telรฉfono que podamos usar para contactarte.",
+ "footerLabel": "Nรบmero de Telรฉfono",
+ "footerButton": "Contactarnos",
+
+ "redeemCodePlaceHolder": "Ingrese su cรณdigo de canje",
+ "submit": "Enviar",
+
+ "trialPlan": "Plan de Prueba",
+ "trialExpireDate": "Vรกlido hasta {{trial_expire_date}}",
+ "trialExpired": "Su prueba gratuita expirรณ {{trial_expire_string}}",
+ "trialInProgress": "Su prueba gratuita expira {{trial_expire_string}}",
+
+ "required": "Este campo es requerido",
+ "invalidCode": "Cรณdigo invรกlido",
+
+ "selectPlan": "Seleccione el mejor plan para su equipo",
+ "changeSubscriptionPlan": "Cambie su plan de suscripciรณn",
+ "noOfSeats": "Nรบmero de asientos",
+ "annualPlan": "Pro - Anual",
+ "monthlyPlan": "Pro - Mensual",
+ "freeForever": "Gratis para siempre",
+ "bestForPersonalUse": "Mejor para uso personal",
+ "storage": "Almacenamiento",
+ "projects": "Proyectos",
+ "teamMembers": "Miembros del equipo",
+ "unlimitedTeamMembers": "Miembros del equipo ilimitados",
+ "unlimitedActiveProjects": "Proyectos activos ilimitados",
+ "schedule": "Programaciรณn",
+ "reporting": "Informes",
+ "subscribeToProjects": "Suscribirse a proyectos",
+ "billedAnnually": "Facturado Anualmente",
+ "billedMonthly": "Facturado Mensualmente",
+
+ "pausePlan": "Pausar Plan",
+ "resumePlan": "Reanudar Plan",
+ "changePlan": "Cambiar Plan",
+ "cancelPlan": "Cancelar Plan",
+
+ "perMonthPerUser": "por usuario / mes",
+ "viewInvoice": "Ver Factura",
+ "switchToFreePlan": "Cambiar a Plan Gratuito",
+
+ "expirestoday": "hoy",
+ "expirestomorrow": "maรฑana",
+ "expiredDaysAgo": "hace {{days}} dรญas",
+ "creditPlan": "Plan de Crรฉdito",
+ "customPlan": "Plan Personalizado",
+ "planValidTill": "Su plan es vรกlido hasta {{date}}",
+ "purchaseSeatsText": "Para continuar, deberรก comprar asientos adicionales.",
+ "currentSeatsText": "Actualmente tiene {{seats}} asientos disponibles.",
+ "selectSeatsText": "Seleccione el nรบmero de asientos adicionales a comprar.",
+ "purchase": "Comprar",
+ "contactSales": "Contactar ventas"
+}
diff --git a/worklenz-backend/src/public/locales/es/admin-center/overview.json b/worklenz-backend/src/public/locales/es/admin-center/overview.json
new file mode 100644
index 00000000..f88dbdf6
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/admin-center/overview.json
@@ -0,0 +1,8 @@
+{
+ "overview": "Resumen",
+ "name": "Nombre de la Organizaciรณn",
+ "owner": "Propietario de la Organizaciรณn",
+ "admins": "Administradores de la Organizaciรณn",
+ "contactNumber": "Agregar Nรบmero de Contacto",
+ "edit": "Editar"
+}
diff --git a/worklenz-backend/src/public/locales/es/admin-center/projects.json b/worklenz-backend/src/public/locales/es/admin-center/projects.json
new file mode 100644
index 00000000..ab28374f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/admin-center/projects.json
@@ -0,0 +1,12 @@
+{
+ "membersCount": "Cantidad de miembros",
+ "createdAt": "Creado en",
+ "projectName": "Nombre del proyecto",
+ "teamName": "Nombre del equipo",
+ "refreshProjects": "Refrescar proyectos",
+ "searchPlaceholder": "Buscar por nombre de proyecto",
+ "deleteProject": "ยฟEstรกs seguro de que deseas eliminar este proyecto?",
+ "confirm": "Confirmar",
+ "cancel": "Cancelar",
+ "delete": "Eliminar proyecto"
+}
diff --git a/worklenz-backend/src/public/locales/es/admin-center/sidebar.json b/worklenz-backend/src/public/locales/es/admin-center/sidebar.json
new file mode 100644
index 00000000..7626302c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/admin-center/sidebar.json
@@ -0,0 +1,8 @@
+{
+ "overview": "Resumen",
+ "users": "Usuarios",
+ "teams": "Equipos",
+ "billing": "Facturaciรณn",
+ "projects": "Proyectos",
+ "adminCenter": "Centro de Administraciรณn"
+}
diff --git a/worklenz-backend/src/public/locales/es/admin-center/teams.json b/worklenz-backend/src/public/locales/es/admin-center/teams.json
new file mode 100644
index 00000000..13453656
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/admin-center/teams.json
@@ -0,0 +1,35 @@
+{
+ "title": "Equipos",
+ "subtitle": "equipos",
+ "tooltip": "Actualizar equipos",
+ "placeholder": "Buscar por nombre",
+ "addTeam": "Agregar Equipo",
+ "team": "Equipo",
+ "membersCount": "Cantidad de Miembros",
+ "members": "Miembros",
+ "drawerTitle": "Crear Nuevo Equipo",
+ "label": "Nombre del Equipo",
+ "drawerPlaceholder": "Nombre",
+ "create": "Crear",
+ "delete": "Eliminar",
+ "settings": "Configuraciรณn",
+ "popTitle": "ยฟEstรก seguro?",
+ "message": "Por favor ingrese un nombre",
+ "teamSettings": "Configuraciรณn del Equipo",
+ "teamName": "Nombre del Equipo",
+ "teamDescription": "Descripciรณn del Equipo",
+ "teamMembers": "Miembros del Equipo",
+ "teamMembersCount": "Cantidad de Miembros del Equipo",
+ "teamMembersPlaceholder": "Buscar por nombre",
+ "addMember": "Agregar Miembro",
+ "add": "Agregar",
+ "update": "Actualizar",
+ "teamNamePlaceholder": "Nombre del Equipo",
+ "user": "Usuario",
+ "role": "Rol",
+ "owner": "Propietario",
+ "admin": "Administrador",
+ "member": "Miembro",
+ "cannotChangeOwnerRole": "El rol de Propietario no puede ser cambiado",
+ "pendingInvitation": "Invitaciรณn pendiente"
+}
diff --git a/worklenz-backend/src/public/locales/es/admin-center/users.json b/worklenz-backend/src/public/locales/es/admin-center/users.json
new file mode 100644
index 00000000..05626c3b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/admin-center/users.json
@@ -0,0 +1,9 @@
+{
+ "title": "Usuarios",
+ "subTitle": "usuarios",
+ "placeholder": "Buscar por nombre",
+ "user": "Usuario",
+ "email": "Correo electrรณnico",
+ "lastActivity": "รltima actividad",
+ "refresh": "Actualizar usuarios"
+}
diff --git a/worklenz-backend/src/public/locales/es/all-project-list.json b/worklenz-backend/src/public/locales/es/all-project-list.json
new file mode 100644
index 00000000..4a72d9c7
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/all-project-list.json
@@ -0,0 +1,34 @@
+{
+ "name": "Nombre",
+ "client": "Cliente",
+ "category": "Categorรญa",
+ "status": "Estado",
+ "tasksProgress": "Progreso de Tareas",
+ "updated_at": "รltima Actualizaciรณn",
+ "members": "Miembros",
+ "setting": "Configuraciรณn",
+ "projects": "Proyectos",
+ "refreshProjects": "Actualizar proyectos",
+ "all": "Todos",
+ "favorites": "Favoritos",
+ "archived": "Archivados",
+ "placeholder": "Buscar por nombre",
+ "archive": "Archivar",
+ "unarchive": "Desarchivar",
+ "archiveConfirm": "ยฟEstรก seguro de que desea archivar este proyecto?",
+ "unarchiveConfirm": "ยฟEstรก seguro de que desea desarchivar este proyecto?",
+ "yes": "Sรญ",
+ "no": "No",
+ "clickToFilter": "Haga clic para filtrar por",
+ "noProjects": "No se encontraron proyectos",
+ "addToFavourites": "Agregar a favoritos",
+ "list": "Lista",
+ "group": "Grupo",
+ "listView": "Vista de Lista",
+ "groupView": "Vista de Grupo",
+ "groupBy": {
+ "category": "Categorรญa",
+ "client": "Cliente"
+ },
+ "noPermission": "No tienes permiso para realizar esta acciรณn"
+}
diff --git a/worklenz-backend/src/public/locales/es/auth/auth-common.json b/worklenz-backend/src/public/locales/es/auth/auth-common.json
new file mode 100644
index 00000000..6539ec51
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/auth/auth-common.json
@@ -0,0 +1,5 @@
+{
+ "loggingOut": "Cerrando sesiรณn...",
+ "authenticating": "Autenticando...",
+ "gettingThingsReady": "Preparando todo para ti..."
+}
diff --git a/worklenz-backend/src/public/locales/es/auth/forgot-password.json b/worklenz-backend/src/public/locales/es/auth/forgot-password.json
new file mode 100644
index 00000000..5ba75336
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/auth/forgot-password.json
@@ -0,0 +1,12 @@
+{
+ "headerDescription": "Restablecer tu contraseรฑa",
+ "emailLabel": "Correo electrรณnico",
+ "emailPlaceholder": "Ingresa tu correo electrรณnico",
+ "emailRequired": "ยกPor favor ingresa tu correo electrรณnico!",
+ "resetPasswordButton": "Restablecer Contraseรฑa",
+ "returnToLoginButton": "Volver al Inicio de Sesiรณn",
+ "passwordResetSuccessMessage": "Se ha enviado un enlace para restablecer la contraseรฑa a tu correo electrรณnico.",
+ "orText": "O",
+ "successTitle": "ยกInstrucciones de restablecimiento enviadas!",
+ "successMessage": "La informaciรณn de restablecimiento se ha enviado a tu correo electrรณnico. Por favor, verifica tu correo."
+}
diff --git a/worklenz-backend/src/public/locales/es/auth/login.json b/worklenz-backend/src/public/locales/es/auth/login.json
new file mode 100644
index 00000000..8c1697f8
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/auth/login.json
@@ -0,0 +1,27 @@
+{
+ "headerDescription": "Inicia sesiรณn en tu cuenta",
+ "emailLabel": "Correo electrรณnico",
+ "emailPlaceholder": "Ingresa tu correo electrรณnico",
+ "emailRequired": "ยกPor favor ingresa tu correo electrรณnico!",
+ "passwordLabel": "Contraseรฑa",
+ "passwordPlaceholder": "Ingresa tu contraseรฑa",
+ "passwordRequired": "ยกPor favor ingresa tu contraseรฑa!",
+ "rememberMe": "Recordarme",
+ "loginButton": "Iniciar sesiรณn",
+ "signupButton": "Registrarse",
+ "forgotPasswordButton": "ยฟOlvidaste tu contraseรฑa?",
+ "signInWithGoogleButton": "Iniciar sesiรณn con Google",
+ "successMessage": "ยกHas iniciado sesiรณn exitosamente!",
+ "dontHaveAccountText": "ยฟNo tienes una cuenta?",
+ "orText": "O",
+ "loginError": "Iniciar sesiรณn fallรณ",
+ "googleLoginError": "Iniciar sesiรณn con Google fallรณ",
+ "validationMessages": {
+ "password": "La contraseรฑa debe tener al menos 8 caracteres",
+ "email": "Por favor ingresa una direcciรณn de correo electrรณnico vรกlida"
+ },
+ "errorMessages": {
+ "loginErrorTitle": "Iniciar sesiรณn fallรณ",
+ "loginErrorMessage": "Por favor verifica tu correo electrรณnico y contraseรฑa y vuelve a intentarlo"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/es/auth/signup.json b/worklenz-backend/src/public/locales/es/auth/signup.json
new file mode 100644
index 00000000..465ff287
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/auth/signup.json
@@ -0,0 +1,29 @@
+{
+ "headerDescription": "Regรญstrate para comenzar",
+ "nameLabel": "Nombre completo",
+ "namePlaceholder": "Ingresa tu nombre completo",
+ "nameRequired": "ยกPor favor ingresa tu nombre completo!",
+ "nameMinCharacterRequired": "ยกEl nombre completo debe tener al menos 4 caracteres!",
+ "emailLabel": "Correo electrรณnico",
+ "emailPlaceholder": "Ingresa tu correo electrรณnico",
+ "emailRequired": "ยกPor favor ingresa tu correo electrรณnico!",
+ "passwordLabel": "Contraseรฑa",
+ "passwordPlaceholder": "Ingresa tu contraseรฑa",
+ "passwordRequired": "ยกPor favor ingresa tu contraseรฑa!",
+ "passwordMinCharacterRequired": "ยกLa contraseรฑa debe tener al menos 8 caracteres!",
+ "passwordPatternRequired": "ยกLa contraseรฑa no cumple con los requisitos!",
+ "strongPasswordPlaceholder": "Ingresa una contraseรฑa mรกs segura",
+ "passwordValidationAltText": "La contraseรฑa debe incluir al menos 8 caracteres con letras mayรบsculas y minรบsculas, un nรบmero y un sรญmbolo.",
+ "signupSuccessMessage": "ยกTe has registrado exitosamente!",
+ "privacyPolicyLink": "Polรญtica de Privacidad",
+ "termsOfUseLink": "Tรฉrminos de Uso",
+ "bySigningUpText": "Al registrarte, aceptas nuestra",
+ "andText": "y",
+ "signupButton": "Registrarse",
+ "signInWithGoogleButton": "Iniciar sesiรณn con Google",
+ "alreadyHaveAccountText": "ยฟYa tienes una cuenta?",
+ "loginButton": "Iniciar sesiรณn",
+ "orText": "O",
+ "reCAPTCHAVerificationError": "Error de verificaciรณn de reCAPTCHA",
+ "reCAPTCHAVerificationErrorMessage": "No pudimos verificar tu reCAPTCHA. Por favor, intรฉntalo de nuevo."
+}
diff --git a/worklenz-backend/src/public/locales/es/auth/verify-reset-email.json b/worklenz-backend/src/public/locales/es/auth/verify-reset-email.json
new file mode 100644
index 00000000..1058bc1c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/auth/verify-reset-email.json
@@ -0,0 +1,14 @@
+{
+ "title": "Verificar correo de restablecimiento",
+ "description": "Ingresa tu nueva contraseรฑa",
+ "placeholder": "Ingresa tu nueva contraseรฑa",
+ "confirmPasswordPlaceholder": "Confirma tu nueva contraseรฑa",
+ "passwordHint": "Mรญnimo 8 caracteres, con mayรบsculas y minรบsculas, un nรบmero y un sรญmbolo.",
+ "resetPasswordButton": "Restablecer contraseรฑa",
+ "orText": "O",
+ "resendResetEmail": "Reenviar correo de restablecimiento",
+ "passwordRequired": "Por favor ingresa tu nueva contraseรฑa",
+ "returnToLoginButton": "Volver al inicio de sesiรณn",
+ "confirmPasswordRequired": "Por favor confirma tu nueva contraseรฑa",
+ "passwordMismatch": "Las contraseรฑas no coinciden"
+}
diff --git a/worklenz-backend/src/public/locales/es/common.json b/worklenz-backend/src/public/locales/es/common.json
new file mode 100644
index 00000000..583e8670
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/common.json
@@ -0,0 +1,9 @@
+{
+ "login-success": "ยกInicio de sesiรณn exitoso!",
+ "login-failed": "Error al iniciar sesiรณn. Por favor verifica tus credenciales e intenta nuevamente.",
+ "signup-success": "ยกRegistro exitoso! Bienvenido a bordo.",
+ "signup-failed": "Error al registrarse. Por favor asegรบrate de llenar todos los campos requeridos e intenta nuevamente.",
+ "reconnecting": "Reconectando al servidor...",
+ "connection-lost": "Conexiรณn perdida. Intentando reconectarse...",
+ "connection-restored": "Conexiรณn restaurada. Reconectando al servidor..."
+}
diff --git a/worklenz-backend/src/public/locales/es/create-first-project-form.json b/worklenz-backend/src/public/locales/es/create-first-project-form.json
new file mode 100644
index 00000000..4382cda5
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/create-first-project-form.json
@@ -0,0 +1,13 @@
+{
+ "formTitle": "Crea tu primer proyecto",
+ "inputLabel": "ยฟEn quรฉ proyecto estรกs trabajando ahora?",
+ "or": "o",
+ "templateButton": "Importar desde plantilla",
+ "createFromTemplate": "Crear desde plantilla",
+ "goBack": "Volver",
+ "continue": "Continuar",
+ "cancel": "Cancelar",
+ "create": "Crear",
+ "templateDrawerTitle": "Seleccionar de plantillas",
+ "createProject": "Crear proyecto"
+}
diff --git a/worklenz-backend/src/public/locales/es/create-first-tasks.json b/worklenz-backend/src/public/locales/es/create-first-tasks.json
new file mode 100644
index 00000000..adca7366
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/create-first-tasks.json
@@ -0,0 +1,7 @@
+{
+ "formTitle": "Crea tu primera tarea.",
+ "inputLable": "Escribe algunas tareas que vas a hacer en",
+ "addAnother": "Agregar otra",
+ "goBack": "Volver",
+ "continue": "Continuar"
+}
diff --git a/worklenz-backend/src/public/locales/es/home.json b/worklenz-backend/src/public/locales/es/home.json
new file mode 100644
index 00000000..cfd238f9
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/home.json
@@ -0,0 +1,45 @@
+{
+ "todoList": {
+ "title": "Lista de tareas",
+ "refreshTasks": "Actualizar tareas",
+ "addTask": "+ Agregar tarea",
+ "noTasks": "Sin tareas",
+ "pressEnter": "Presiona",
+ "toCreate": "para crear.",
+ "markAsDone": "Marcar como hecho"
+ },
+ "projects": {
+ "title": "Proyectos",
+ "refreshProjects": "Actualizar proyectos",
+ "noRecentProjects": "Actualmente no estรกs asignado a ningรบn proyecto.",
+ "noFavouriteProjects": "No hay proyectos marcados como favoritos.",
+ "recent": "Recientes",
+ "favourites": "Favoritos"
+ },
+ "tasks": {
+ "assignedToMe": "Asignadas a mรญ",
+ "assignedByMe": "Asignadas por mรญ",
+ "all": "Todas",
+ "today": "Hoy",
+ "upcoming": "Prรณximas",
+ "overdue": "Vencidas",
+ "noDueDate": "Sin fecha de vencimiento",
+ "noTasks": "No hay tareas para mostrar.",
+ "addTask": "+ Agregar tarea",
+ "name": "Nombre",
+ "project": "Proyecto",
+ "status": "Estado",
+ "dueDate": "Fecha de vencimiento",
+ "dueDatePlaceholder": "Establecer fecha de vencimiento",
+ "tomorrow": "Maรฑana",
+ "nextWeek": "La semana que viene",
+ "nextMonth": "El prรณximo mes",
+ "projectRequired": "Por favor selecciona un proyecto",
+ "dueOn": "Tareas vencidas el",
+ "taskRequired": "Por favor agrega una tarea",
+ "list": "Lista",
+ "calendar": "Calendario",
+ "tasks": "Tareas",
+ "refresh": "Actualizar"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/es/invite-initial-team-members.json b/worklenz-backend/src/public/locales/es/invite-initial-team-members.json
new file mode 100644
index 00000000..87fb006c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/invite-initial-team-members.json
@@ -0,0 +1,8 @@
+{
+ "formTitle": "Invita a tu equipo a trabajar",
+ "inputLable": "Invitar por correo electrรณnico",
+ "addAnother": "Agregar otro",
+ "goBack": "Volver",
+ "continue": "Continuar",
+ "skipForNow": "Omitir por ahora"
+}
diff --git a/worklenz-backend/src/public/locales/es/kanban-board.json b/worklenz-backend/src/public/locales/es/kanban-board.json
new file mode 100644
index 00000000..6e8d5975
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/kanban-board.json
@@ -0,0 +1,30 @@
+{
+ "rename": "Renombrar",
+ "delete": "Eliminar",
+ "addTask": "Agregar tarea",
+ "addSectionButton": "Agregar secciรณn",
+ "changeCategory": "Cambiar categorรญa",
+
+ "deleteTooltip": "Eliminar",
+ "deleteConfirmationTitle": "ยฟEstรกs seguro?",
+ "deleteConfirmationOk": "Sรญ",
+ "deleteConfirmationCancel": "Cancelar",
+
+ "dueDate": "Fecha de vencimiento",
+ "cancel": "Cancelar",
+
+ "today": "Hoy",
+ "tomorrow": "Maรฑana",
+ "assignToMe": "Asignarme",
+ "archive": "Archivar",
+
+ "newTaskNamePlaceholder": "Escribe un nombre de tarea",
+ "newSubtaskNamePlaceholder": "Escribe un nombre de subtarea",
+ "untitledSection": "Secciรณn sin tรญtulo",
+ "unmapped": "Sin asignar",
+ "clickToChangeDate": "Haz clic para cambiar la fecha",
+ "noDueDate": "Sin fecha de vencimiento",
+ "save": "Guardar",
+ "clear": "Limpiar",
+ "nextWeek": "Prรณxima semana"
+}
diff --git a/worklenz-backend/src/public/locales/es/license-expired.json b/worklenz-backend/src/public/locales/es/license-expired.json
new file mode 100644
index 00000000..3cd0de2d
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/license-expired.json
@@ -0,0 +1,6 @@
+{
+ "title": "ยกTu prueba de Worklenz ha expirado!",
+ "subtitle": "Por favor actualiza ahora.",
+ "button": "Actualizar ahora",
+ "checking": "Verificando estado de la suscripciรณn..."
+}
diff --git a/worklenz-backend/src/public/locales/es/navbar.json b/worklenz-backend/src/public/locales/es/navbar.json
new file mode 100644
index 00000000..97c79d50
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/navbar.json
@@ -0,0 +1,31 @@
+{
+ "logoAlt": "Logo de Worklenz",
+ "home": "Inicio",
+ "projects": "Proyectos",
+ "schedule": "Calendario",
+ "reporting": "Informes",
+ "clients": "Clientes",
+ "teams": "Equipos",
+ "labels": "Etiquetas",
+ "jobTitles": "Cargos",
+ "upgradePlan": "Actualizar Plan",
+ "upgradePlanTooltip": "Actualizar Plan",
+ "invite": "Invitar",
+ "inviteTooltip": "Invitar miembros al equipo",
+ "switchTeamTooltip": "Cambiar equipo",
+ "help": "Ayuda",
+ "notificationTooltip": "Ver notificaciones",
+ "profileTooltip": "Ver perfil",
+ "adminCenter": "Centro de administraciรณn",
+ "settings": "Configuraciรณn",
+ "logOut": "Cerrar sesiรณn",
+ "notificationsDrawer": {
+ "read": "Notificaciones leรญdas",
+ "unread": "Notificaciones no leรญdas",
+ "markAsRead": "Marcar como leรญdo",
+ "readAndJoin": "Leer y unirse",
+ "accept": "Aceptar",
+ "acceptAndJoin": "Aceptar y unirse",
+ "noNotifications": "Sin notificaciones"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/es/organization-name-form.json b/worklenz-backend/src/public/locales/es/organization-name-form.json
new file mode 100644
index 00000000..efd60ed7
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/organization-name-form.json
@@ -0,0 +1,5 @@
+{
+ "nameYourOrganization": "Nombra tu organizaciรณn.",
+ "worklenzAccountTitle": "Elige un nombre para tu cuenta de Worklenz.",
+ "continue": "Continuar"
+}
diff --git a/worklenz-backend/src/public/locales/es/phases-drawer.json b/worklenz-backend/src/public/locales/es/phases-drawer.json
new file mode 100644
index 00000000..e961b068
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/phases-drawer.json
@@ -0,0 +1,19 @@
+{
+ "configurePhases": "Configurar fases",
+ "phaseLabel": "Etiqueta de fase",
+ "enterPhaseName": "Ingrese un nombre para la etiqueta de fase",
+ "addOption": "Agregar opciรณn",
+ "phaseOptions": "Opciones de fase:",
+ "dragToReorderPhases": "Arrastra las fases para reordenarlas. Cada fase puede tener un color diferente.",
+ "enterNewPhaseName": "Introducir nuevo nombre de fase...",
+ "addPhase": "Aรฑadir Fase",
+ "noPhasesFound": "No se encontraron fases. Crea tu primera fase arriba.",
+ "deletePhase": "Eliminar Fase",
+ "deletePhaseConfirm": "ยฟEstรกs seguro de que quieres eliminar esta fase? Esta acciรณn no se puede deshacer.",
+ "rename": "Renombrar",
+ "delete": "Eliminar",
+ "enterPhaseName": "Introducir nombre de la fase",
+ "selectColor": "Seleccionar color",
+ "managePhases": "Gestionar Fases",
+ "close": "Cerrar"
+}
diff --git a/worklenz-backend/src/public/locales/es/project-drawer.json b/worklenz-backend/src/public/locales/es/project-drawer.json
new file mode 100644
index 00000000..447ad4f1
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/project-drawer.json
@@ -0,0 +1,52 @@
+{
+ "createProject": "Crear Proyecto",
+ "editProject": "Editar Proyecto",
+ "enterCategoryName": "Ingrese un nombre para la categorรญa",
+ "hitEnterToCreate": "ยกPresiona enter para crear!",
+ "enterNotes": "Notas",
+ "youCanManageClientsUnderSettings": "Puedes gestionar clientes en Configuraciรณn",
+ "addCategory": "Agregar una categorรญa al proyecto",
+ "newCategory": "Nueva Categorรญa",
+ "notes": "Notas",
+ "startDate": "Fecha de Inicio",
+ "endDate": "Fecha de Finalizaciรณn",
+ "estimateWorkingDays": "Estimar dรญas de trabajo",
+ "estimateManDays": "Estimar dรญas de trabajo",
+ "hoursPerDay": "Horas por dรญa",
+ "create": "Crear",
+ "update": "Actualizar",
+ "delete": "Eliminar",
+ "typeToSearchClients": "Escribe para buscar clientes",
+ "projectColor": "Color del Proyecto",
+ "pleaseEnterAName": "Por favor ingresa un nombre",
+ "enterProjectName": "Ingresa el nombre del proyecto",
+ "name": "Nombre",
+ "status": "Estado",
+ "health": "Salud",
+ "category": "Categorรญa",
+ "projectManager": "Gerente de Proyecto",
+ "client": "Cliente",
+ "deleteConfirmation": "ยฟEstรกs seguro de que quieres eliminar?",
+ "deleteConfirmationDescription": "Esto eliminarรก todos los datos asociados y no se puede deshacer.",
+ "yes": "Sรญ",
+ "no": "No",
+ "createdAt": "Creado",
+ "updatedAt": "Actualizado",
+ "by": "por",
+ "add": "Agregar",
+ "asClient": "como cliente",
+ "createClient": "Crear cliente",
+ "searchInputPlaceholder": "Busca por nombre o email",
+ "hoursPerDayValidationMessage": "Las horas por dรญa deben ser un nรบmero entre 1 y 24",
+ "workingDaysValidationMessage": "Los dรญas de trabajo deben ser un nรบmero positivo",
+ "manDaysValidationMessage": "Los dรญas hombre deben ser un nรบmero positivo",
+ "noPermission": "Sin permiso",
+ "progressSettings": "Configuraciรณn de Progreso",
+ "manualProgress": "Progreso Manual",
+ "manualProgressTooltip": "Permitir actualizaciones manuales de progreso para tareas sin subtareas",
+ "weightedProgress": "Progreso Ponderado",
+ "weightedProgressTooltip": "Calcular el progreso basado en los pesos de las subtareas",
+ "timeProgress": "Progreso Basado en Tiempo",
+ "timeProgressTooltip": "Calcular el progreso basado en el tiempo estimado",
+ "enterProjectKey": "Ingresa la clave del proyecto"
+}
diff --git a/worklenz-backend/src/public/locales/es/project-view-files.json b/worklenz-backend/src/public/locales/es/project-view-files.json
new file mode 100644
index 00000000..13071a2a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/project-view-files.json
@@ -0,0 +1,14 @@
+{
+ "nameColumn": "Nombre",
+ "attachedTaskColumn": "Tarea Adjunta",
+ "sizeColumn": "Tamaรฑo",
+ "uploadedByColumn": "Subido Por",
+ "uploadedAtColumn": "Subido El",
+ "fileIconAlt": "Icono de archivo",
+ "titleDescriptionText": "Todos los archivos adjuntos a las tareas en este proyecto aparecerรกn aquรญ.",
+ "deleteConfirmationTitle": "ยฟEstรกs seguro?",
+ "deleteConfirmationOk": "Sรญ",
+ "deleteConfirmationCancel": "Cancelar",
+ "segmentedTooltip": "ยกPrรณximamente! Cambiar entre vista de lista y vista de miniaturas.",
+ "emptyText": "No hay archivos adjuntos en el proyecto."
+}
diff --git a/worklenz-backend/src/public/locales/es/project-view-insights.json b/worklenz-backend/src/public/locales/es/project-view-insights.json
new file mode 100644
index 00000000..bd60b58e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/project-view-insights.json
@@ -0,0 +1,41 @@
+{
+ "overview": {
+ "title": "Resumen",
+ "statusOverview": "Resumen de Estado",
+ "priorityOverview": "Resumen de Prioridad",
+ "lastUpdatedTasks": "รltimas Tareas Actualizadas"
+ },
+ "members": {
+ "title": "Miembros",
+ "tooltip": "Miembros",
+ "tasksByMembers": "Tareas por miembros",
+ "tasksByMembersTooltip": "Tareas por miembros",
+ "name": "Nombre",
+ "taskCount": "Cantidad de Tareas",
+ "contribution": "Contribuciรณn",
+ "completed": "Completadas",
+ "incomplete": "Incompletas",
+ "overdue": "Atrasadas",
+ "progress": "Progreso"
+ },
+ "tasks": {
+ "overdueTasks": "Tareas Atrasadas",
+ "overLoggedTasks": "Tareas con Exceso de Tiempo",
+ "tasksCompletedEarly": "Tareas completadas antes de tiempo",
+ "tasksCompletedLate": "Tareas completadas tarde",
+ "overLoggedTasksTooltip": "Tareas que tienen tiempo registrado mรกs allรก de su tiempo estimado",
+ "overdueTasksTooltip": "Tareas que estรกn mรกs allรก de su fecha lรญmite"
+ },
+ "common": {
+ "seeAll": "Ver todo",
+ "totalLoggedHours": "Total de horas registradas",
+ "totalEstimation": "Estimaciรณn total",
+ "completedTasks": "Tareas completadas",
+ "incompleteTasks": "Tareas incompletas",
+ "overdueTasks": "Tareas atrasadas",
+ "overdueTasksTooltip": "Tareas que estรกn mรกs allรก de su fecha lรญmite",
+ "totalLoggedHoursTooltip": "Estimaciรณn de tareas y tiempo registrado para las tareas.",
+ "includeArchivedTasks": "Incluir Tareas Archivadas",
+ "export": "Exportar"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/es/project-view-members.json b/worklenz-backend/src/public/locales/es/project-view-members.json
new file mode 100644
index 00000000..95a8d943
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/project-view-members.json
@@ -0,0 +1,17 @@
+{
+ "nameColumn": "Nombre",
+ "jobTitleColumn": "Cargo",
+ "emailColumn": "Correo",
+ "tasksColumn": "Tareas",
+ "taskProgressColumn": "Progreso de Tareas",
+ "accessColumn": "Acceso",
+ "fileIconAlt": "Icono de archivo",
+ "deleteConfirmationTitle": "ยฟEstรกs seguro?",
+ "deleteConfirmationOk": "Sรญ",
+ "deleteConfirmationCancel": "Cancelar",
+ "refreshButtonTooltip": "Actualizar miembros",
+ "deleteButtonTooltip": "Eliminar del proyecto",
+ "memberCount": "Miembro",
+ "membersCountPlural": "Miembros",
+ "emptyText": "No hay archivos adjuntos en el proyecto."
+}
diff --git a/worklenz-backend/src/public/locales/es/project-view-updates.json b/worklenz-backend/src/public/locales/es/project-view-updates.json
new file mode 100644
index 00000000..d565fcfc
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/project-view-updates.json
@@ -0,0 +1,6 @@
+{
+ "inputPlaceholder": "Agregar un comentario..",
+ "addButton": "Agregar",
+ "cancelButton": "Cancelar",
+ "deleteButton": "Eliminar"
+}
diff --git a/worklenz-backend/src/public/locales/es/project-view.json b/worklenz-backend/src/public/locales/es/project-view.json
new file mode 100644
index 00000000..a4c12d9f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/project-view.json
@@ -0,0 +1,14 @@
+{
+ "taskList": "Lista de Tareas",
+ "board": "Tablero Kanban",
+ "insights": "Anรกlisis",
+ "files": "Archivos",
+ "members": "Miembros",
+ "updates": "Actualizaciones",
+ "projectView": "Vista del Proyecto",
+ "loading": "Cargando proyecto...",
+ "error": "Error al cargar el proyecto",
+ "pinnedTab": "Fijado como pestaรฑa predeterminada",
+ "pinTab": "Fijar como pestaรฑa predeterminada",
+ "unpinTab": "Desfijar pestaรฑa predeterminada"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/es/project-view/import-task-templates.json b/worklenz-backend/src/public/locales/es/project-view/import-task-templates.json
new file mode 100644
index 00000000..7be1539b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/project-view/import-task-templates.json
@@ -0,0 +1,11 @@
+{
+ "importTaskTemplate": "Importar plantilla de tarea",
+ "templateName": "Nombre de la plantilla",
+ "templateDescription": "Descripciรณn de la plantilla",
+ "selectedTasks": "Tareas seleccionadas",
+ "tasks": "Tareas",
+ "templates": "Plantillas",
+ "remove": "Eliminar",
+ "cancel": "Cancelar",
+ "import": "Importar"
+}
diff --git a/worklenz-backend/src/public/locales/es/project-view/project-member-drawer.json b/worklenz-backend/src/public/locales/es/project-view/project-member-drawer.json
new file mode 100644
index 00000000..ab7570fd
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/project-view/project-member-drawer.json
@@ -0,0 +1,7 @@
+{
+ "title": "Miembros del Proyecto",
+ "searchLabel": "Agregar miembros ingresando su nombre o correo electrรณnico",
+ "searchPlaceholder": "Escriba nombre o correo electrรณnico",
+ "inviteAsAMember": "Invitar como miembro",
+ "inviteNewMemberByEmail": "Invitar nuevo miembro por correo electrรณnico"
+}
diff --git a/worklenz-backend/src/public/locales/es/project-view/project-view-header.json b/worklenz-backend/src/public/locales/es/project-view/project-view-header.json
new file mode 100644
index 00000000..0215b89c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/project-view/project-view-header.json
@@ -0,0 +1,30 @@
+{
+ "importTasks": "Importar tareas",
+ "importTask": "Importar tarea",
+ "createTask": "Crear tarea",
+ "settings": "Configuraciรณn",
+ "subscribe": "Suscribirse",
+ "unsubscribe": "Cancelar suscripciรณn",
+ "deleteProject": "Eliminar proyecto",
+ "startDate": "Fecha de inicio",
+ "endDate": "Fecha de finalizaciรณn",
+ "projectSettings": "Configuraciรณn del proyecto",
+ "projectSummary": "Resumen del proyecto",
+ "receiveProjectSummary": "Recibe un resumen del proyecto cada noche.",
+ "refreshProject": "Actualizar proyecto",
+ "saveAsTemplate": "Guardar como plantilla",
+ "invite": "Invitar",
+ "share": "Compartir",
+ "subscribeTooltip": "Suscribirse a notificaciones del proyecto",
+ "unsubscribeTooltip": "Cancelar suscripciรณn a notificaciones del proyecto",
+ "refreshTooltip": "Actualizar datos del proyecto",
+ "settingsTooltip": "Abrir configuraciรณn del proyecto",
+ "saveAsTemplateTooltip": "Guardar este proyecto como plantilla",
+ "inviteTooltip": "Invitar miembros del equipo a este proyecto",
+ "createTaskTooltip": "Crear una nueva tarea",
+ "importTaskTooltip": "Importar tarea desde plantilla",
+ "navigateBackTooltip": "Volver a la lista de proyectos",
+ "projectStatusTooltip": "Estado del proyecto",
+ "projectDatesInfo": "Informaciรณn de cronograma del proyecto",
+ "projectCategoryTooltip": "Categorรญa del proyecto"
+}
diff --git a/worklenz-backend/src/public/locales/es/project-view/save-as-template.json b/worklenz-backend/src/public/locales/es/project-view/save-as-template.json
new file mode 100644
index 00000000..4d7e9354
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/project-view/save-as-template.json
@@ -0,0 +1,27 @@
+{
+ "title": "Guardar como Plantilla",
+ "templateName": "Nombre de la Plantilla",
+ "includes": "ยฟQuรฉ se debe incluir en la plantilla del proyecto?",
+ "includesOptions": {
+ "statuses": "Estados",
+ "phases": "Fases",
+ "labels": "Etiquetas"
+ },
+ "taskIncludes": "ยฟQuรฉ se debe incluir en la plantilla de las tareas?",
+ "taskIncludesOptions": {
+ "statuses": "Estados",
+ "phases": "Fases",
+ "labels": "Etiquetas",
+ "name": "Nombre",
+ "priority": "Prioridad",
+ "status": "Estado",
+ "phase": "Fase",
+ "label": "Etiqueta",
+ "timeEstimate": "Estimaciรณn de Tiempo",
+ "description": "Descripciรณn",
+ "subTasks": "Sub Tasks"
+ },
+ "cancel": "Cancel",
+ "save": "Save",
+ "templateNamePlaceholder": "Enter template name"
+}
diff --git a/worklenz-backend/src/public/locales/es/reporting-members-drawer.json b/worklenz-backend/src/public/locales/es/reporting-members-drawer.json
new file mode 100644
index 00000000..fb8ecf20
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/reporting-members-drawer.json
@@ -0,0 +1,90 @@
+{
+ "exportButton": "Exportar",
+ "timeLogsButton": "Registros de Tiempo",
+ "activityLogsButton": "Registros de Actividad",
+ "tasksButton": "Tareas",
+ "searchByNameInputPlaceholder": "Buscar por nombre",
+
+ "overviewTab": "Resumen",
+ "timeLogsTab": "Registros de Tiempo",
+ "activityLogsTab": "Registros de Actividad",
+ "tasksTab": "Tareas",
+
+ "projectsText": "Proyectos",
+ "totalTasksText": "Total de Tareas",
+ "assignedTasksText": "Tareas Asignadas",
+ "completedTasksText": "Tareas Completadas",
+ "ongoingTasksText": "Tareas en Curso",
+ "overdueTasksText": "Tareas Atrasadas",
+ "loggedHoursText": "Horas Registradas",
+
+ "tasksText": "Tareas",
+ "allText": "Todo",
+
+ "tasksByProjectsText": "Tareas por Proyectos",
+ "tasksByStatusText": "Tareas por Estado",
+ "tasksByPriorityText": "Tareas por Prioridad",
+
+ "todoText": "Por Hacer",
+ "doingText": "Haciendo",
+ "doneText": "Hecho",
+ "lowText": "Baja",
+ "mediumText": "Media",
+ "highText": "Alta",
+
+ "billableButton": "Facturable",
+ "billableText": "Facturable",
+ "nonBillableText": "No Facturable",
+
+ "timeLogsEmptyPlaceholder": "No hay registros de tiempo para mostrar",
+ "loggedText": "Registrado",
+ "forText": "para",
+ "inText": "en",
+ "updatedText": "Actualizado",
+ "fromText": "Desde",
+ "toText": "hasta",
+ "withinText": "dentro de",
+
+ "activityLogsEmptyPlaceholder": "No hay registros de actividad para mostrar",
+
+ "filterByText": "Filtrar por:",
+ "selectProjectPlaceholder": "Seleccionar Proyecto",
+
+ "taskColumn": "Tarea",
+ "nameColumn": "Nombre",
+ "projectColumn": "Proyecto",
+ "statusColumn": "Estado",
+ "priorityColumn": "Prioridad",
+ "dueDateColumn": "Fecha de Vencimiento",
+ "completedDateColumn": "Fecha de Finalizaciรณn",
+ "estimatedTimeColumn": "Tiempo Estimado",
+ "loggedTimeColumn": "Tiempo Registrado",
+ "overloggedTimeColumn": "Tiempo Excedido",
+ "daysLeftColumn": "Dรญas Restantes/Atrasados",
+ "startDateColumn": "Fecha de Inicio",
+ "endDateColumn": "Fecha de Fin",
+ "actualTimeColumn": "Tiempo Real",
+ "projectHealthColumn": "Salud del Proyecto",
+ "categoryColumn": "Categorรญa",
+ "projectManagerColumn": "Gerente de Proyecto",
+
+ "tasksStatsOverviewDrawerTitle": "Tareas de",
+ "projectsStatsOverviewDrawerTitle": "Proyectos de",
+
+ "cancelledText": "Cancelado",
+ "blockedText": "Bloqueado",
+ "onHoldText": "En Espera",
+ "proposedText": "Propuesto",
+ "inPlanningText": "En Planificaciรณn",
+ "inProgressText": "En Progreso",
+ "completedText": "Completado",
+ "continuousText": "Continuo",
+
+ "daysLeftText": "dรญas restantes",
+ "daysOverdueText": "dรญas de retraso",
+
+ "notSetText": "No Establecido",
+ "needsAttentionText": "Necesita Atenciรณn",
+ "atRiskText": "En Riesgo",
+ "goodText": "Bien"
+}
diff --git a/worklenz-backend/src/public/locales/es/reporting-members.json b/worklenz-backend/src/public/locales/es/reporting-members.json
new file mode 100644
index 00000000..d87cafb8
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/reporting-members.json
@@ -0,0 +1,35 @@
+{
+ "yesterdayText": "Ayer",
+ "lastSevenDaysText": "รltimos 7 Dรญas",
+ "lastWeekText": "รltima Semana",
+ "lastThirtyDaysText": "รltimos 30 Dรญas",
+ "lastMonthText": "รltimo Mes",
+ "lastThreeMonthsText": "รltimos 3 Meses",
+ "allTimeText": "Todo el Tiempo",
+ "customRangeText": "Rango personalizado",
+ "startDateInputPlaceholder": "Fecha de inicio",
+ "EndDateInputPlaceholder": "Fecha final",
+ "filterButton": "Filtrar",
+
+ "membersTitle": "Miembros",
+ "includeArchivedButton": "Incluir Proyectos Archivados",
+ "exportButton": "Exportar",
+ "excelButton": "Excel",
+ "searchByNameInputPlaceholder": "Buscar por nombre",
+
+ "memberColumn": "Miembro",
+ "tasksProgressColumn": "Progreso de Tareas",
+ "tasksAssignedColumn": "Tareas Asignadas",
+ "completedTasksColumn": "Tareas Completadas",
+ "overdueTasksColumn": "Tareas Atrasadas",
+ "ongoingTasksColumn": "Tareas en Curso",
+
+ "tasksAssignedColumnTooltip": "Tareas asignadas en el rango de fechas seleccionado",
+ "overdueTasksColumnTooltip": "Tareas atrasadas al final del rango de fechas seleccionado",
+ "completedTasksColumnTooltip": "Tareas completadas en el rango de fechas seleccionado",
+ "ongoingTasksColumnTooltip": "Tareas iniciadas aรบn no completadas",
+
+ "todoText": "Por Hacer",
+ "doingText": "Haciendo",
+ "doneText": "Hecho"
+}
diff --git a/worklenz-backend/src/public/locales/es/reporting-overview-drawer.json b/worklenz-backend/src/public/locales/es/reporting-overview-drawer.json
new file mode 100644
index 00000000..fce8e554
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/reporting-overview-drawer.json
@@ -0,0 +1,39 @@
+{
+ "exportButton": "Exportar",
+ "projectsButton": "Proyectos",
+ "membersButton": "Miembros",
+ "searchByNameInputPlaceholder": "Buscar por nombre",
+
+ "overviewTab": "Resumen",
+ "projectsTab": "Proyectos",
+ "membersTab": "Miembros",
+
+ "projectsByStatusText": "Proyectos por Estado",
+ "projectsByCategoryText": "Proyectos por Categorรญa",
+ "projectsByHealthText": "Proyectos por Salud",
+
+ "projectsText": "Proyectos",
+ "allText": "Todo",
+
+ "cancelledText": "Cancelado",
+ "blockedText": "Bloqueado",
+ "onHoldText": "En Espera",
+ "proposedText": "Propuesto",
+ "inPlanningText": "En Planificaciรณn",
+ "inProgressText": "En Progreso",
+ "completedText": "Completado",
+ "continuousText": "Continuo",
+
+ "notSetText": "No Establecido",
+ "needsAttentionText": "Necesita Atenciรณn",
+ "atRiskText": "En Riesgo",
+ "goodText": "Bien",
+
+ "nameColumn": "Nombre",
+ "emailColumn": "Correo",
+ "projectsColumn": "Proyectos",
+ "tasksColumn": "Tareas",
+ "overdueTasksColumn": "Tareas Atrasadas",
+ "completedTasksColumn": "Tareas Completadas",
+ "ongoingTasksColumn": "Tareas en Curso"
+}
diff --git a/worklenz-backend/src/public/locales/es/reporting-overview.json b/worklenz-backend/src/public/locales/es/reporting-overview.json
new file mode 100644
index 00000000..3f18fbed
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/reporting-overview.json
@@ -0,0 +1,25 @@
+{
+ "overviewTitle": "Resumen",
+ "includeArchivedButton": "Incluir Proyectos Archivados",
+
+ "teamCount": "Equipo",
+ "teamCountPlural": "Equipos",
+ "projectCount": "Proyecto",
+ "projectCountPlural": "Proyectos",
+ "memberCount": "Miembro",
+ "memberCountPlural": "Miembros",
+ "activeProjectCount": "Proyecto Activo",
+ "activeProjectCountPlural": "Proyectos Activos",
+ "overdueProjectCount": "Proyecto Atrasado",
+ "overdueProjectCountPlural": "Proyectos Atrasados",
+ "unassignedMemberCount": "Miembro Sin Asignar",
+ "unassignedMemberCountPlural": "Miembros Sin Asignar",
+ "memberWithOverdueTaskCount": "Miembro Con Tarea Atrasada",
+ "memberWithOverdueTaskCountPlural": "Miembros Con Tareas Atrasadas",
+
+ "teamsText": "Equipos",
+
+ "nameColumn": "Nombre",
+ "projectsColumn": "Proyectos",
+ "membersColumn": "Miembros"
+}
diff --git a/worklenz-backend/src/public/locales/es/reporting-projects-drawer.json b/worklenz-backend/src/public/locales/es/reporting-projects-drawer.json
new file mode 100644
index 00000000..1e056a29
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/reporting-projects-drawer.json
@@ -0,0 +1,59 @@
+{
+ "exportButton": "Exportar",
+ "membersButton": "Miembros",
+ "tasksButton": "Tareas",
+ "searchByNameInputPlaceholder": "Buscar por nombre",
+
+ "overviewTab": "Resumen",
+ "membersTab": "Miembros",
+ "tasksTab": "Tareas",
+
+ "completedTasksText": "Tareas Completadas",
+ "incompleteTasksText": "Tareas Incompletas",
+ "overdueTasksText": "Tareas Atrasadas",
+ "allocatedHoursText": "Horas Asignadas",
+ "loggedHoursText": "Horas Registradas",
+
+ "tasksText": "Tareas",
+ "allText": "Todos",
+
+ "tasksByStatusText": "Tareas por Estado",
+ "tasksByPriorityText": "Tareas por Prioridad",
+ "tasksByDueDateText": "Tareas por Fecha de Vencimiento",
+
+ "todoText": "Por Hacer",
+ "doingText": "En Proceso",
+ "doneText": "Hecho",
+ "lowText": "Baja",
+ "mediumText": "Media",
+ "highText": "Alta",
+ "completedText": "Completado",
+ "upcomingText": "Prรณximo",
+ "overdueText": "Atrasado",
+ "noDueDateText": "Sin Fecha de Vencimiento",
+
+ "nameColumn": "Nombre",
+ "tasksCountColumn": "Cantidad de Tareas",
+ "completedTasksColumn": "Tareas Completadas",
+ "incompleteTasksColumn": "Tareas Incompletas",
+ "overdueTasksColumn": "Tareas Atrasadas",
+ "contributionColumn": "Contribuciรณn",
+ "progressColumn": "Progreso",
+ "loggedTimeColumn": "Tiempo Registrado",
+ "taskColumn": "Tarea",
+ "projectColumn": "Proyecto",
+ "statusColumn": "Estado",
+ "priorityColumn": "Prioridad",
+ "phaseColumn": "Fase",
+ "dueDateColumn": "Fecha de Vencimiento",
+ "completedDateColumn": "Fecha de Finalizaciรณn",
+ "estimatedTimeColumn": "Tiempo Estimado",
+ "overloggedTimeColumn": "Tiempo Excedido",
+ "completedOnColumn": "Completado El",
+ "daysOverdueColumn": "Dรญas de Retraso",
+
+ "groupByText": "Agrupar Por:",
+ "statusText": "Estado",
+ "priorityText": "Prioridad",
+ "phaseText": "Fase"
+}
diff --git a/worklenz-backend/src/public/locales/es/reporting-projects-filters.json b/worklenz-backend/src/public/locales/es/reporting-projects-filters.json
new file mode 100644
index 00000000..1a4df4af
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/reporting-projects-filters.json
@@ -0,0 +1,35 @@
+{
+ "searchByNamePlaceholder": "Buscar por nombre",
+ "searchByCategoryPlaceholder": "Buscar por categorรญa",
+
+ "statusText": "Estado",
+ "healthText": "Salud",
+ "categoryText": "Categorรญa",
+ "projectManagerText": "Gerente de Proyecto",
+ "showFieldsText": "Mostrar campos",
+
+ "cancelledText": "Cancelado",
+ "blockedText": "Bloqueado",
+ "onHoldText": "En Espera",
+ "proposedText": "Propuesto",
+ "inPlanningText": "En Planificaciรณn",
+ "inProgressText": "En Progreso",
+ "completedText": "Completado",
+ "continuousText": "Continuo",
+
+ "notSetText": "No Establecido",
+ "needsAttentionText": "Necesita Atenciรณn",
+ "atRiskText": "En Riesgo",
+ "goodText": "Bien",
+
+ "nameText": "Proyecto",
+ "estimatedVsActualText": "Estimado vs Real",
+ "tasksProgressText": "Progreso de Tareas",
+ "lastActivityText": "รltima Actividad",
+ "datesText": "Fechas de Inicio/Fin",
+ "daysLeftText": "Dรญas Restantes/Atrasados",
+ "projectHealthText": "Salud del Proyecto",
+ "projectUpdateText": "Actualizaciรณn del Proyecto",
+ "clientText": "Cliente",
+ "teamText": "Equipo"
+}
diff --git a/worklenz-backend/src/public/locales/es/reporting-projects.json b/worklenz-backend/src/public/locales/es/reporting-projects.json
new file mode 100644
index 00000000..fbd9283f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/reporting-projects.json
@@ -0,0 +1,52 @@
+{
+ "projectCount": "Proyecto",
+ "projectCountPlural": "Proyectos",
+ "includeArchivedButton": "Incluir Proyectos Archivados",
+ "exportButton": "Exportar",
+ "excelButton": "Excel",
+
+ "projectColumn": "Proyecto",
+ "estimatedVsActualColumn": "Estimado vs Real",
+ "tasksProgressColumn": "Progreso de Tareas",
+ "lastActivityColumn": "รltima Actividad",
+ "statusColumn": "Estado",
+ "datesColumn": "Fechas Inicio/Fin",
+ "daysLeftColumn": "Dรญas Restantes/Atrasados",
+ "projectHealthColumn": "Salud del Proyecto",
+ "categoryColumn": "Categorรญa",
+ "projectUpdateColumn": "Actualizaciรณn del Proyecto",
+ "clientColumn": "Cliente",
+ "teamColumn": "Equipo",
+ "projectManagerColumn": "Gerente de Proyecto",
+
+ "openButton": "Abrir",
+
+ "estimatedText": "Estimado",
+ "actualText": "Real",
+
+ "todoText": "Por Hacer",
+ "doingText": "En Proceso",
+ "doneText": "Terminado",
+
+ "cancelledText": "Cancelado",
+ "blockedText": "Bloqueado",
+ "onHoldText": "En Espera",
+ "proposedText": "Propuesto",
+ "inPlanningText": "En Planificaciรณn",
+ "inProgressText": "En Progreso",
+ "completedText": "Completado",
+ "continuousText": "Continuo",
+
+ "daysLeftText": "dรญas restantes",
+ "dayLeftText": "dรญa restante",
+ "daysOverdueText": "dรญas de retraso",
+
+ "notSetText": "No Establecido",
+ "needsAttentionText": "Necesita Atenciรณn",
+ "atRiskText": "En Riesgo",
+ "goodText": "Bien",
+
+ "setCategoryText": "Establecer Categorรญa",
+ "searchByNameInputPlaceholder": "Buscar por nombre",
+ "todayText": "Hoy"
+}
diff --git a/worklenz-backend/src/public/locales/es/reporting-sidebar.json b/worklenz-backend/src/public/locales/es/reporting-sidebar.json
new file mode 100644
index 00000000..d5e89788
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/reporting-sidebar.json
@@ -0,0 +1,8 @@
+{
+ "overviewText": "Resumen",
+ "projectsText": "Proyectos",
+ "membersText": "Miembros",
+ "timeReportsText": "Informes de Tiempo",
+ "estimateVsActualText": "Estimado vs Real",
+ "currentOrganizationTooltip": "Organizaciรณn actual"
+}
diff --git a/worklenz-backend/src/public/locales/es/schedule.json b/worklenz-backend/src/public/locales/es/schedule.json
new file mode 100644
index 00000000..5b24c1f4
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/schedule.json
@@ -0,0 +1,39 @@
+{
+ "today": "Hoy",
+ "week": "Semana",
+ "month": "Mes",
+
+ "settings": "Configuraciรณn",
+ "workingDays": "Dรญas laborables",
+ "monday": "Lunes",
+ "tuesday": "Martes",
+ "wednesday": "Miรฉrcoles",
+ "thursday": "Jueves",
+ "friday": "Viernes",
+ "saturday": "Sรกbado",
+ "sunday": "Domingo",
+ "workingHours": "Horas laborables",
+ "hours": "horas",
+ "saveButton": "Guardar",
+
+ "totalAllocation": "Asignaciรณn Total",
+ "timeLogged": "Tiempo Registrado",
+ "remainingTime": "Tiempo Restante",
+ "total": "Total",
+ "perDay": "Por Dรญa",
+ "tasks": "tareas",
+ "startDate": "Fecha de Inicio",
+ "endDate": "Fecha de Fin",
+
+ "hoursPerDay": "Horas Por Dรญa",
+ "totalHours": "Horas Totales",
+ "deleteButton": "Eliminar",
+ "cancelButton": "Cancelar",
+
+ "tabTitle": "Tarea sin Fechas de Inicio y Fin",
+
+ "allocatedTime": "Tiempo Asignado",
+ "totalLogged": "Total Registrado",
+ "loggedBillable": "Registrado Facturable",
+ "loggedNonBillable": "Registrado No Facturable"
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/appearance.json b/worklenz-backend/src/public/locales/es/settings/appearance.json
new file mode 100644
index 00000000..d6b196da
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/appearance.json
@@ -0,0 +1,5 @@
+{
+ "title": "Apariencia",
+ "darkMode": "Modo Oscuro",
+ "darkModeDescription": "Cambia entre el modo claro y oscuro para personalizar tu experiencia visual."
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/categories.json b/worklenz-backend/src/public/locales/es/settings/categories.json
new file mode 100644
index 00000000..417e17dd
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/categories.json
@@ -0,0 +1,10 @@
+{
+ "categoryColumn": "Category",
+ "deleteConfirmationTitle": "Are you sure?",
+ "deleteConfirmationOk": "Yes",
+ "deleteConfirmationCancel": "Cancel",
+ "associatedTaskColumn": "Associated Task",
+ "searchPlaceholder": "Search by name",
+ "emptyText": "Categories can be created while updating or creating projects.",
+ "colorChangeTooltip": "Click to change color"
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/change-password.json b/worklenz-backend/src/public/locales/es/settings/change-password.json
new file mode 100644
index 00000000..e52b9aef
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/change-password.json
@@ -0,0 +1,15 @@
+{
+ "title": "Cambiar Contraseรฑa",
+ "currentPassword": "Contraseรฑa Actual",
+ "newPassword": "Nueva Contraseรฑa",
+ "confirmPassword": "Confirmar Contraseรฑa",
+ "currentPasswordPlaceholder": "Introduce tu contraseรฑa actual",
+ "newPasswordPlaceholder": "Nueva Contraseรฑa",
+ "confirmPasswordPlaceholder": "Confirmar Contraseรฑa",
+ "currentPasswordRequired": "ยกPor favor, introduce tu contraseรฑa actual!",
+ "newPasswordRequired": "ยกPor favor, introduce tu nueva contraseรฑa!",
+ "passwordValidationError": "La contraseรฑa debe tener al menos 8 caracteres con una letra mayรบscula, un nรบmero y un sรญmbolo.",
+ "passwordMismatch": "ยกLas contraseรฑas no coinciden!",
+ "passwordRequirements": "La nueva contraseรฑa debe tener un mรญnimo de 8 caracteres, con una letra mayรบscula, un nรบmero y un sรญmbolo.",
+ "updateButton": "Actualizar Contraseรฑa"
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/clients.json b/worklenz-backend/src/public/locales/es/settings/clients.json
new file mode 100644
index 00000000..ca206be1
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/clients.json
@@ -0,0 +1,22 @@
+{
+ "nameColumn": "Nombre",
+ "projectColumn": "Proyecto",
+ "noProjectsAvailable": "No hay proyectos disponibles",
+ "deleteConfirmationTitle": "ยฟEstรกs seguro?",
+ "deleteConfirmationOk": "Sรญ",
+ "deleteConfirmationCancel": "Cancelar",
+ "searchPlaceholder": "Buscar por nombre",
+ "createClient": "Crear Cliente",
+ "pinTooltip": "Haz clic para fijar esto en el menรบ principal",
+ "createClientDrawerTitle": "Crear Cliente",
+ "updateClientDrawerTitle": "Actualizar Cliente",
+ "nameLabel": "Nombre",
+ "namePlaceholder": "Nombre",
+ "nameRequiredError": "Por favor ingresa un nombre",
+ "createButton": "Crear",
+ "updateButton": "Actualizar",
+ "createClientSuccessMessage": "ยกCliente creado exitosamente!",
+ "createClientErrorMessage": "ยกError al crear el cliente!",
+ "updateClientSuccessMessage": "ยกCliente actualizado exitosamente!",
+ "updateClientErrorMessage": "ยกError al actualizar el cliente!"
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/job-titles.json b/worklenz-backend/src/public/locales/es/settings/job-titles.json
new file mode 100644
index 00000000..1b892d72
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/job-titles.json
@@ -0,0 +1,20 @@
+{
+ "nameColumn": "Nombre",
+ "deleteConfirmationTitle": "ยฟEstรกs seguro?",
+ "deleteConfirmationOk": "Sรญ",
+ "deleteConfirmationCancel": "Cancelar",
+ "searchPlaceholder": "Buscar por nombre",
+ "createJobTitleButton": "Crear Cargo",
+ "pinTooltip": "Haz clic para fijar esto en el menรบ principal",
+ "createJobTitleDrawerTitle": "Crear Cargo",
+ "updateJobTitleDrawerTitle": "Actualizar Cargo",
+ "nameLabel": "Nombre",
+ "namePlaceholder": "Nombre",
+ "nameRequiredError": "Por favor ingresa un nombre",
+ "createButton": "Crear",
+ "updateButton": "Actualizar",
+ "createJobTitleSuccessMessage": "ยกCargo creado exitosamente!",
+ "createJobTitleErrorMessage": "ยกError al crear el cargo!",
+ "updateJobTitleSuccessMessage": "ยกCargo actualizado exitosamente!",
+ "updateJobTitleErrorMessage": "ยกError al actualizar el cargo!"
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/labels.json b/worklenz-backend/src/public/locales/es/settings/labels.json
new file mode 100644
index 00000000..22cd9532
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/labels.json
@@ -0,0 +1,11 @@
+{
+ "labelColumn": "Etiqueta",
+ "deleteConfirmationTitle": "ยฟEstรกs seguro?",
+ "deleteConfirmationOk": "Sรญ",
+ "deleteConfirmationCancel": "Cancelar",
+ "associatedTaskColumn": "Cantidad de Tareas Asociadas",
+ "searchPlaceholder": "Buscar por nombre",
+ "emptyText": "Las etiquetas se pueden crear al actualizar o crear tareas.",
+ "pinTooltip": "Haz clic para fijar esto en el menรบ principal",
+ "colorChangeTooltip": "Haz clic para cambiar el color"
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/language.json b/worklenz-backend/src/public/locales/es/settings/language.json
new file mode 100644
index 00000000..e07fd933
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/language.json
@@ -0,0 +1,7 @@
+{
+ "language": "Idioma",
+ "language_required": "El idioma es requerido",
+ "time_zone": "Zona horaria",
+ "time_zone_required": "La zona horaria es requerida",
+ "save_changes": "Guardar cambios"
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/notifications.json b/worklenz-backend/src/public/locales/es/settings/notifications.json
new file mode 100644
index 00000000..c7a5af22
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/notifications.json
@@ -0,0 +1,10 @@
+{
+ "emailTitle": "Enviarme notificaciones por correo electrรณnico",
+ "emailDescription": "Esto incluye nuevas asignaciones de tareas",
+ "dailyDigestTitle": "Enviarme un resumen diario",
+ "dailyDigestDescription": "Cada tarde, recibirรกs un resumen de la actividad reciente en las tareas.",
+ "popupTitle": "Mostrar notificaciones emergentes en mi computadora cuando Worklenz estรฉ abierto",
+ "popupDescription": "Las notificaciones emergentes pueden ser desactivadas por tu navegador. Cambia la configuraciรณn de tu navegador para permitirlas.",
+ "unreadItemsTitle": "Mostrar el nรบmero de elementos no leรญdos",
+ "unreadItemsDescription": "Verรกs contadores para cada notificaciรณn."
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/profile.json b/worklenz-backend/src/public/locales/es/settings/profile.json
new file mode 100644
index 00000000..1a1698c8
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/profile.json
@@ -0,0 +1,14 @@
+{
+ "uploadError": "ยกSolo puedes subir archivos JPG/PNG!",
+ "uploadSizeError": "ยกLa imagen debe ser menor de 2MB!",
+ "upload": "Subir",
+ "nameLabel": "Nombre",
+ "nameRequiredError": "El nombre es obligatorio",
+ "emailLabel": "Correo electrรณnico",
+ "emailRequiredError": "El correo electrรณnico es obligatorio",
+ "saveChanges": "Guardar cambios",
+ "profileJoinedText": "Se uniรณ hace un mes",
+ "profileLastUpdatedText": "รltima actualizaciรณn hace un mes",
+ "avatarTooltip": "Haz clic para subir un avatar",
+ "title": "Configuraciรณn del Perfil"
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/project-templates.json b/worklenz-backend/src/public/locales/es/settings/project-templates.json
new file mode 100644
index 00000000..045f2240
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/project-templates.json
@@ -0,0 +1,8 @@
+{
+ "nameColumn": "Nombre",
+ "editToolTip": "Editar",
+ "deleteToolTip": "Eliminar",
+ "confirmText": "ยฟEstรกs seguro?",
+ "okText": "Sรญ",
+ "cancelText": "Cancelar"
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/sidebar.json b/worklenz-backend/src/public/locales/es/settings/sidebar.json
new file mode 100644
index 00000000..3793e77f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/sidebar.json
@@ -0,0 +1,15 @@
+{
+ "profile": "Perfil",
+ "notifications": "Notificaciones",
+ "clients": "Clientes",
+ "job-titles": "Tรญtulos de trabajo",
+ "labels": "Etiquetas",
+ "categories": "Categorรญas",
+ "project-templates": "Plantillas de proyectos",
+ "task-templates": "Plantillas de tareas",
+ "team-members": "Miembros del equipo",
+ "teams": "Equipos",
+ "change-password": "Cambiar contraseรฑa",
+ "language-and-region": "Idioma y regiรณn",
+ "appearance": "Apariencia"
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/task-templates.json b/worklenz-backend/src/public/locales/es/settings/task-templates.json
new file mode 100644
index 00000000..fbdc3c81
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/task-templates.json
@@ -0,0 +1,9 @@
+{
+ "nameColumn": "Nombre",
+ "createdColumn": "Creado",
+ "editToolTip": "Editar",
+ "deleteToolTip": "Eliminar",
+ "confirmText": "ยฟEstรกs seguro?",
+ "okText": "Sรญ",
+ "cancelText": "Cancelar"
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/team-members.json b/worklenz-backend/src/public/locales/es/settings/team-members.json
new file mode 100644
index 00000000..1000bf98
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/team-members.json
@@ -0,0 +1,47 @@
+{
+ "title": "Miembros del Equipo",
+ "nameColumn": "Nombre",
+ "projectsColumn": "Proyectos",
+ "emailColumn": "Correo electrรณnico",
+ "teamAccessColumn": "Acceso al equipo",
+ "memberCount": "Miembro",
+ "membersCountPlural": "Miembros",
+ "searchPlaceholder": "Buscar miembros por nombre",
+ "pinTooltip": "Actualizar lista de miembros",
+ "addMemberButton": "Agregar nuevo miembro",
+ "editTooltip": "Editar miembro",
+ "deactivateTooltip": "Desactivar miembro",
+ "activateTooltip": "Activar miembro",
+ "deleteTooltip": "Eliminar miembro",
+ "confirmDeleteTitle": "ยฟEstรก seguro de que desea eliminar este miembro?",
+ "confirmActivateTitle": "ยฟEstรก seguro de que desea cambiar el estado de este miembro?",
+ "okText": "Sรญ, continuar",
+ "cancelText": "No, cancelar",
+ "deactivatedText": "(Actualmente desactivado)",
+ "pendingInvitationText": "(Invitaciรณn pendiente)",
+ "addMemberDrawerTitle": "Agregar nuevo miembro del equipo",
+ "updateMemberDrawerTitle": "Actualizar miembro del equipo",
+ "addMemberEmailHint": "Los miembros se agregarรกn al equipo independientemente del estado de aceptaciรณn de la invitaciรณn",
+ "memberEmailLabel": "Direcciรณn(es) de correo electrรณnico",
+ "memberEmailPlaceholder": "Ingrese la direcciรณn de correo electrรณnico del miembro del equipo",
+ "memberEmailRequiredError": "Por favor, ingrese una direcciรณn de correo electrรณnico vรกlida",
+ "jobTitleLabel": "Cargo",
+ "jobTitlePlaceholder": "Seleccione o busque cargo (Opcional)",
+ "memberAccessLabel": "Nivel de acceso",
+ "addToTeamButton": "Agregar miembro al equipo",
+ "updateButton": "Guardar cambios",
+ "resendInvitationButton": "Reenviar correo de invitaciรณn",
+ "invitationSentSuccessMessage": "ยกInvitaciรณn al equipo enviada exitosamente!",
+ "createMemberSuccessMessage": "ยกNuevo miembro del equipo agregado exitosamente!",
+ "createMemberErrorMessage": "Error al agregar miembro del equipo. Por favor, intente nuevamente.",
+ "updateMemberSuccessMessage": "ยกMiembro del equipo actualizado exitosamente!",
+ "updateMemberErrorMessage": "Error al actualizar miembro del equipo. Por favor, intente nuevamente.",
+ "memberText": "Miembro del equipo",
+ "adminText": "Administrador",
+ "ownerText": "Propietario del equipo",
+ "addedText": "Agregado",
+ "updatedText": "Actualizado",
+ "noResultFound": "Escriba una direcciรณn de correo electrรณnico y presione enter...",
+ "jobTitlesFetchError": "Error al obtener los cargos",
+ "invitationResent": "ยกInvitaciรณn reenviada exitosamente!"
+}
diff --git a/worklenz-backend/src/public/locales/es/settings/teams.json b/worklenz-backend/src/public/locales/es/settings/teams.json
new file mode 100644
index 00000000..808c1b78
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/settings/teams.json
@@ -0,0 +1,16 @@
+{
+ "title": "Equipos",
+ "team": "Equipo",
+ "teams": "Equipos",
+ "name": "Nombre",
+ "created": "Creado",
+ "ownsBy": "Pertenece a",
+ "edit": "Editar",
+ "editTeam": "Editar Equipo",
+ "pinTooltip": "Haz clic para fijar esto en el menรบ principal",
+ "editTeamName": "Editar Nombre del Equipo",
+ "updateName": "Actualizar Nombre",
+ "namePlaceholder": "Nombre",
+ "nameRequired": "Por favor ingresa un Nombre",
+ "updateFailed": "ยกFallรณ el cambio de nombre del equipo!"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/es/task-drawer/task-drawer-info-tab.json b/worklenz-backend/src/public/locales/es/task-drawer/task-drawer-info-tab.json
new file mode 100644
index 00000000..02b3038a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/task-drawer/task-drawer-info-tab.json
@@ -0,0 +1,30 @@
+{
+ "details": {
+ "task-key": "Clave de tarea",
+ "phase": "Fase",
+ "assignees": "Asignados",
+ "due-date": "Fecha de vencimiento",
+ "time-estimation": "Estimaciรณn de tiempo",
+ "priority": "Prioridad",
+ "labels": "Etiquetas",
+ "billable": "Facturable",
+ "notify": "Notificar",
+ "when-done-notify": "Al terminar, notificar",
+ "start-date": "Fecha de inicio",
+ "end-date": "Fecha de finalizaciรณn",
+ "hide-start-date": "Ocultar fecha de inicio",
+ "show-start-date": "Mostrar fecha de inicio",
+ "hours": "Horas",
+ "minutes": "Minutos",
+ "recurring": "Recurrente"
+ },
+ "description": {
+ "title": "Descripciรณn",
+ "placeholder": "Aรฑadir una descripciรณn mรกs detallada..."
+ },
+ "subTasks": {
+ "title": "Subtareas",
+ "add-sub-task": "+ Aรฑadir subtarea",
+ "refresh-sub-tasks": "Actualizar subtareas"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/es/task-drawer/task-drawer-recurring-config.json b/worklenz-backend/src/public/locales/es/task-drawer/task-drawer-recurring-config.json
new file mode 100644
index 00000000..c1ef9e83
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/task-drawer/task-drawer-recurring-config.json
@@ -0,0 +1,34 @@
+{
+ "recurring": "Recurrente",
+ "recurringTaskConfiguration": "Configuraciรณn de tarea recurrente",
+ "repeats": "Repeticiones",
+ "daily": "Diario",
+ "weekly": "Semanal",
+ "everyXDays": "Cada X dรญas",
+ "everyXWeeks": "Cada X semanas",
+ "everyXMonths": "Cada X meses",
+ "monthly": "Mensual",
+ "selectDaysOfWeek": "Seleccionar dรญas de la semana",
+ "mon": "Lun",
+ "tue": "Mar",
+ "wed": "Miรฉ",
+ "thu": "Jue",
+ "fri": "Vie",
+ "sat": "Sรกb",
+ "sun": "Dom",
+ "monthlyRepeatType": "Tipo de repeticiรณn mensual",
+ "onSpecificDate": "En una fecha especรญfica",
+ "onSpecificDay": "En un dรญa especรญfico",
+ "dateOfMonth": "Fecha del mes",
+ "weekOfMonth": "Semana del mes",
+ "dayOfWeek": "Dรญa de la semana",
+ "first": "Primero",
+ "second": "Segundo",
+ "third": "Tercero",
+ "fourth": "Cuarto",
+ "last": "รltimo",
+ "intervalDays": "Intervalo (dรญas)",
+ "intervalWeeks": "Intervalo (semanas)",
+ "intervalMonths": "Intervalo (meses)",
+ "saveChanges": "Guardar cambios"
+}
diff --git a/worklenz-backend/src/public/locales/es/task-drawer/task-drawer.json b/worklenz-backend/src/public/locales/es/task-drawer/task-drawer.json
new file mode 100644
index 00000000..8e438716
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/task-drawer/task-drawer.json
@@ -0,0 +1,123 @@
+{
+ "taskHeader": {
+ "taskNamePlaceholder": "Escriba su Tarea",
+ "deleteTask": "Eliminar Tarea"
+ },
+ "taskInfoTab": {
+ "title": "Informaciรณn",
+ "details": {
+ "title": "Detalles",
+ "task-key": "Clave de Tarea",
+ "phase": "Fase",
+ "assignees": "Asignados",
+ "due-date": "Fecha de Vencimiento",
+ "time-estimation": "Estimaciรณn de Tiempo",
+ "priority": "Prioridad",
+ "labels": "Etiquetas",
+ "billable": "Facturable",
+ "notify": "Notificar",
+ "when-done-notify": "Al terminar, notificar",
+ "start-date": "Fecha de Inicio",
+ "end-date": "Fecha de Fin",
+ "hide-start-date": "Ocultar Fecha de Inicio",
+ "show-start-date": "Mostrar Fecha de Inicio",
+ "hours": "Horas",
+ "minutes": "Minutos",
+ "progressValue": "Valor de Progreso",
+ "progressValueTooltip": "Establecer el porcentaje de progreso (0-100%)",
+ "progressValueRequired": "Por favor, introduzca un valor de progreso",
+ "progressValueRange": "El progreso debe estar entre 0 y 100",
+ "taskWeight": "Peso de la Tarea",
+ "taskWeightTooltip": "Establecer el peso de esta subtarea (porcentaje)",
+ "taskWeightRequired": "Por favor, introduzca un peso de tarea",
+ "taskWeightRange": "El peso debe estar entre 0 y 100",
+ "recurring": "Recurrente"
+ },
+ "labels": {
+ "labelInputPlaceholder": "Buscar o crear",
+ "labelsSelectorInputTip": "Presiona Enter para crear"
+ },
+ "description": {
+ "title": "Descripciรณn",
+ "placeholder": "Aรฑadir una descripciรณn mรกs detallada..."
+ },
+ "subTasks": {
+ "title": "Sub Tareas",
+ "addSubTask": "Agregar Sub Tarea",
+ "addSubTaskInputPlaceholder": "Escriba su tarea y presione enter",
+ "refreshSubTasks": "Actualizar Sub Tareas",
+ "edit": "Editar",
+ "delete": "Eliminar",
+ "confirmDeleteSubTask": "ยฟEstรก seguro de que desea eliminar esta subtarea?",
+ "deleteSubTask": "Eliminar Sub Tarea"
+ },
+ "dependencies": {
+ "title": "Dependencias",
+ "addDependency": "+ Agregar nueva dependencia",
+ "blockedBy": "Bloqueado por",
+ "searchTask": "Escribir para buscar tarea",
+ "noTasksFound": "No se encontraron tareas",
+ "confirmDeleteDependency": "ยฟEstรก seguro de que desea eliminar?"
+ },
+ "attachments": {
+ "title": "Adjuntos",
+ "chooseOrDropFileToUpload": "Elija o arrastre un archivo para subir",
+ "uploading": "Subiendo..."
+ },
+ "comments": {
+ "title": "Comentarios",
+ "addComment": "+ Agregar nuevo comentario",
+ "noComments": "Aรบn no hay comentarios. ยกSรฉ el primero en comentar!",
+ "delete": "Eliminar",
+ "confirmDeleteComment": "ยฟEstรก seguro de que desea eliminar este comentario?",
+ "addCommentPlaceholder": "Agregar un comentario...",
+ "cancel": "Cancelar",
+ "commentButton": "Comentar",
+ "attachFiles": "Adjuntar archivos",
+ "addMoreFiles": "Agregar mรกs archivos",
+ "selectedFiles": "Archivos Seleccionados (Hasta 25MB, Mรกximo {count})",
+ "maxFilesError": "Solo puede subir un mรกximo de {count} archivos",
+ "processFilesError": "Error al procesar archivos",
+ "addCommentError": "Por favor agregue un comentario o adjunte archivos",
+ "createdBy": "Creado {{time}} por {{user}}",
+ "updatedTime": "Actualizado {{time}}"
+ },
+ "searchInputPlaceholder": "Buscar por nombre",
+ "pendingInvitation": "Invitaciรณn Pendiente"
+ },
+ "taskTimeLogTab": {
+ "title": "Registro de Tiempo",
+ "addTimeLog": "Aรฑadir nuevo registro de tiempo",
+ "totalLogged": "Total Registrado",
+ "exportToExcel": "Exportar a Excel",
+ "noTimeLogsFound": "No se encontraron registros de tiempo",
+ "timeLogForm": {
+ "date": "Fecha",
+ "startTime": "Hora de Inicio",
+ "endTime": "Hora de Fin",
+ "workDescription": "Descripciรณn del Trabajo",
+ "descriptionPlaceholder": "Agregar una descripciรณn",
+ "logTime": "Registrar tiempo",
+ "updateTime": "Actualizar tiempo",
+ "cancel": "Cancelar",
+ "selectDateError": "Por favor seleccione una fecha",
+ "selectStartTimeError": "Por favor seleccione la hora de inicio",
+ "selectEndTimeError": "Por favor seleccione la hora de fin",
+ "endTimeAfterStartError": "La hora de fin debe ser posterior a la hora de inicio"
+ }
+ },
+ "taskActivityLogTab": {
+ "title": "Registro de Actividad",
+ "add": "AGREGAR",
+ "remove": "QUITAR",
+ "none": "Ninguno",
+ "weight": "Peso",
+ "createdTask": "creรณ la tarea."
+ },
+ "taskProgress": {
+ "markAsDoneTitle": "ยฟMarcar Tarea como Completada?",
+ "confirmMarkAsDone": "Sรญ, marcar como completada",
+ "cancelMarkAsDone": "No, mantener estado actual",
+ "markAsDoneDescription": "Ha establecido el progreso al 100%. ยฟLe gustarรญa actualizar el estado de la tarea a \"Completada\"?"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/es/task-list-filters.json b/worklenz-backend/src/public/locales/es/task-list-filters.json
new file mode 100644
index 00000000..465368f0
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/task-list-filters.json
@@ -0,0 +1,81 @@
+{
+ "searchButton": "Buscar",
+ "resetButton": "Restablecer",
+ "searchInputPlaceholder": "Buscar por nombre",
+
+ "sortText": "Ordenar",
+ "statusText": "Estado",
+ "phaseText": "Fase",
+ "priorityText": "Prioridad",
+ "labelsText": "Etiquetas",
+ "membersText": "Miembros",
+ "groupByText": "Agrupar por",
+ "showArchivedText": "Mostrar archivados",
+ "showFieldsText": "Mostrar campos",
+ "keyText": "Clave",
+ "taskText": "Tarea",
+ "descriptionText": "Descripciรณn",
+ "phasesText": "Fases",
+ "progressText": "Progreso",
+ "timeTrackingText": "Seguimiento de tiempo",
+ "estimationText": "Estimaciรณn",
+ "startDateText": "Fecha de inicio",
+ "endDateText": "Fecha de fin",
+ "dueDateText": "Fecha de vencimiento",
+ "completedDateText": "Fecha de finalizaciรณn",
+ "createdDateText": "Fecha de creaciรณn",
+ "lastUpdatedText": "รltima actualizaciรณn",
+ "reporterText": "Reportero",
+ "dueTimeText": "Hora de vencimiento",
+ "lowText": "Baja",
+ "mediumText": "Media",
+ "highText": "Alta",
+ "assigneesText": "Asignados",
+ "timetrackingText": "Seguimiento de tiempo",
+ "startdateText": "Fecha de inicio",
+ "duedateText": "Fecha de vencimiento",
+ "completeddateText": "Fecha de finalizaciรณn",
+ "createddateText": "Fecha de creaciรณn",
+ "lastupdatedText": "รltima actualizaciรณn",
+ "duetimeText": "Hora de vencimiento",
+ "createStatusButtonTooltip": "Configuraciรณn de estados",
+ "configPhaseButtonTooltip": "Configuraciรณn de fases",
+ "noLabelsFound": "No se encontraron etiquetas",
+
+ "addStatusButton": "Agregar estado",
+ "addPhaseButton": "Agregar fase",
+
+ "createStatus": "Crear estado",
+ "name": "Nombre",
+ "category": "Categorรญa",
+ "selectCategory": "Seleccionar una categorรญa",
+ "pleaseEnterAName": "Por favor, ingrese un nombre",
+ "pleaseSelectACategory": "Por favor, seleccione una categorรญa",
+ "create": "Crear",
+
+ "searchTasks": "Buscar tareas...",
+ "searchPlaceholder": "Buscar...",
+ "fieldsText": "Campos",
+ "loadingFilters": "Cargando filtros...",
+ "noOptionsFound": "No se encontraron opciones",
+ "filtersActive": "filtros activos",
+ "filterActive": "filtro activo",
+ "clearAll": "Limpiar todo",
+ "clearing": "Limpiando...",
+ "cancel": "Cancelar",
+ "search": "Buscar",
+ "groupedBy": "Agrupado por",
+ "manageStatuses": "Gestionar Estados",
+ "managePhases": "Gestionar Fases",
+ "dragToReorderStatuses": "Arrastra los estados para reordenarlos. Cada estado puede tener una categorรญa diferente.",
+ "enterNewStatusName": "Introducir nuevo nombre de estado...",
+ "addStatus": "Aรฑadir Estado",
+ "noStatusesFound": "No se encontraron estados. Crea tu primer estado arriba.",
+ "deleteStatus": "Eliminar Estado",
+ "deleteStatusConfirm": "ยฟEstรกs seguro de que quieres eliminar este estado? Esta acciรณn no se puede deshacer.",
+ "rename": "Renombrar",
+ "delete": "Eliminar",
+ "enterStatusName": "Introducir nombre del estado",
+ "selectCategory": "Seleccionar categorรญa",
+ "close": "Cerrar"
+}
diff --git a/worklenz-backend/src/public/locales/es/task-list-table.json b/worklenz-backend/src/public/locales/es/task-list-table.json
new file mode 100644
index 00000000..0648c2ff
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/task-list-table.json
@@ -0,0 +1,136 @@
+{
+ "keyColumn": "Clave",
+ "taskColumn": "Tarea",
+ "descriptionColumn": "Descripciรณn",
+ "progressColumn": "Progreso",
+ "membersColumn": "Miembros",
+ "assigneesColumn": "Asignados",
+ "labelsColumn": "Etiquetas",
+ "phasesColumn": "Fases",
+ "phaseColumn": "Fase",
+ "statusColumn": "Estado",
+ "priorityColumn": "Prioridad",
+ "timeTrackingColumn": "Seguimiento de tiempo",
+ "timetrackingColumn": "Seguimiento de tiempo",
+ "estimationColumn": "Estimaciรณn",
+ "startDateColumn": "Fecha de inicio",
+ "startdateColumn": "Fecha de inicio",
+ "dueDateColumn": "Fecha de vencimiento",
+ "duedateColumn": "Fecha de vencimiento",
+ "completedDateColumn": "Fecha de completado",
+ "completeddateColumn": "Fecha de completado",
+ "createdDateColumn": "Fecha de creaciรณn",
+ "createddateColumn": "Fecha de creaciรณn",
+ "lastUpdatedColumn": "รltima actualizaciรณn",
+ "lastupdatedColumn": "รltima actualizaciรณn",
+ "reporterColumn": "Reportador",
+ "dueTimeColumn": "Hora de vencimiento",
+ "todoSelectorText": "Por hacer",
+ "doingSelectorText": "En progreso",
+ "doneSelectorText": "Completado",
+
+ "lowSelectorText": "Baja",
+ "mediumSelectorText": "Media",
+ "highSelectorText": "Alta",
+
+ "selectText": "Seleccionar",
+ "labelsSelectorInputTip": "ยกPresiona enter para crear!",
+
+ "addTaskText": "Agregar tarea",
+ "addSubTaskText": "Agregar subtarea",
+ "noTasksInGroup": "No hay tareas en este grupo",
+ "addTaskInputPlaceholder": "Escribe tu tarea y presiona enter",
+
+ "openButton": "Abrir",
+ "okButton": "Aceptar",
+
+ "noLabelsFound": "No se encontraron etiquetas",
+ "searchInputPlaceholder": "Buscar o crear",
+ "assigneeSelectorInviteButton": "Invitar a un nuevo miembro por correo",
+ "labelInputPlaceholder": "Buscar o crear",
+ "searchLabelsPlaceholder": "Buscar etiquetas...",
+ "createLabelButton": "Crear \"{{name}}\"",
+ "manageLabelsPath": "Configuraciรณn โ Etiquetas",
+
+ "pendingInvitation": "Invitaciรณn pendiente",
+
+ "contextMenu": {
+ "assignToMe": "Asignar a mรญ",
+ "moveTo": "Mover a",
+ "unarchive": "Desarchivar",
+ "archive": "Archivar",
+ "convertToSubTask": "Convertir en subtarea",
+ "convertToTask": "Convertir en tarea",
+ "delete": "Eliminar",
+ "searchByNameInputPlaceholder": "Buscar por nombre"
+ },
+ "setDueDate": "Establecer fecha de vencimiento",
+ "setStartDate": "Establecer fecha de inicio",
+ "clearDueDate": "Limpiar fecha de vencimiento",
+ "clearStartDate": "Limpiar fecha de inicio",
+ "dueDatePlaceholder": "Fecha de vencimiento",
+ "startDatePlaceholder": "Fecha de inicio",
+
+ "emptyStates": {
+ "noTaskGroups": "No se encontraron grupos de tareas",
+ "noTaskGroupsDescription": "Las tareas aparecerรกn aquรญ cuando se creen o cuando se apliquen filtros.",
+ "errorPrefix": "Error:",
+ "dragTaskFallback": "Tarea"
+ },
+
+ "customColumns": {
+ "addCustomColumn": "Agregar una columna personalizada",
+ "customColumnHeader": "Columna Personalizada",
+ "customColumnSettings": "Configuraciรณn de columna personalizada",
+ "noCustomValue": "Sin valor",
+ "peopleField": "Campo de personas",
+ "noDate": "Sin fecha",
+ "unsupportedField": "Tipo de campo no compatible",
+
+ "modal": {
+ "addFieldTitle": "Agregar campo",
+ "editFieldTitle": "Editar campo",
+ "fieldTitle": "Tรญtulo del campo",
+ "fieldTitleRequired": "El tรญtulo del campo es obligatorio",
+ "columnTitlePlaceholder": "Tรญtulo de la columna",
+ "type": "Tipo",
+ "deleteConfirmTitle": "ยฟEstรก seguro de que desea eliminar esta columna personalizada?",
+ "deleteConfirmDescription": "Esta acciรณn no se puede deshacer. Todos los datos asociados con esta columna se eliminarรกn permanentemente.",
+ "deleteButton": "Eliminar",
+ "cancelButton": "Cancelar",
+ "createButton": "Crear",
+ "updateButton": "Actualizar",
+ "createSuccessMessage": "Columna personalizada creada exitosamente",
+ "updateSuccessMessage": "Columna personalizada actualizada exitosamente",
+ "deleteSuccessMessage": "Columna personalizada eliminada exitosamente",
+ "deleteErrorMessage": "Error al eliminar la columna personalizada",
+ "createErrorMessage": "Error al crear la columna personalizada",
+ "updateErrorMessage": "Error al actualizar la columna personalizada"
+ },
+
+ "fieldTypes": {
+ "people": "Personas",
+ "number": "Nรบmero",
+ "date": "Fecha",
+ "selection": "Selecciรณn",
+ "checkbox": "Casilla de verificaciรณn",
+ "labels": "Etiquetas",
+ "key": "Clave",
+ "formula": "Fรณrmula"
+ }
+ },
+
+ "indicators": {
+ "tooltips": {
+ "subtasks": "{{count}} subtarea",
+ "subtasks_plural": "{{count}} subtareas",
+ "comments": "{{count}} comentario",
+ "comments_plural": "{{count}} comentarios",
+ "attachments": "{{count}} archivo adjunto",
+ "attachments_plural": "{{count}} archivos adjuntos",
+ "subscribers": "La tarea tiene suscriptores",
+ "dependencies": "La tarea tiene dependencias",
+ "recurring": "Tarea recurrente"
+ }
+ }
+}
diff --git a/worklenz-backend/src/public/locales/es/task-management.json b/worklenz-backend/src/public/locales/es/task-management.json
new file mode 100644
index 00000000..1c80304c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/task-management.json
@@ -0,0 +1,21 @@
+{
+ "noTasksInGroup": "No hay tareas en este grupo",
+ "noTasksInGroupDescription": "Aรฑade una tarea para comenzar",
+ "addFirstTask": "Aรฑade tu primera tarea",
+ "openTask": "Abrir",
+ "subtask": "subtarea",
+ "subtasks": "subtareas",
+ "comment": "comentario",
+ "comments": "comentarios",
+ "attachment": "adjunto",
+ "attachments": "adjuntos",
+ "enterSubtaskName": "Ingresa el nombre de la subtarea...",
+ "add": "Aรฑadir",
+ "cancel": "Cancelar",
+ "renameGroup": "Renombrar Grupo",
+ "renameStatus": "Renombrar Estado",
+ "renamePhase": "Renombrar Fase",
+ "changeCategory": "Cambiar Categorรญa",
+ "clickToEditGroupName": "Haz clic para editar el nombre del grupo",
+ "enterGroupName": "Ingresa el nombre del grupo"
+}
diff --git a/worklenz-backend/src/public/locales/es/task-template-drawer.json b/worklenz-backend/src/public/locales/es/task-template-drawer.json
new file mode 100644
index 00000000..a3bfc45b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/task-template-drawer.json
@@ -0,0 +1,11 @@
+{
+ "createTaskTemplate": "Crear Plantilla de Tarea",
+ "editTaskTemplate": "Editar Plantilla de Tarea",
+ "cancelText": "Cancelar",
+ "saveText": "Guardar",
+ "templateNameText": "Nombre de la Plantilla",
+ "selectedTasks": "Tareas Seleccionadas",
+ "removeTask": "Eliminar",
+ "cancelButton": "Cancelar",
+ "saveButton": "Guardar"
+}
diff --git a/worklenz-backend/src/public/locales/es/tasks/task-table-bulk-actions.json b/worklenz-backend/src/public/locales/es/tasks/task-table-bulk-actions.json
new file mode 100644
index 00000000..0f98b1a5
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/tasks/task-table-bulk-actions.json
@@ -0,0 +1,41 @@
+{
+ "taskSelected": "Tarea seleccionada",
+ "tasksSelected": "Tareas seleccionadas",
+ "changeStatus": "Cambiar estado/ prioridad/ fases",
+ "changeLabel": "Cambiar etiqueta",
+ "assignToMe": "Asignar a mรญ",
+ "changeAssignees": "Cambiar asignados",
+ "archive": "Archivar",
+ "unarchive": "Desarchivar",
+ "delete": "Eliminar",
+ "moreOptions": "Mรกs opciones",
+ "deselectAll": "Deseleccionar todo",
+ "status": "Estado",
+ "priority": "Prioridad",
+ "phase": "Fase",
+ "member": "Miembro",
+ "createTaskTemplate": "Crear plantilla de tarea",
+ "apply": "Aplicar",
+ "createLabel": "+ Crear etiqueta",
+ "searchOrCreateLabel": "Buscar o crear etiqueta...",
+ "hitEnterToCreate": "Presione Enter para crear",
+ "labelExists": "La etiqueta ya existe",
+ "pendingInvitation": "Invitaciรณn Pendiente",
+ "noMatchingLabels": "No hay etiquetas coincidentes",
+ "noLabels": "Sin etiquetas",
+ "CHANGE_STATUS": "Cambiar Estado",
+ "CHANGE_PRIORITY": "Cambiar Prioridad",
+ "CHANGE_PHASE": "Cambiar Fase",
+ "ADD_LABELS": "Agregar Etiquetas",
+ "ASSIGN_TO_ME": "Asignar a Mรญ",
+ "ASSIGN_MEMBERS": "Asignar Miembros",
+ "ARCHIVE": "Archivar",
+ "DELETE": "Eliminar",
+ "CANCEL": "Cancelar",
+ "CLEAR_SELECTION": "Limpiar Selecciรณn",
+ "TASKS_SELECTED": "{{count}} tarea seleccionada",
+ "TASKS_SELECTED_plural": "{{count}} tareas seleccionadas",
+ "DELETE_TASKS_CONFIRM": "ยฟEliminar {{count}} tarea?",
+ "DELETE_TASKS_CONFIRM_plural": "ยฟEliminar {{count}} tareas?",
+ "DELETE_TASKS_WARNING": "Esta acciรณn no se puede deshacer."
+}
diff --git a/worklenz-backend/src/public/locales/es/template-drawer.json b/worklenz-backend/src/public/locales/es/template-drawer.json
new file mode 100644
index 00000000..7c6c7f3d
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/template-drawer.json
@@ -0,0 +1,19 @@
+{
+ "title": "Editar Plantilla de Tarea",
+ "cancelText": "Cancelar",
+ "saveText": "Guardar",
+ "templateNameText": "Nombre de la Plantilla",
+ "selectedTasks": "Tareas Seleccionadas",
+ "removeTask": "Eliminar",
+ "description": "Descripciรณn",
+ "phase": "Fase",
+ "statuses": "Estados",
+ "priorities": "Prioridades",
+ "labels": "Etiquetas",
+ "tasks": "Tareas",
+ "noTemplateSelected": "No hay plantilla seleccionada",
+ "noDescription": "Sin descripciรณn",
+ "worklenzTemplates": "Plantillas de Worklenz",
+ "yourTemplatesLibrary": "Tu Biblioteca",
+ "searchTemplates": "Buscar Plantillas"
+}
diff --git a/worklenz-backend/src/public/locales/es/templateDrawer.json b/worklenz-backend/src/public/locales/es/templateDrawer.json
new file mode 100644
index 00000000..8028f0cd
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/templateDrawer.json
@@ -0,0 +1,23 @@
+{
+ "bugTracking": "Seguimiento de Errores",
+ "construction": "Construcciรณn",
+ "designCreative": "Diseรฑo y Creatividad",
+ "education": "Educaciรณn",
+ "finance": "Finanzas",
+ "hrRecruiting": "RRHH y Reclutamiento",
+ "informationTechnology": "Tecnologรญa de la Informaciรณn",
+ "legal": "Legal",
+ "manufacturing": "Fabricaciรณn",
+ "marketing": "Marketing",
+ "nonprofit": "Sin fines de lucro",
+ "personalUse": "Uso personal",
+ "salesCRM": "Ventas y CRM",
+ "serviceConsulting": "Servicios y Consultorรญa",
+ "softwareDevelopment": "Desarrollo de Software",
+ "description": "Descripciรณn",
+ "phase": "Fase",
+ "statuses": "Estados",
+ "priorities": "Prioridades",
+ "labels": "Etiquetas",
+ "tasks": "Tareas"
+}
diff --git a/worklenz-backend/src/public/locales/es/time-report.json b/worklenz-backend/src/public/locales/es/time-report.json
new file mode 100644
index 00000000..2646520f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/time-report.json
@@ -0,0 +1,57 @@
+{
+ "includeArchivedProjects": "Incluir Proyectos Archivados",
+ "export": "Exportar",
+ "timeSheet": "Hoja de Tiempo",
+
+ "searchByName": "Buscar por nombre",
+ "selectAll": "Seleccionar Todo",
+ "teams": "Equipos",
+
+ "searchByProject": "Buscar por nombre del proyecto",
+ "projects": "Proyectos",
+
+ "searchByCategory": "Buscar por nombre de categorรญa",
+ "categories": "Categorรญas",
+
+ "billable": "Facturable",
+ "nonBillable": "No Facturable",
+
+ "total": "Total",
+
+ "projectsTimeSheet": "Hoja de Tiempo de Proyectos",
+
+ "loggedTime": "Tiempo Registrado(horas)",
+
+ "exportToExcel": "Exportar a Excel",
+ "logged": "registrado",
+ "for": "para",
+
+ "membersTimeSheet": "Hoja de Tiempo de Miembros",
+ "member": "Miembro",
+
+ "estimatedVsActual": "Estimado vs Real",
+ "workingDays": "Dรญas Laborables",
+ "manDays": "Dรญas Hombre",
+ "days": "Dรญas",
+ "estimatedDays": "Dรญas Estimados",
+ "actualDays": "Dรญas Reales",
+
+ "noCategories": "No se encontraron categorรญas",
+ "noCategory": "Sin Categorรญa",
+ "noProjects": "No se encontraron proyectos",
+ "noTeams": "No se encontraron equipos",
+ "noData": "No se encontraron datos",
+
+ "groupBy": "Agrupar por",
+ "groupByCategory": "Categorรญa",
+ "groupByTeam": "Equipo",
+ "groupByStatus": "Estado",
+ "groupByNone": "Ninguno",
+ "clearSearch": "Limpiar bรบsqueda",
+ "selectedProjects": "Proyectos Seleccionados",
+ "projectsSelected": "proyectos seleccionados",
+ "showSelected": "Mostrar Solo Seleccionados",
+ "expandAll": "Expandir Todo",
+ "collapseAll": "Contraer Todo",
+ "ungrouped": "Sin Agrupar"
+}
diff --git a/worklenz-backend/src/public/locales/es/unauthorized.json b/worklenz-backend/src/public/locales/es/unauthorized.json
new file mode 100644
index 00000000..e28ce8f4
--- /dev/null
+++ b/worklenz-backend/src/public/locales/es/unauthorized.json
@@ -0,0 +1,5 @@
+{
+ "title": "ยกNo autorizado!",
+ "subtitle": "No tienes permisos para acceder a esta pรกgina",
+ "button": "Ir a Inicio"
+}
diff --git a/worklenz-backend/src/public/locales/pt/404-page.json b/worklenz-backend/src/public/locales/pt/404-page.json
new file mode 100644
index 00000000..638d30b3
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/404-page.json
@@ -0,0 +1,4 @@
+{
+ "doesNotExistText": "Desculpe, a pรกgina que vocรช visitou nรฃo existe.",
+ "backHomeButton": "Voltar ao Inรญcio"
+}
diff --git a/worklenz-backend/src/public/locales/pt/account-setup.json b/worklenz-backend/src/public/locales/pt/account-setup.json
new file mode 100644
index 00000000..1d8a8cba
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/account-setup.json
@@ -0,0 +1,32 @@
+{
+ "continue": "Continuar",
+
+ "setupYourAccount": "Configure sua conta.",
+ "organizationStepTitle": "Nomeie sua organizaรงรฃo",
+ "organizationStepLabel": "Escolha um nome para sua conta Worklenz.",
+
+ "projectStepTitle": "Crie seu primeiro projeto",
+ "projectStepLabel": "Em qual projeto vocรช estรก trabalhando agora?",
+ "projectStepPlaceholder": "ex. Plano de Marketing",
+
+ "step2Title": "Crie suas primeiras tarefas",
+ "step2InputLabel": "Digite algumas tarefas que vocรช vai fazer em",
+ "step2AddAnother": "Adicionar outro",
+
+ "emailPlaceholder": "Endereรงo de e-mail",
+ "invalidEmail": "Por favor, insira um endereรงo de e-mail vรกlido",
+ "or": "ou",
+ "templateButton": "Importar do modelo",
+ "goBack": "Voltar",
+ "cancel": "Cancelar",
+ "create": "Criar",
+ "templateDrawerTitle": "Selecionar dos modelos",
+ "step3InputLabel": "Convidar por email",
+ "addAnother": "Adicionar outro",
+ "skipForNow": "Pular por enquanto",
+ "formTitle": "Crie sua primeira tarefa.",
+ "step3Title": "Convide sua equipe para trabalhar",
+
+ "maxMembers": " (Vocรช pode convidar atรฉ 5 membros)",
+ "maxTasks": " (Vocรช pode criar atรฉ 5 tarefas)"
+}
diff --git a/worklenz-backend/src/public/locales/pt/admin-center/current-bill.json b/worklenz-backend/src/public/locales/pt/admin-center/current-bill.json
new file mode 100644
index 00000000..2e4b41d7
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/admin-center/current-bill.json
@@ -0,0 +1,113 @@
+{
+ "title": "Cobranรงas",
+ "currentBill": "Fatura Atual",
+ "configuration": "Configuraรงรฃo",
+ "currentPlanDetails": "Detalhes do Plano Atual",
+ "upgradePlan": "Atualizar Plano",
+ "cardBodyText01": "Teste gratuito",
+ "cardBodyText02": "(Seu plano de teste expira em 1 mรชs e 19 dias)",
+ "redeemCode": "Resgatar Cรณdigo",
+ "accountStorage": "Armazenamento da Conta",
+ "used": "Usado:",
+ "remaining": "Restante:",
+ "charges": "Cobranรงas",
+ "tooltip": "Cobranรงas para o ciclo de faturamento atual",
+ "description": "Descriรงรฃo",
+ "billingPeriod": "Perรญodo de Faturamento",
+ "billStatus": "Status da Fatura",
+ "perUserValue": "Valor por Usuรกrio",
+ "users": "Usuรกrios",
+ "amount": "Valor",
+ "invoices": "Faturas",
+ "transactionId": "ID da Transaรงรฃo",
+ "transactionDate": "Data da Transaรงรฃo",
+ "paymentMethod": "Mรฉtodo de Pagamento",
+ "status": "Status",
+ "ltdUsers": "Puedes agregar hasta {{ltd_users}} usuarios.",
+
+ "drawerTitle": "Resgatar Cรณdigo",
+ "label": "Resgatar Cรณdigo",
+ "drawerPlaceholder": "Digite seu cรณdigo de resgate",
+ "redeemSubmit": "Enviar",
+
+ "modalTitle": "Selecione o melhor plano para sua equipe",
+ "seatLabel": "Nรบmero de assentos",
+ "freePlan": "Plano Gratuito",
+ "startup": "Startup",
+ "business": "Empresarial",
+ "tag": "Mais Popular",
+ "enterprise": "Enterprise",
+
+ "freeSubtitle": "gratuito para sempre",
+ "freeUsers": "Melhor para uso pessoal",
+ "freeText01": "100MB de armazenamento",
+ "freeText02": "3 projetos",
+ "freeText03": "5 membros na equipe",
+
+ "startupSubtitle": "TAXA FIXA / mรชs",
+ "startupUsers": "Atรฉ 15 usuรกrios",
+ "startupText01": "25GB de armazenamento",
+ "startupText02": "Projetos ativos ilimitados",
+ "startupText03": "Agendamento",
+ "startupText04": "Relatรณrios",
+ "startupText05": "Inscrever-se em projetos",
+
+ "businessSubtitle": "usuรกrio / mรชs",
+ "businessUsers": "16 - 200 usuรกrios",
+
+ "enterpriseUsers": "200 - 500+ usuรกrios",
+
+ "footerTitle": "Por favor, forneรงa um nรบmero de contato para que possamos entrar em contato com vocรช.",
+ "footerLabel": "Nรบmero de Contato",
+ "footerButton": "Contate-nos",
+
+ "redeemCodePlaceHolder": "Digite seu cรณdigo de resgate",
+ "submit": "Enviar",
+
+ "trialPlan": "Plano de Teste",
+ "trialExpireDate": "Vรกlido atรฉ {{trial_expire_date}}",
+ "trialExpired": "Sua prova gratuita expirou {{trial_expire_string}}",
+ "trialInProgress": "Sua prova gratuita expira {{trial_expire_string}}",
+
+ "required": "Este campo รฉ obrigatรณrio",
+ "invalidCode": "Cรณdigo invรกlido",
+
+ "selectPlan": "Selecione o melhor plano para sua equipe",
+ "changeSubscriptionPlan": "Mude seu plano de assinatura",
+ "noOfSeats": "Nรบmero de assentos",
+ "annualPlan": "Pro - Anual",
+ "monthlyPlan": "Pro - Mensal",
+ "freeForever": "Gratis para sempre",
+ "bestForPersonalUse": "Melhor para uso pessoal",
+ "storage": "Armazenamento",
+ "projects": "Projetos",
+ "teamMembers": "Membros da equipe",
+ "unlimitedTeamMembers": "Membros da equipe ilimitados",
+ "unlimitedActiveProjects": "Projetos ativos ilimitados",
+ "schedule": "Agendamento",
+ "reporting": "Relatรณrios",
+ "subscribeToProjects": "Inscreva-se em projetos",
+ "billedAnnually": "Faturado Anualmente",
+ "billedMonthly": "Faturado Mensalmente",
+
+ "pausePlan": "Pausar Plano",
+ "resumePlan": "Reanudar Plano",
+ "changePlan": "Mudar Plano",
+ "cancelPlan": "Cancelar Plano",
+
+ "perMonthPerUser": "por usuรกrio / mรชs",
+ "viewInvoice": "Ver Fatura",
+ "switchToFreePlan": "Mudar para Plano Gratuito",
+
+ "expirestoday": "hoje",
+ "expirestomorrow": "amanhรฃ",
+ "expiredDaysAgo": "hรก {{days}} dias",
+ "creditPlan": "Plano de Crรฉdito",
+ "customPlan": "Plano Personalizado",
+ "planValidTill": "Seu plano รฉ vรกlido atรฉ {{date}}",
+ "purchaseSeatsText": "Para continuar, vocรช precisarรก comprar assentos adicionais.",
+ "currentSeatsText": "Atualmente vocรช tem {{seats}} assentos disponรญveis.",
+ "selectSeatsText": "Selecione o nรบmero de assentos adicionais para comprar.",
+ "purchase": "Comprar",
+ "contactSales": "Fale com vendas"
+}
diff --git a/worklenz-backend/src/public/locales/pt/admin-center/overview.json b/worklenz-backend/src/public/locales/pt/admin-center/overview.json
new file mode 100644
index 00000000..7cce8587
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/admin-center/overview.json
@@ -0,0 +1,8 @@
+{
+ "overview": "Visรฃo Geral",
+ "name": "Nome da Organizaรงรฃo",
+ "owner": "Proprietรกrio da Organizaรงรฃo",
+ "admins": "Administradores da Organizaรงรฃo",
+ "contactNumber": "Adicione o Nรบmero de Contato",
+ "edit": "Editar"
+}
diff --git a/worklenz-backend/src/public/locales/pt/admin-center/projects.json b/worklenz-backend/src/public/locales/pt/admin-center/projects.json
new file mode 100644
index 00000000..02fdc0bb
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/admin-center/projects.json
@@ -0,0 +1,12 @@
+{
+ "membersCount": "Contagem de Membros",
+ "createdAt": "Criado em",
+ "projectName": "Nome do Projeto",
+ "teamName": "Nome do Time",
+ "refreshProjects": "Atualizar Projetos",
+ "searchPlaceholder": "Pesquisar por nome do projeto",
+ "deleteProject": "Tem a certeza de que deseja deletar este projeto?",
+ "confirm": "Confirmar",
+ "cancel": "Cancelar",
+ "delete": "Deletar Projeto"
+}
diff --git a/worklenz-backend/src/public/locales/pt/admin-center/sidebar.json b/worklenz-backend/src/public/locales/pt/admin-center/sidebar.json
new file mode 100644
index 00000000..253b77e4
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/admin-center/sidebar.json
@@ -0,0 +1,8 @@
+{
+ "overview": "Visรฃo Geral",
+ "users": "Usuรกrios",
+ "teams": "Equipes",
+ "billing": "Faturamento",
+ "projects": "Projetos",
+ "adminCenter": "Central Administrativa"
+}
diff --git a/worklenz-backend/src/public/locales/pt/admin-center/teams.json b/worklenz-backend/src/public/locales/pt/admin-center/teams.json
new file mode 100644
index 00000000..6a71b491
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/admin-center/teams.json
@@ -0,0 +1,35 @@
+{
+ "title": "Equipes",
+ "subtitle": "equipes",
+ "tooltip": "Atualizar equipes",
+ "placeholder": "Pesquisar por nome",
+ "addTeam": "Adicionar Equipe",
+ "team": "Equipe",
+ "membersCount": "Contagem de Membros",
+ "members": "Membros",
+ "drawerTitle": "Criar Nova Equipe",
+ "label": "Nome da Equipe",
+ "drawerPlaceholder": "Nome",
+ "create": "Criar",
+ "delete": "Deletar",
+ "settings": "Configuraรงรตes",
+ "popTitle": "Tem a certeza?",
+ "message": "Por favor, insira um Nome",
+ "teamSettings": "Configuraรงรตes da Equipe",
+ "teamName": "Nome da Equipe",
+ "teamDescription": "Descriรงรฃo da Equipe",
+ "teamMembers": "Membros da Equipe",
+ "teamMembersCount": "Quantidade de Membros da Equipe",
+ "teamMembersPlaceholder": "Buscar por nome",
+ "addMember": "Adicionar Membro",
+ "add": "Adicionar",
+ "update": "Atualizar",
+ "teamNamePlaceholder": "Nome da Equipe",
+ "user": "Usuรกrio",
+ "role": "Rol",
+ "owner": "Propietario",
+ "admin": "Administrador",
+ "member": "Miembro",
+ "cannotChangeOwnerRole": "A funรงรฃo de Proprietรกrio nรฃo pode ser alterada",
+ "pendingInvitation": "Convite pendente"
+}
diff --git a/worklenz-backend/src/public/locales/pt/admin-center/users.json b/worklenz-backend/src/public/locales/pt/admin-center/users.json
new file mode 100644
index 00000000..9826c548
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/admin-center/users.json
@@ -0,0 +1,9 @@
+{
+ "title": "Usuรกrios",
+ "subTitle": "usuรกrios",
+ "placeholder": "Pesquisar por nome",
+ "user": "Usuรกrio",
+ "email": "Email",
+ "lastActivity": "รltima Atividade",
+ "refresh": "Atualizar usuรกrios"
+}
diff --git a/worklenz-backend/src/public/locales/pt/all-project-list.json b/worklenz-backend/src/public/locales/pt/all-project-list.json
new file mode 100644
index 00000000..482132eb
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/all-project-list.json
@@ -0,0 +1,34 @@
+{
+ "name": "Nome",
+ "client": "Cliente",
+ "category": "Categoria",
+ "status": "Status",
+ "tasksProgress": "Progresso das Tarefas",
+ "updated_at": "รltima Atualizaรงรฃo",
+ "members": "Membros",
+ "setting": "Configuraรงรตes",
+ "projects": "Projetos",
+ "refreshProjects": "Atualizar projetos",
+ "all": "Todos",
+ "favorites": "Favoritos",
+ "archived": "Arquivados",
+ "placeholder": "Pesquisar por nome",
+ "archive": "Arquivar",
+ "unarchive": "Desarquivar",
+ "archiveConfirm": "Tem certeza de que deseja arquivar este projeto?",
+ "unarchiveConfirm": "Tem certeza de que deseja desarquivar este projeto?",
+ "yes": "Sim",
+ "no": "Nรฃo",
+ "clickToFilter": "Clique para filtrar por",
+ "noProjects": "Nenhum projeto encontrado",
+ "addToFavourites": "Adicionar aos favoritos",
+ "list": "Lista",
+ "group": "Grupo",
+ "listView": "Visualizaรงรฃo em Lista",
+ "groupView": "Visualizaรงรฃo em Grupo",
+ "groupBy": {
+ "category": "Categoria",
+ "client": "Cliente"
+ },
+ "noPermission": "Vocรช nรฃo tem permissรฃo para realizar esta aรงรฃo"
+}
diff --git a/worklenz-backend/src/public/locales/pt/auth/auth-common.json b/worklenz-backend/src/public/locales/pt/auth/auth-common.json
new file mode 100644
index 00000000..e828bddf
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/auth/auth-common.json
@@ -0,0 +1,5 @@
+{
+ "loggingOut": "Deslogando...",
+ "authenticating": "Autenticando...",
+ "gettingThingsReady": "Preparando coisas para vocรช..."
+}
diff --git a/worklenz-backend/src/public/locales/pt/auth/forgot-password.json b/worklenz-backend/src/public/locales/pt/auth/forgot-password.json
new file mode 100644
index 00000000..5e9c89e0
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/auth/forgot-password.json
@@ -0,0 +1,12 @@
+{
+ "headerDescription": "Redefina sua senha",
+ "emailLabel": "Email",
+ "emailPlaceholder": "Digite seu email",
+ "emailRequired": "Por favor, digite seu email!",
+ "resetPasswordButton": "Redefinir Senha",
+ "returnToLoginButton": "Voltar para Login",
+ "passwordResetSuccessMessage": "Um link de redefiniรงรฃo de senha foi enviado para seu email.",
+ "orText": "OU",
+ "successTitle": "Instruรงรตes de redefiniรงรฃo enviadas!",
+ "successMessage": "A informaรงรฃo de redefiniรงรฃo foi enviada para seu email. Por favor, verifique seu email."
+}
diff --git a/worklenz-backend/src/public/locales/pt/auth/login.json b/worklenz-backend/src/public/locales/pt/auth/login.json
new file mode 100644
index 00000000..2ce79115
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/auth/login.json
@@ -0,0 +1,27 @@
+{
+ "headerDescription": "Faรงa login na sua conta",
+ "emailLabel": "Email",
+ "emailPlaceholder": "Digite seu email",
+ "emailRequired": "Por favor, digite seu email!",
+ "passwordLabel": "Senha",
+ "passwordPlaceholder": "Digite sua senha",
+ "passwordRequired": "Por favor, digite sua Senha!",
+ "rememberMe": "Lembre de mim",
+ "loginButton": "Entrar",
+ "signupButton": "Inscrever-se",
+ "forgotPasswordButton": "Esqueceu sua senha?",
+ "signInWithGoogleButton": "Entrar com Google",
+ "successMessage": "Vocรช entrou com sucesso!",
+ "dontHaveAccountText": "Nรฃo tem uma conta?",
+ "orText": "OU",
+ "loginError": "Login falhou",
+ "googleLoginError": "Login com Google falhou",
+ "validationMessages": {
+ "password": "A senha deve ter pelo menos 8 caracteres",
+ "email": "Por favor, insira um endereรงo de e-mail vรกlido"
+ },
+ "errorMessages": {
+ "loginErrorTitle": "Login falhou",
+ "loginErrorMessage": "Por favor, verifique seu e-mail e senha e tente novamente"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/pt/auth/signup.json b/worklenz-backend/src/public/locales/pt/auth/signup.json
new file mode 100644
index 00000000..cd994d4a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/auth/signup.json
@@ -0,0 +1,29 @@
+{
+ "headerDescription": "Inscreva-se para comeรงar",
+ "nameLabel": "Nome Completo",
+ "namePlaceholder": "Insira seu nome completo",
+ "nameRequired": "Por favor, insira seu nome completo!",
+ "nameMinCharacterRequired": "Nome completo deve ter pelo menos 4 caracteres!",
+ "emailLabel": "Email",
+ "emailPlaceholder": "Insira seu email",
+ "emailRequired": "Por favor, insira seu Email!",
+ "passwordLabel": "Senha",
+ "passwordPlaceholder": "Insira sua senha",
+ "passwordRequired": "Por favor, insira sua Senha!",
+ "passwordMinCharacterRequired": "Senha deve ter pelo menos 8 caracteres!",
+ "passwordPatternRequired": "Senha nรฃo atende aos requisitos!",
+ "strongPasswordPlaceholder": "Insira uma senha mais forte",
+ "passwordValidationAltText": "Senha deve incluir pelo menos 8 caracteres com letras maiรบsculas e minรบsculas, um nรบmero e um sรญmbolo.",
+ "signupSuccessMessage": "Vocรช se inscreveu com sucesso!",
+ "privacyPolicyLink": "Polรญtica de Privacidade",
+ "termsOfUseLink": "Termos de Uso",
+ "bySigningUpText": "Ao se inscrever, vocรช concorda com nossos",
+ "andText": "e",
+ "signupButton": "Inscrever-se",
+ "signInWithGoogleButton": "Entrar com Google",
+ "alreadyHaveAccountText": "Jรก tem uma conta?",
+ "loginButton": "Entrar",
+ "orText": "OU",
+ "reCAPTCHAVerificationError": "Erro de verificaรงรฃo do reCAPTCHA",
+ "reCAPTCHAVerificationErrorMessage": "Nรฃo pudemos verificar seu reCAPTCHA. Por favor, tente novamente."
+}
diff --git a/worklenz-backend/src/public/locales/pt/auth/verify-reset-email.json b/worklenz-backend/src/public/locales/pt/auth/verify-reset-email.json
new file mode 100644
index 00000000..189a6d51
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/auth/verify-reset-email.json
@@ -0,0 +1,14 @@
+{
+ "title": "Verificar E-mail de Redefiniรงรฃo",
+ "description": "Digite sua nova senha",
+ "placeholder": "Digite sua nova senha",
+ "confirmPasswordPlaceholder": "Confirme sua nova senha",
+ "passwordHint": "Mรญnimo de 8 caracteres, com maiรบsculas e minรบsculas, um nรบmero e um sรญmbolo.",
+ "resetPasswordButton": "Redefinir senha",
+ "orText": "Ou",
+ "resendResetEmail": "Reenviar e-mail de redefiniรงรฃo",
+ "passwordRequired": "Por favor, digite sua nova senha",
+ "returnToLoginButton": "Voltar ao Login",
+ "confirmPasswordRequired": "Por favor, confirme sua nova senha",
+ "passwordMismatch": "As senhas nรฃo coincidem"
+}
diff --git a/worklenz-backend/src/public/locales/pt/common.json b/worklenz-backend/src/public/locales/pt/common.json
new file mode 100644
index 00000000..ce540a28
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/common.json
@@ -0,0 +1,9 @@
+{
+ "login-success": "Login realizado com sucesso!",
+ "login-failed": "Falha no login. Por favor, verifique suas credenciais e tente novamente.",
+ "signup-success": "Cadastro realizado com sucesso! Bem-vindo a bordo.",
+ "signup-failed": "Falha no cadastro. Por favor, certifique-se de que todos os campos obrigatรณrios estรฃo preenchidos e tente novamente.",
+ "reconnecting": "Reconectando ao servidor...",
+ "connection-lost": "Conexรฃo perdida. Tentando reconectar...",
+ "connection-restored": "Conexรฃo restaurada. Reconectando ao servidor..."
+}
diff --git a/worklenz-backend/src/public/locales/pt/create-first-project-form.json b/worklenz-backend/src/public/locales/pt/create-first-project-form.json
new file mode 100644
index 00000000..ec3ec300
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/create-first-project-form.json
@@ -0,0 +1,13 @@
+{
+ "formTitle": "Crie seu primeiro projeto",
+ "inputLabel": "Em qual projeto vocรช estรก trabalhando agora?",
+ "or": "ou",
+ "templateButton": "Importar do modelo",
+ "createFromTemplate": "Criar do modelo",
+ "goBack": "Voltar",
+ "continue": "Continuar",
+ "cancel": "Cancelar",
+ "create": "Criar",
+ "templateDrawerTitle": "Selecione um modelo",
+ "createProject": "Criar projeto"
+}
diff --git a/worklenz-backend/src/public/locales/pt/create-first-tasks.json b/worklenz-backend/src/public/locales/pt/create-first-tasks.json
new file mode 100644
index 00000000..06c1ae87
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/create-first-tasks.json
@@ -0,0 +1,7 @@
+{
+ "formTitle": "Crie sua primeira tarefa.",
+ "inputLable": "Digite algumas tarefas que vocรช vai fazer em",
+ "addAnother": "Adicionar outro",
+ "goBack": "Voltar",
+ "continue": "Continuar"
+}
diff --git a/worklenz-backend/src/public/locales/pt/home.json b/worklenz-backend/src/public/locales/pt/home.json
new file mode 100644
index 00000000..b19ece5f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/home.json
@@ -0,0 +1,45 @@
+{
+ "todoList": {
+ "title": "Lista de tarefas",
+ "refreshTasks": "Atualizar tarefas",
+ "addTask": "+ Adicionar tarefa",
+ "noTasks": "Nenhuma tarefa",
+ "pressEnter": "Pressione",
+ "toCreate": "para criar.",
+ "markAsDone": "Marcar como feito"
+ },
+ "projects": {
+ "title": "Projetos",
+ "refreshProjects": "Atualizar projetos",
+ "noRecentProjects": "Vocรช nรฃo estรก atribuรญdo a nenhum projeto.",
+ "noFavouriteProjects": "Nenhum projeto foi marcado como favorito.",
+ "recent": "Recentes",
+ "favourites": "Favoritos"
+ },
+ "tasks": {
+ "assignedToMe": "Atribuรญdo a mim",
+ "assignedByMe": "Atribuรญdo por mim",
+ "all": "Todas",
+ "today": "Hoje",
+ "upcoming": "Prรณximas",
+ "overdue": "Vencidas",
+ "noDueDate": "Sem data de vencimento",
+ "noTasks": "Nenhuma tarefa para mostrar.",
+ "addTask": "+ Adicionar tarefa",
+ "name": "Nome",
+ "project": "Projeto",
+ "status": "Status",
+ "dueDate": "Data de vencimento",
+ "dueDatePlaceholder": "Definir data de vencimento",
+ "tomorrow": "Amanhรฃ",
+ "nextWeek": "Semana que vem",
+ "nextMonth": "Prรณximo mรชs",
+ "projectRequired": "Por favor selecione um projeto",
+ "dueOn": "Tarefas vencidas em",
+ "taskRequired": "Por favor adicione uma tarefa",
+ "list": "Lista",
+ "calendar": "Calendรกrio",
+ "tasks": "Tarefas",
+ "refresh": "Atualizar"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/pt/invite-initial-team-members.json b/worklenz-backend/src/public/locales/pt/invite-initial-team-members.json
new file mode 100644
index 00000000..39808ab2
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/invite-initial-team-members.json
@@ -0,0 +1,8 @@
+{
+ "formTitle": "Convide sua equipe para trabalhar com",
+ "inputLable": "Convidar com email",
+ "addAnother": "Adicionar outro",
+ "goBack": "Voltar",
+ "continue": "Continuar",
+ "skipForNow": "Pular por enquanto"
+}
diff --git a/worklenz-backend/src/public/locales/pt/kanban-board.json b/worklenz-backend/src/public/locales/pt/kanban-board.json
new file mode 100644
index 00000000..a2034daa
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/kanban-board.json
@@ -0,0 +1,30 @@
+{
+ "rename": "Renomear",
+ "delete": "Excluir",
+ "addTask": "Adicionar Tarefa",
+ "addSectionButton": "Adicionar Seรงรฃo",
+ "changeCategory": "Alterar categoria",
+
+ "deleteTooltip": "Excluir",
+ "deleteConfirmationTitle": "Tem certeza?",
+ "deleteConfirmationOk": "Sim",
+ "deleteConfirmationCancel": "Cancelar",
+
+ "dueDate": "Data de vencimento",
+ "cancel": "Cancelar",
+
+ "today": "Hoje",
+ "tomorrow": "Amanhรฃ",
+ "assignToMe": "Atribuir a mim",
+ "archive": "Arquivar",
+
+ "newTaskNamePlaceholder": "Escreva um nome de tarefa",
+ "newSubtaskNamePlaceholder": "Escreva um nome de subtarefa",
+ "untitledSection": "Seรงรฃo sem tรญtulo",
+ "unmapped": "Nรฃo mapeado",
+ "clickToChangeDate": "Clique para alterar a data",
+ "noDueDate": "Sem data de vencimento",
+ "save": "Salvar",
+ "clear": "Limpar",
+ "nextWeek": "Prรณxima semana"
+}
diff --git a/worklenz-backend/src/public/locales/pt/license-expired.json b/worklenz-backend/src/public/locales/pt/license-expired.json
new file mode 100644
index 00000000..aa7ae88b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/license-expired.json
@@ -0,0 +1,6 @@
+{
+ "title": "Seu teste do Worklenz expirou!",
+ "subtitle": "Por favor, atualize agora.",
+ "button": "Atualizar agora",
+ "checking": "Verificando status da assinatura..."
+}
diff --git a/worklenz-backend/src/public/locales/pt/navbar.json b/worklenz-backend/src/public/locales/pt/navbar.json
new file mode 100644
index 00000000..be0f3a63
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/navbar.json
@@ -0,0 +1,31 @@
+{
+ "logoAlt": "Logotipo Worklenz",
+ "home": "Inรญcio",
+ "projects": "Projetos",
+ "schedule": "Agendamento",
+ "reporting": "Relatรณrios",
+ "clients": "Clientes",
+ "teams": "Equipes",
+ "labels": "Rรณtulos",
+ "jobTitles": "Tรญtulos de Emprego",
+ "upgradePlan": "Plano de Upgrade",
+ "upgradePlanTooltip": "Plano de Upgrade",
+ "invite": "Convidar",
+ "inviteTooltip": "Convidar membros da equipe a se juntar",
+ "switchTeamTooltip": "Trocar equipe",
+ "help": "Ajuda",
+ "notificationTooltip": "Ver notificaรงรตes",
+ "profileTooltip": "Ver perfil",
+ "adminCenter": "Centro de administraรงรฃo",
+ "settings": "Configuraรงรตes",
+ "logOut": "Sair",
+ "notificationsDrawer": {
+ "read": "Notificaรงรตes lidas",
+ "unread": "Notificaรงรตes nรฃo lidas",
+ "markAsRead": "Marcar como lido",
+ "readAndJoin": "Ler e participar",
+ "accept": "Aceitar",
+ "acceptAndJoin": "Aceitar e participar",
+ "noNotifications": "Sem notificaรงรตes"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/pt/organization-name-form.json b/worklenz-backend/src/public/locales/pt/organization-name-form.json
new file mode 100644
index 00000000..c165b8cb
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/organization-name-form.json
@@ -0,0 +1,5 @@
+{
+ "nameYourOrganization": "Nomeie sua organizaรงรฃo.",
+ "worklenzAccountTitle": "Escolha um nome para sua conta Worklenz.",
+ "continue": "Continuar"
+}
diff --git a/worklenz-backend/src/public/locales/pt/phases-drawer.json b/worklenz-backend/src/public/locales/pt/phases-drawer.json
new file mode 100644
index 00000000..080b13df
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/phases-drawer.json
@@ -0,0 +1,19 @@
+{
+ "configurePhases": "Configurar fases",
+ "phaseLabel": "Etiqueta de fase",
+ "enterPhaseName": "Digite um nome para o rรณtulo da fase",
+ "addOption": "Adicionar Opรงรฃo",
+ "phaseOptions": "Opรงรตes de Fase:",
+ "dragToReorderPhases": "Arraste as fases para reordenรก-las. Cada fase pode ter uma cor diferente.",
+ "enterNewPhaseName": "Digite o novo nome da fase...",
+ "addPhase": "Adicionar Fase",
+ "noPhasesFound": "Nenhuma fase encontrada. Crie sua primeira fase acima.",
+ "deletePhase": "Excluir Fase",
+ "deletePhaseConfirm": "Tem certeza de que deseja excluir esta fase? Esta aรงรฃo nรฃo pode ser desfeita.",
+ "rename": "Renomear",
+ "delete": "Excluir",
+ "enterPhaseName": "Digite o nome da fase",
+ "selectColor": "Selecionar cor",
+ "managePhases": "Gerenciar Fases",
+ "close": "Fechar"
+}
diff --git a/worklenz-backend/src/public/locales/pt/project-drawer.json b/worklenz-backend/src/public/locales/pt/project-drawer.json
new file mode 100644
index 00000000..92e11964
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/project-drawer.json
@@ -0,0 +1,52 @@
+{
+ "createProject": "Criar Projeto",
+ "editProject": "Editar Projeto",
+ "enterCategoryName": "Insira um nome para a categoria",
+ "hitEnterToCreate": "Pressione enter para criar!",
+ "enterNotes": "Notas",
+ "youCanManageClientsUnderSettings": "Vocรช pode gerenciar clientes em Configuraรงรตes",
+ "addCategory": "Adicione uma categoria ao projeto",
+ "newCategory": "Nova Categoria",
+ "notes": "Notas",
+ "startDate": "Data de Inรญcio",
+ "endDate": "Data de Fim",
+ "estimateWorkingDays": "Estime os dias de trabalho",
+ "estimateManDays": "Estime os dias de trabalho",
+ "hoursPerDay": "Horas por dia",
+ "create": "Criar",
+ "update": "Atualizar",
+ "delete": "Excluir",
+ "typeToSearchClients": "Digite para buscar clientes",
+ "projectColor": "Cor do Projeto",
+ "pleaseEnterAName": "Por favor, insira um nome",
+ "enterProjectName": "Insira o nome do projeto",
+ "name": "Nome",
+ "status": "Estado",
+ "health": "Saรบde",
+ "category": "Categoria",
+ "projectManager": "Gerente de Projeto",
+ "client": "Cliente",
+ "deleteConfirmation": "Tem a certeza de que deseja excluir?",
+ "deleteConfirmationDescription": "Isso removerรก todos os dados associados e nรฃo pode ser desfeito.",
+ "yes": "Sim",
+ "no": "Nรฃo",
+ "createdAt": "Criado",
+ "updatedAt": "Atualizado",
+ "by": "por",
+ "add": "Adicionar",
+ "asClient": "como cliente",
+ "createClient": "Criar cliente",
+ "searchInputPlaceholder": "Pesquise por nome ou email",
+ "hoursPerDayValidationMessage": "As horas por dia devem ser um nรบmero entre 1 e 24",
+ "workingDaysValidationMessage": "Os dias de trabalho devem ser um nรบmero positivo",
+ "manDaysValidationMessage": "Os dias de homem devem ser um nรบmero positivo",
+ "noPermission": "Sem permissรฃo",
+ "progressSettings": "Configuraรงรตes de Progresso",
+ "manualProgress": "Progresso Manual",
+ "manualProgressTooltip": "Permitir atualizaรงรตes manuais de progresso para tarefas sem subtarefas",
+ "weightedProgress": "Progresso Ponderado",
+ "weightedProgressTooltip": "Calcular o progresso com base nos pesos das subtarefas",
+ "timeProgress": "Progresso Baseado em Tempo",
+ "timeProgressTooltip": "Calcular o progresso com base no tempo estimado",
+ "enterProjectKey": "Insira a chave do projeto"
+}
diff --git a/worklenz-backend/src/public/locales/pt/project-view-files.json b/worklenz-backend/src/public/locales/pt/project-view-files.json
new file mode 100644
index 00000000..61f1cb59
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/project-view-files.json
@@ -0,0 +1,14 @@
+{
+ "nameColumn": "Nome",
+ "attachedTaskColumn": "Tarefa Anexada",
+ "sizeColumn": "Tamanho",
+ "uploadedByColumn": "Enviado Por",
+ "uploadedAtColumn": "Enviado Em",
+ "fileIconAlt": "รcone do Arquivo",
+ "titleDescriptionText": "Todos os anexos das tarefas neste projeto aparecerรฃo aqui.",
+ "deleteConfirmationTitle": "Tem certeza?",
+ "deleteConfirmationOk": "Sim",
+ "deleteConfirmationCancel": "Cancelar",
+ "segmentedTooltip": "Em breve! Alterne entre a visualizaรงรฃo em lista e a visualizaรงรฃo em miniatura.",
+ "emptyText": "Nรฃo hรก anexos no projeto."
+}
diff --git a/worklenz-backend/src/public/locales/pt/project-view-insights.json b/worklenz-backend/src/public/locales/pt/project-view-insights.json
new file mode 100644
index 00000000..2ad6ee92
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/project-view-insights.json
@@ -0,0 +1,41 @@
+{
+ "overview": {
+ "title": "Visรฃo Geral",
+ "statusOverview": "Visรฃo Geral do Status",
+ "priorityOverview": "Visรฃo Geral da Prioridade",
+ "lastUpdatedTasks": "รltimas Tarefas Atualizadas"
+ },
+ "members": {
+ "title": "Membros",
+ "tooltip": "Membros",
+ "tasksByMembers": "Tarefas por membros",
+ "tasksByMembersTooltip": "Tarefas por membros",
+ "name": "Nome",
+ "taskCount": "Contagem de Tarefas",
+ "contribution": "Contribuiรงรฃo",
+ "completed": "Concluรญdo",
+ "incomplete": "Incompleto",
+ "overdue": "Atrasado",
+ "progress": "Progresso"
+ },
+ "tasks": {
+ "overdueTasks": "Tarefas Atrasadas",
+ "overLoggedTasks": "Tarefas com excesso de tempo registrado",
+ "tasksCompletedEarly": "Tarefas concluรญdas cedo",
+ "tasksCompletedLate": "Tarefas concluรญdas tarde",
+ "overLoggedTasksTooltip": "Tarefas que tรชm tempo registrado alรฉm do tempo estimado",
+ "overdueTasksTooltip": "Tarefas que estรฃo atrasadas"
+ },
+ "common": {
+ "seeAll": "Ver tudo",
+ "totalLoggedHours": "Total de horas registradas",
+ "totalEstimation": "Total de estimativa",
+ "completedTasks": "Tarefas concluรญdas",
+ "incompleteTasks": "Tarefas incompletas",
+ "overdueTasks": "Tarefas atrasadas",
+ "overdueTasksTooltip": "Tarefas que estรฃo atrasadas",
+ "totalLoggedHoursTooltip": "Estimativa de tarefas e tempo registrado.",
+ "includeArchivedTasks": "Incluir Tarefas Arquivadas",
+ "export": "Exportar"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/pt/project-view-members.json b/worklenz-backend/src/public/locales/pt/project-view-members.json
new file mode 100644
index 00000000..72524807
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/project-view-members.json
@@ -0,0 +1,17 @@
+{
+ "nameColumn": "Nome",
+ "jobTitleColumn": "Tรญtulo do Cargo",
+ "emailColumn": "Email",
+ "tasksColumn": "Tarefas",
+ "taskProgressColumn": "Progresso da Tarefa",
+ "accessColumn": "Acesso",
+ "fileIconAlt": "รcone do Arquivo",
+ "deleteConfirmationTitle": "Tem a certeza?",
+ "deleteConfirmationOk": "Sim",
+ "deleteConfirmationCancel": "Cancelar",
+ "refreshButtonTooltip": "Atualizar membros",
+ "deleteButtonTooltip": "Remover do projeto",
+ "memberCount": "Membro",
+ "membersCountPlural": "Membros",
+ "emptyText": "Nรฃo hรก anexos no projeto."
+}
diff --git a/worklenz-backend/src/public/locales/pt/project-view-updates.json b/worklenz-backend/src/public/locales/pt/project-view-updates.json
new file mode 100644
index 00000000..93a48950
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/project-view-updates.json
@@ -0,0 +1,6 @@
+{
+ "inputPlaceholder": "Adicione um comentรกrio..",
+ "addButton": "Adicionar",
+ "cancelButton": "Cancelar",
+ "deleteButton": "Deletar"
+}
diff --git a/worklenz-backend/src/public/locales/pt/project-view.json b/worklenz-backend/src/public/locales/pt/project-view.json
new file mode 100644
index 00000000..c58337da
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/project-view.json
@@ -0,0 +1,14 @@
+{
+ "taskList": "Lista de Tarefas",
+ "board": "Quadro Kanban",
+ "insights": "Insights",
+ "files": "Arquivos",
+ "members": "Membros",
+ "updates": "Atualizaรงรตes",
+ "projectView": "Visualizaรงรฃo do Projeto",
+ "loading": "Carregando projeto...",
+ "error": "Erro ao carregar projeto",
+ "pinnedTab": "Fixada como aba padrรฃo",
+ "pinTab": "Fixar como aba padrรฃo",
+ "unpinTab": "Desfixar aba padrรฃo"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/pt/project-view/import-task-templates.json b/worklenz-backend/src/public/locales/pt/project-view/import-task-templates.json
new file mode 100644
index 00000000..81a64607
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/project-view/import-task-templates.json
@@ -0,0 +1,11 @@
+{
+ "importTaskTemplate": "Importar modelo de tarefa",
+ "templateName": "Nome do modelo",
+ "templateDescription": "Descriรงรฃo do modelo",
+ "selectedTasks": "Tarefas selecionadas",
+ "tasks": "Tarefas",
+ "templates": "Modelos",
+ "remove": "Remover",
+ "cancel": "Cancelar",
+ "import": "Importar"
+}
diff --git a/worklenz-backend/src/public/locales/pt/project-view/project-member-drawer.json b/worklenz-backend/src/public/locales/pt/project-view/project-member-drawer.json
new file mode 100644
index 00000000..0afe3d87
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/project-view/project-member-drawer.json
@@ -0,0 +1,7 @@
+{
+ "title": "Membros do Projeto",
+ "searchLabel": "Adicionar membros inserindo nome ou e-mail",
+ "searchPlaceholder": "Digite nome ou e-mail",
+ "inviteAsAMember": "Convidar como membro",
+ "inviteNewMemberByEmail": "Convidar novo membro por e-mail"
+}
diff --git a/worklenz-backend/src/public/locales/pt/project-view/project-view-header.json b/worklenz-backend/src/public/locales/pt/project-view/project-view-header.json
new file mode 100644
index 00000000..4649b768
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/project-view/project-view-header.json
@@ -0,0 +1,30 @@
+{
+ "importTasks": "Importar tarefas",
+ "importTask": "Importar tarefa",
+ "createTask": "Criar tarefa",
+ "settings": "Configuraรงรตes",
+ "subscribe": "Inscrever-se",
+ "unsubscribe": "Cancelar inscriรงรฃo",
+ "deleteProject": "Excluir projeto",
+ "startDate": "Data de inรญcio",
+ "endDate": "Data de tรฉrmino",
+ "projectSettings": "Configuraรงรตes do projeto",
+ "projectSummary": "Resumo do projeto",
+ "receiveProjectSummary": "Receba um resumo do projeto todas as noites.",
+ "refreshProject": "Atualizar projeto",
+ "saveAsTemplate": "Salvar como modelo",
+ "invite": "Convidar",
+ "share": "Compartilhar",
+ "subscribeTooltip": "Inscrever-se nas notificaรงรตes do projeto",
+ "unsubscribeTooltip": "Cancelar inscriรงรฃo nas notificaรงรตes do projeto",
+ "refreshTooltip": "Atualizar dados do projeto",
+ "settingsTooltip": "Abrir configuraรงรตes do projeto",
+ "saveAsTemplateTooltip": "Salvar este projeto como modelo",
+ "inviteTooltip": "Convidar membros da equipe para este projeto",
+ "createTaskTooltip": "Criar uma nova tarefa",
+ "importTaskTooltip": "Importar tarefa de modelo",
+ "navigateBackTooltip": "Voltar para lista de projetos",
+ "projectStatusTooltip": "Status do projeto",
+ "projectDatesInfo": "Informaรงรตes do cronograma do projeto",
+ "projectCategoryTooltip": "Categoria do projeto"
+}
diff --git a/worklenz-backend/src/public/locales/pt/project-view/save-as-template.json b/worklenz-backend/src/public/locales/pt/project-view/save-as-template.json
new file mode 100644
index 00000000..c67eb20e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/project-view/save-as-template.json
@@ -0,0 +1,27 @@
+{
+ "title": "Salvar como Modelo",
+ "templateName": "Nome do Modelo",
+ "includes": "O que deve ser incluรญdo no modelo do projeto?",
+ "includesOptions": {
+ "statuses": "Status",
+ "phases": "Fases",
+ "labels": "Etiquetas"
+ },
+ "taskIncludes": "O que deve ser incluรญdo no modelo das tarefas?",
+ "taskIncludesOptions": {
+ "statuses": "Status",
+ "phases": "Fases",
+ "labels": "Etiquetas",
+ "name": "Nome",
+ "priority": "Prioridade",
+ "status": "Status",
+ "phase": "Fase",
+ "label": "Etiqueta",
+ "timeEstimate": "Estimativa de Tempo",
+ "description": "Descriรงรฃo",
+ "subTasks": "Subtarefas"
+ },
+ "cancel": "Cancelar",
+ "save": "Salvar",
+ "templateNamePlaceholder": "Digite o nome do modelo"
+}
diff --git a/worklenz-backend/src/public/locales/pt/reporting-members-drawer.json b/worklenz-backend/src/public/locales/pt/reporting-members-drawer.json
new file mode 100644
index 00000000..49d0008b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/reporting-members-drawer.json
@@ -0,0 +1,90 @@
+{
+ "exportButton": "Exportar",
+ "timeLogsButton": "Registros de Tempo",
+ "activityLogsButton": "Registros de Atividade",
+ "tasksButton": "Tarefas",
+ "searchByNameInputPlaceholder": "Pesquisar por nome",
+
+ "overviewTab": "Visรฃo Geral",
+ "timeLogsTab": "Registros de Tempo",
+ "activityLogsTab": "Registros de Atividade",
+ "tasksTab": "Tarefas",
+
+ "projectsText": "Projetos",
+ "totalTasksText": "Total de Tarefas",
+ "assignedTasksText": "Tarefas Atribuรญdas",
+ "completedTasksText": "Tarefas Concluรญdas",
+ "ongoingTasksText": "Tarefas em Andamento",
+ "overdueTasksText": "Tarefas Atrasadas",
+ "loggedHoursText": "Horas Registradas",
+
+ "tasksText": "Tarefas",
+ "allText": "Todas",
+
+ "tasksByProjectsText": "Tarefas Por Projetos",
+ "tasksByStatusText": "Tarefas Por Status",
+ "tasksByPriorityText": "Tarefas Por Prioridade",
+
+ "todoText": "A Fazer",
+ "doingText": "Fazendo",
+ "doneText": "Feita",
+ "lowText": "Baixa",
+ "mediumText": "Mรฉdia",
+ "highText": "Alta",
+
+ "billableButton": "Cobrรกvel",
+ "billableText": "Cobrรกvel",
+ "nonBillableText": "Nรฃo Cobrรกvel",
+
+ "timeLogsEmptyPlaceholder": "Nenhum registro de tempo para mostrar",
+ "loggedText": "Registrado",
+ "forText": "para",
+ "inText": "em",
+ "updatedText": "Atualizado",
+ "fromText": "De",
+ "toText": "atรฉ",
+ "withinText": "dentro de",
+
+ "activityLogsEmptyPlaceholder": "Nenhum registro de atividade para mostrar",
+
+ "filterByText": "Filtrar por:",
+ "selectProjectPlaceholder": "Selecione o Projeto",
+
+ "taskColumn": "Tarefa",
+ "nameColumn": "Nome",
+ "projectColumn": "Projeto",
+ "statusColumn": "Status",
+ "priorityColumn": "Prioridade",
+ "dueDateColumn": "Data de Vencimento",
+ "completedDateColumn": "Data de Conclusรฃo",
+ "estimatedTimeColumn": "Tempo Estimado",
+ "loggedTimeColumn": "Tempo Registrado",
+ "overloggedTimeColumn": "Tempo Excedido",
+ "daysLeftColumn": "Dias Restantes/Atrasados",
+ "startDateColumn": "Data de Inรญcio",
+ "endDateColumn": "Data de Fim",
+ "actualTimeColumn": "Tempo Real",
+ "projectHealthColumn": "Saรบde do Projeto",
+ "categoryColumn": "Categoria",
+ "projectManagerColumn": "Gerente do Projeto",
+
+ "tasksStatsOverviewDrawerTitle": "Tarefas de",
+ "projectsStatsOverviewDrawerTitle": "Projetos de",
+
+ "cancelledText": "Cancelada",
+ "blockedText": "Bloqueada",
+ "onHoldText": "Em Espera",
+ "proposedText": "Proposta",
+ "inPlanningText": "Em Planejamento",
+ "inProgressText": "Em Progresso",
+ "completedText": "Concluรญda",
+ "continuousText": "Contรญnua",
+
+ "daysLeftText": "dias restantes",
+ "daysOverdueText": "dias atrasados",
+
+ "notSetText": "Nรฃo Definido",
+ "needsAttentionText": "Precisa de Atenรงรฃo",
+ "atRiskText": "Em Risco",
+ "goodText": "Bom"
+}
diff --git a/worklenz-backend/src/public/locales/pt/reporting-members.json b/worklenz-backend/src/public/locales/pt/reporting-members.json
new file mode 100644
index 00000000..a8035dcd
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/reporting-members.json
@@ -0,0 +1,35 @@
+{
+ "yesterdayText": "Yesterday",
+ "lastSevenDaysText": "Last 7 Days",
+ "lastWeekText": "Last Week",
+ "lastThirtyDaysText": "Last 30 Days",
+ "lastMonthText": "Last Month",
+ "lastThreeMonthsText": "Last 3 Months",
+ "allTimeText": "All Time",
+ "customRangeText": "Custom range",
+ "startDateInputPlaceholder": "Start date",
+ "EndDateInputPlaceholder": "End date",
+ "filterButton": "Filter",
+
+ "membersTitle": "Members",
+ "includeArchivedButton": "Include Archived Projects",
+ "exportButton": "Export",
+ "excelButton": "Excel",
+ "searchByNameInputPlaceholder": "Search by name",
+
+ "memberColumn": "Member",
+ "tasksProgressColumn": "Tasks Progress",
+ "tasksAssignedColumn": "Tasks Assigned",
+ "completedTasksColumn": "Completed Tasks",
+ "overdueTasksColumn": "Overdue Tasks",
+ "ongoingTasksColumn": "Ongoing Tasks",
+
+ "tasksAssignedColumnTooltip": "Tasks assigned on selected date range",
+ "overdueTasksColumnTooltip": "Tasks overdue for end of the selected date range",
+ "completedTasksColumnTooltip": "Tasks completed on selected date range",
+ "ongoingTasksColumnTooltip": "Started tasks not completed yet",
+
+ "todoText": "To Do",
+ "doingText": "Doing",
+ "doneText": "Done"
+}
diff --git a/worklenz-backend/src/public/locales/pt/reporting-overview-drawer.json b/worklenz-backend/src/public/locales/pt/reporting-overview-drawer.json
new file mode 100644
index 00000000..af8b06ee
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/reporting-overview-drawer.json
@@ -0,0 +1,39 @@
+{
+ "exportButton": "Exportar",
+ "projectsButton": "Projetos",
+ "membersButton": "Membros",
+ "searchByNameInputPlaceholder": "Pesquisar por nome",
+
+ "overviewTab": "Visรฃo Geral",
+ "projectsTab": "Projetos",
+ "membersTab": "Membros",
+
+ "projectsByStatusText": "Projetos Por Status",
+ "projectsByCategoryText": "Projetos Por Categoria",
+ "projectsByHealthText": "Projetos Por Saรบde",
+
+ "projectsText": "Projetos",
+ "allText": "Todos",
+
+ "cancelledText": "Cancelado",
+ "blockedText": "Bloqueado",
+ "onHoldText": "Em Espera",
+ "proposedText": "Proposto",
+ "inPlanningText": "Em Planejamento",
+ "inProgressText": "Em Andamento",
+ "completedText": "Concluรญdo",
+ "continuousText": "Contรญnuo",
+
+ "notSetText": "Nรฃo Definido",
+ "needsAttentionText": "Necessita de Atenรงรฃo",
+ "atRiskText": "Em Risco",
+ "goodText": "Bom",
+
+ "nameColumn": "Nome",
+ "emailColumn": "Email",
+ "projectsColumn": "Projetos",
+ "tasksColumn": "Tarefas",
+ "overdueTasksColumn": "Tarefas Atrasadas",
+ "completedTasksColumn": "Tarefas Concluรญdas",
+ "ongoingTasksColumn": "Tarefas em Andamento"
+}
diff --git a/worklenz-backend/src/public/locales/pt/reporting-overview.json b/worklenz-backend/src/public/locales/pt/reporting-overview.json
new file mode 100644
index 00000000..01681d1a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/reporting-overview.json
@@ -0,0 +1,25 @@
+{
+ "overviewTitle": "Visรฃo Geral",
+ "includeArchivedButton": "Incluir Projetos Arquivados",
+
+ "teamCount": "Equipe",
+ "teamCountPlural": "Equipes",
+ "projectCount": "Projeto",
+ "projectCountPlural": "Projetos",
+ "memberCount": "Membro",
+ "memberCountPlural": "Membros",
+ "activeProjectCount": "Projeto Ativo",
+ "activeProjectCountPlural": "Projetos Ativos",
+ "overdueProjectCount": "Projeto Atrasado",
+ "overdueProjectCountPlural": "Projetos Atrasados",
+ "unassignedMemberCount": "Membro Nรฃo Atribuรญdo",
+ "unassignedMemberCountPlural": "Membros Nรฃo Atribuรญdos",
+ "memberWithOverdueTaskCount": "Membro Com Tarefa Atrasada",
+ "memberWithOverdueTaskCountPlural": "Membros Com Tarefas Atrasadas",
+
+ "teamsText": "Equipes",
+
+ "nameColumn": "Nome",
+ "projectsColumn": "Projetos",
+ "membersColumn": "Membros"
+}
diff --git a/worklenz-backend/src/public/locales/pt/reporting-projects-drawer.json b/worklenz-backend/src/public/locales/pt/reporting-projects-drawer.json
new file mode 100644
index 00000000..14bcfaca
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/reporting-projects-drawer.json
@@ -0,0 +1,59 @@
+{
+ "exportButton": "Exportar",
+ "membersButton": "Membros",
+ "tasksButton": "Tarefas",
+ "searchByNameInputPlaceholder": "Pesquisar por nome",
+
+ "overviewTab": "Visรฃo Geral",
+ "membersTab": "Membros",
+ "tasksTab": "Tarefas",
+
+ "completedTasksText": "Tarefas Concluรญdas",
+ "incompleteTasksText": "Tarefas Incompletas",
+ "overdueTasksText": "Tarefas Atrasadas",
+ "allocatedHoursText": "Horas Alocadas",
+ "loggedHoursText": "Horas Registradas",
+
+ "tasksText": "Tarefas",
+ "allText": "Todas",
+
+ "tasksByStatusText": "Tarefas Por Status",
+ "tasksByPriorityText": "Tarefas Por Prioridade",
+ "tasksByDueDateText": "Tarefas Por Data de Vencimento",
+
+ "todoText": "A Fazer",
+ "doingText": "Fazendo",
+ "doneText": "Feita",
+ "lowText": "Baixa",
+ "mediumText": "Mรฉdia",
+ "highText": "Alta",
+ "completedText": "Concluรญda",
+ "upcomingText": "Prรณxima",
+ "overdueText": "Atrasada",
+ "noDueDateText": "Sem Data de Vencimento",
+
+ "nameColumn": "Nome",
+ "tasksCountColumn": "Contagem de Tarefas",
+ "completedTasksColumn": "Tarefas Concluรญdas",
+ "incompleteTasksColumn": "Tarefas Incompletas",
+ "overdueTasksColumn": "Tarefas Atrasadas",
+ "contributionColumn": "Contribuiรงรฃo",
+ "progressColumn": "Progresso",
+ "loggedTimeColumn": "Tempo Registrado",
+ "taskColumn": "Tarefa",
+ "projectColumn": "Projeto",
+ "statusColumn": "Status",
+ "priorityColumn": "Prioridade",
+ "phaseColumn": "Fase",
+ "dueDateColumn": "Data de Vencimento",
+ "completedDateColumn": "Data de Conclusรฃo",
+ "estimatedTimeColumn": "Tempo Estimado",
+ "overloggedTimeColumn": "Tempo Excedido",
+ "completedOnColumn": "Concluรญdo Em",
+ "daysOverdueColumn": "Dias Atrasados",
+
+ "groupByText": "Agrupar Por:",
+ "statusText": "Status",
+ "priorityText": "Prioridade",
+ "phaseText": "Fase"
+}
diff --git a/worklenz-backend/src/public/locales/pt/reporting-projects-filters.json b/worklenz-backend/src/public/locales/pt/reporting-projects-filters.json
new file mode 100644
index 00000000..5d47d282
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/reporting-projects-filters.json
@@ -0,0 +1,35 @@
+{
+ "searchByNamePlaceholder": "Pesquisar por nome",
+ "searchByCategoryPlaceholder": "Pesquisar por categoria",
+
+ "statusText": "Status",
+ "healthText": "Saรบde",
+ "categoryText": "Categoria",
+ "projectManagerText": "Gerente de Projeto",
+ "showFieldsText": "Mostrar campos",
+
+ "cancelledText": "Cancelado",
+ "blockedText": "Bloqueado",
+ "onHoldText": "Em Espera",
+ "proposedText": "Proposto",
+ "inPlanningText": "Em Planejamento",
+ "inProgressText": "Em Andamento",
+ "completedText": "Concluรญdo",
+ "continuousText": "Contรญnuo",
+
+ "notSetText": "Nรฃo Definido",
+ "needsAttentionText": "Precisa de Atenรงรฃo",
+ "atRiskText": "Em Risco",
+ "goodText": "Bom",
+
+ "nameText": "Projeto",
+ "estimatedVsActualText": "Estimado Vs Real",
+ "tasksProgressText": "Progresso das Tarefas",
+ "lastActivityText": "รltima Atividade",
+ "datesText": "Datas de Inรญcio/Fim",
+ "daysLeftText": "Dias Restantes/Atrasados",
+ "projectHealthText": "Saรบde do Projeto",
+ "projectUpdateText": "Atualizaรงรฃo do Projeto",
+ "clientText": "Cliente",
+ "teamText": "Equipe"
+}
diff --git a/worklenz-backend/src/public/locales/pt/reporting-projects.json b/worklenz-backend/src/public/locales/pt/reporting-projects.json
new file mode 100644
index 00000000..c5035b54
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/reporting-projects.json
@@ -0,0 +1,52 @@
+{
+ "projectCount": "Projeto",
+ "projectCountPlural": "Projetos",
+ "includeArchivedButton": "Incluir Projetos Arquivados",
+ "exportButton": "Exportar",
+ "excelButton": "Excel",
+
+ "projectColumn": "Projeto",
+ "estimatedVsActualColumn": "Estimado Vs Real",
+ "tasksProgressColumn": "Progresso das Tarefas",
+ "lastActivityColumn": "รltima Atividade",
+ "statusColumn": "Status",
+ "datesColumn": "Datas de Inรญcio/Fim",
+ "daysLeftColumn": "Dias Restantes/Atrasados",
+ "projectHealthColumn": "Saรบde do Projeto",
+ "categoryColumn": "Categoria",
+ "projectUpdateColumn": "Atualizaรงรฃo do Projeto",
+ "clientColumn": "Cliente",
+ "teamColumn": "Equipe",
+ "projectManagerColumn": "Gerente de Projeto",
+
+ "openButton": "Abrir",
+
+ "estimatedText": "Estimado",
+ "actualText": "Real",
+
+ "todoText": "A Fazer",
+ "doingText": "Fazendo",
+ "doneText": "Feito",
+
+ "cancelledText": "Cancelado",
+ "blockedText": "Bloqueado",
+ "onHoldText": "Em Espera",
+ "proposedText": "Proposto",
+ "inPlanningText": "Em Planejamento",
+ "inProgressText": "Em Andamento",
+ "completedText": "Concluรญdo",
+ "continuousText": "Contรญnuo",
+
+ "daysLeftText": "dias restantes",
+ "dayLeftText": "dia restante",
+ "daysOverdueText": "dias atrasados",
+
+ "notSetText": "Nรฃo Definido",
+ "needsAttentionText": "Precisa de Atenรงรฃo",
+ "atRiskText": "Em Risco",
+ "goodText": "Bom",
+
+ "setCategoryText": "Definir Categoria",
+ "searchByNameInputPlaceholder": "Pesquisar por nome",
+ "todayText": "Hoje"
+}
diff --git a/worklenz-backend/src/public/locales/pt/reporting-sidebar.json b/worklenz-backend/src/public/locales/pt/reporting-sidebar.json
new file mode 100644
index 00000000..e09940f3
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/reporting-sidebar.json
@@ -0,0 +1,8 @@
+{
+ "overviewText": "Visรฃo Geral",
+ "projectsText": "Projetos",
+ "membersText": "Membros",
+ "timeReportsText": "Relatรณrios de Tempo",
+ "estimateVsActualText": "Estimado Vs Real",
+ "currentOrganizationTooltip": "Organizaรงรฃo Atual"
+}
diff --git a/worklenz-backend/src/public/locales/pt/schedule.json b/worklenz-backend/src/public/locales/pt/schedule.json
new file mode 100644
index 00000000..c2d9fed6
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/schedule.json
@@ -0,0 +1,39 @@
+{
+ "today": "Hoje",
+ "week": "Semana",
+ "month": "Mรชs",
+
+ "settings": "Configuraรงรตes",
+ "workingDays": "Dias de Trabalho",
+ "monday": "Segunda-feira",
+ "tuesday": "Terรงa-feira",
+ "wednesday": "Quarta-feira",
+ "thursday": "Quinta-feira",
+ "friday": "Sexta-feira",
+ "saturday": "Sรกbado",
+ "sunday": "Domingo",
+ "workingHours": "Horas de Trabalho",
+ "hours": "horas",
+ "saveButton": "Salvar",
+
+ "totalAllocation": "Alocaรงรฃo Total",
+ "timeLogged": "Tempo Registrado",
+ "remainingTime": "Tempo Restante",
+ "total": "Total",
+ "perDay": "Por Dia",
+ "tasks": "tarefas",
+ "startDate": "Data de Inรญcio",
+ "endDate": "Data de Fim",
+
+ "hoursPerDay": "Horas Por Dia",
+ "totalHours": "Horas Totais",
+ "deleteButton": "Excluir",
+ "cancelButton": "Cancelar",
+
+ "tabTitle": "Tarefa sem Data de Inรญcio & Fim",
+
+ "allocatedTime": "Tempo Alocado",
+ "totalLogged": "Total Registrado",
+ "loggedBillable": "Registrado Faturรกvel",
+ "loggedNonBillable": "Registrado Nรฃo Faturรกvel"
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/appearance.json b/worklenz-backend/src/public/locales/pt/settings/appearance.json
new file mode 100644
index 00000000..13e5a1e6
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/appearance.json
@@ -0,0 +1,5 @@
+{
+ "title": "Aparรชncia",
+ "darkMode": "Modo Escuro",
+ "darkModeDescription": "Alterne entre o modo claro e escuro para personalizar sua experiรชncia de visualizaรงรฃo."
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/categories.json b/worklenz-backend/src/public/locales/pt/settings/categories.json
new file mode 100644
index 00000000..9972d2a9
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/categories.json
@@ -0,0 +1,10 @@
+{
+ "categoryColumn": "Categoria",
+ "deleteConfirmationTitle": "Tem a certeza?",
+ "deleteConfirmationOk": "Sim",
+ "deleteConfirmationCancel": "Cancelar",
+ "associatedTaskColumn": "Tarefa Associada",
+ "searchPlaceholder": "Pesquisar por nome",
+ "emptyText": "As categorias podem ser criadas ao atualizar ou criar projetos.",
+ "colorChangeTooltip": "Clique para mudar a cor"
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/change-password.json b/worklenz-backend/src/public/locales/pt/settings/change-password.json
new file mode 100644
index 00000000..07b993dd
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/change-password.json
@@ -0,0 +1,15 @@
+{
+ "title": "Alterar Senha",
+ "currentPassword": "Senha Atual",
+ "newPassword": "Nova Senha",
+ "confirmPassword": "Confirmar Senha",
+ "currentPasswordPlaceholder": "Digite sua senha atual",
+ "newPasswordPlaceholder": "Nova Senha",
+ "confirmPasswordPlaceholder": "Confirmar Senha",
+ "currentPasswordRequired": "Por favor, digite sua senha atual!",
+ "newPasswordRequired": "Por favor, digite sua nova senha!",
+ "passwordValidationError": "A senha deve ter pelo menos 8 caracteres com uma letra maiรบscula, um nรบmero e um sรญmbolo.",
+ "passwordMismatch": "As senhas nรฃo coincidem!",
+ "passwordRequirements": "A nova senha deve ter no mรญnimo 8 caracteres, com uma letra maiรบscula, um nรบmero e um sรญmbolo.",
+ "updateButton": "Atualizar Senha"
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/clients.json b/worklenz-backend/src/public/locales/pt/settings/clients.json
new file mode 100644
index 00000000..932a7f5e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/clients.json
@@ -0,0 +1,22 @@
+{
+ "nameColumn": "Nome",
+ "projectColumn": "Projeto",
+ "noProjectsAvailable": "Nenhum projeto disponรญvel",
+ "deleteConfirmationTitle": "Tem a certeza?",
+ "deleteConfirmationOk": "Sim",
+ "deleteConfirmationCancel": "Cancelar",
+ "searchPlaceholder": "Pesquisar por nome",
+ "createClient": "Criar Cliente",
+ "pinTooltip": "Clique para fixar isso no menu principal",
+ "createClientDrawerTitle": "Criar Cliente",
+ "updateClientDrawerTitle": "Atualizar Cliente",
+ "nameLabel": "Nome",
+ "namePlaceholder": "Nome",
+ "nameRequiredError": "Por favor, insira um Nome",
+ "createButton": "Criar",
+ "updateButton": "Atualizar",
+ "createClientSuccessMessage": "Criar cliente sucesso!",
+ "createClientErrorMessage": "Criar cliente falhou!",
+ "updateClientSuccessMessage": "Atualizar cliente sucesso!",
+ "updateClientErrorMessage": "Atualizar cliente falhou!"
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/job-titles.json b/worklenz-backend/src/public/locales/pt/settings/job-titles.json
new file mode 100644
index 00000000..379ddc03
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/job-titles.json
@@ -0,0 +1,20 @@
+{
+ "nameColumn": "Nome",
+ "deleteConfirmationTitle": "Tem a certeza?",
+ "deleteConfirmationOk": "Sim",
+ "deleteConfirmationCancel": "Cancelar",
+ "searchPlaceholder": "Pesquisar por nome",
+ "createJobTitleButton": "Criar Tรญtulo de Emprego",
+ "pinTooltip": "Clique para fixar isso no menu principal",
+ "createJobTitleDrawerTitle": "Criar Tรญtulo de Emprego",
+ "updateJobTitleDrawerTitle": "Atualizar Tรญtulo de Emprego",
+ "nameLabel": "Nome",
+ "namePlaceholder": "Nome",
+ "nameRequiredError": "Por favor, insira um Nome",
+ "createButton": "Criar",
+ "updateButton": "Atualizar",
+ "createJobTitleSuccessMessage": "Criar tรญtulo de emprego com sucesso!",
+ "createJobTitleErrorMessage": "Falha ao criar tรญtulo de emprego!",
+ "updateJobTitleSuccessMessage": "Atualizar tรญtulo de emprego com sucesso!",
+ "updateJobTitleErrorMessage": "Falha ao atualizar tรญtulo de emprego!"
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/labels.json b/worklenz-backend/src/public/locales/pt/settings/labels.json
new file mode 100644
index 00000000..737dccef
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/labels.json
@@ -0,0 +1,11 @@
+{
+ "labelColumn": "Rรณtulo",
+ "deleteConfirmationTitle": "Tem a certeza?",
+ "deleteConfirmationOk": "Sim",
+ "deleteConfirmationCancel": "Cancelar",
+ "associatedTaskColumn": "Contagem de Tarefas Associadas",
+ "searchPlaceholder": "Pesquisar por nome",
+ "emptyText": "Os rรณtulos podem ser criados ao atualizar ou criar tarefas.",
+ "pinTooltip": "Clique para fixar isso no menu principal",
+ "colorChangeTooltip": "Clique para mudar a cor"
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/language.json b/worklenz-backend/src/public/locales/pt/settings/language.json
new file mode 100644
index 00000000..f4494ff3
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/language.json
@@ -0,0 +1,7 @@
+{
+ "language": "Idioma",
+ "language_required": "O idioma รฉ obrigatรณrio",
+ "time_zone": "Fuso horรกrio",
+ "time_zone_required": "O fuso horรกrio รฉ obrigatรณrio",
+ "save_changes": "Salvar alteraรงรตes"
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/notifications.json b/worklenz-backend/src/public/locales/pt/settings/notifications.json
new file mode 100644
index 00000000..5a61cdf0
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/notifications.json
@@ -0,0 +1,10 @@
+{
+ "emailTitle": "Envie-me notificaรงรตes por email",
+ "emailDescription": "Isso inclui novas atribuiรงรตes de tarefas",
+ "dailyDigestTitle": "Envie-me um resumo diรกrio",
+ "dailyDigestDescription": "Toda noite, vocรช receberรก um resumo da atividade recente nas tarefas.",
+ "popupTitle": "Notificaรงรตes pop-up no meu computador quando o Worklenz estรก aberto",
+ "popupDescription": "As notificaรงรตes pop-up podem ser desativadas pelo seu navegador. Altere as configuraรงรตes do seu navegador para permiti-las.",
+ "unreadItemsTitle": "Mostrar o nรบmero de itens nรฃo lidos",
+ "unreadItemsDescription": "Vocรช verรก contagens para cada notificaรงรฃo."
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/profile.json b/worklenz-backend/src/public/locales/pt/settings/profile.json
new file mode 100644
index 00000000..3a4a8447
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/profile.json
@@ -0,0 +1,14 @@
+{
+ "uploadError": "Vocรช sรณ pode fazer upload de arquivos JPG/PNG!",
+ "uploadSizeError": "A imagem deve ser menor que 2MB!",
+ "upload": "Carregar",
+ "nameLabel": "Nome",
+ "nameRequiredError": "Nome รฉ obrigatรณrio",
+ "emailLabel": "Email",
+ "emailRequiredError": "Email รฉ obrigatรณrio",
+ "saveChanges": "Salvar Alteraรงรตes",
+ "profileJoinedText": "Entrou hรก um mรชs",
+ "profileLastUpdatedText": "รltima atualizaรงรฃo hรก um mรชs",
+ "avatarTooltip": "Clique para carregar um avatar",
+ "title": "Configuraรงรตes do Perfil"
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/project-templates.json b/worklenz-backend/src/public/locales/pt/settings/project-templates.json
new file mode 100644
index 00000000..55546630
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/project-templates.json
@@ -0,0 +1,8 @@
+{
+ "nameColumn": "Nome",
+ "editToolTip": "Editar",
+ "deleteToolTip": "Excluir",
+ "confirmText": "Tem a certeza?",
+ "okText": "Sim",
+ "cancelText": "Cancelar"
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/sidebar.json b/worklenz-backend/src/public/locales/pt/settings/sidebar.json
new file mode 100644
index 00000000..0cb663f1
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/sidebar.json
@@ -0,0 +1,15 @@
+{
+ "profile": "Perfil",
+ "notifications": "Notificaรงรตes",
+ "clients": "Clientes",
+ "job-titles": "Tรญtulos de Emprego",
+ "labels": "Rรณtulos",
+ "categories": "Categorias",
+ "project-templates": "Modelos de Projeto",
+ "task-templates": "Modelos de Tarefa",
+ "team-members": "Membros da Equipe",
+ "teams": "Equipes",
+ "change-password": "Alterar Senha",
+ "language-and-region": "Idioma e Regiรฃo",
+ "appearance": "Aparรชncia"
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/task-templates.json b/worklenz-backend/src/public/locales/pt/settings/task-templates.json
new file mode 100644
index 00000000..fb501000
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/task-templates.json
@@ -0,0 +1,9 @@
+{
+ "nameColumn": "Nome",
+ "createdColumn": "Criado",
+ "editToolTip": "Editar",
+ "deleteToolTip": "Excluir",
+ "confirmText": "Tem a certeza?",
+ "okText": "Sim",
+ "cancelText": "Cancelar"
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/team-members.json b/worklenz-backend/src/public/locales/pt/settings/team-members.json
new file mode 100644
index 00000000..9ace1764
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/team-members.json
@@ -0,0 +1,47 @@
+{
+ "title": "Membros da Equipe",
+ "nameColumn": "Nome",
+ "projectsColumn": "Projetos",
+ "emailColumn": "Email",
+ "teamAccessColumn": "Acesso ร Equipe",
+ "memberCount": "Membro",
+ "membersCountPlural": "Membros",
+ "searchPlaceholder": "Pesquisar membros pelo nome",
+ "pinTooltip": "Atualizar lista de membros",
+ "addMemberButton": "Adicionar Novo Membro",
+ "editTooltip": "Editar membro",
+ "deactivateTooltip": "Desativar membro",
+ "activateTooltip": "Ativar membro",
+ "deleteTooltip": "Deletar membro",
+ "confirmDeleteTitle": "Tem a certeza de que deseja deletar este membro?",
+ "confirmActivateTitle": "Tem a certeza de que deseja alterar o status deste membro?",
+ "okText": "Sim, proceder",
+ "cancelText": "Nรฃo, cancelar",
+ "deactivatedText": "(Atualmente desativado)",
+ "pendingInvitationText": "(Convite pendente)",
+ "addMemberDrawerTitle": "Adicionar Novo Membro da Equipe",
+ "updateMemberDrawerTitle": "Atualizar Membro da Equipe",
+ "addMemberEmailHint": "Os membros serรฃo adicionados ร equipe independentemente do status de aceitaรงรฃo do convite",
+ "memberEmailLabel": "Endereรงo(s) de Email",
+ "memberEmailPlaceholder": "Insira o endereรงo de email do membro da equipe",
+ "memberEmailRequiredError": "Por favor, insira um email vรกlido",
+ "jobTitleLabel": "Tรญtulo do Emprego",
+ "jobTitlePlaceholder": "Selecione ou pesquise o tรญtulo do emprego (Opcional)",
+ "memberAccessLabel": "Nรญvel de Acesso",
+ "addToTeamButton": "Adicionar Membro ร Equipe",
+ "updateButton": "Salvar Alteraรงรตes",
+ "resendInvitationButton": "Redirecionar Email de Convite",
+ "invitationSentSuccessMessage": "Convite para a equipe enviado com sucesso!",
+ "createMemberSuccessMessage": "Novo membro da equipe adicionado com sucesso!",
+ "createMemberErrorMessage": "Falha ao adicionar membro da equipe. Por favor, tente novamente.",
+ "updateMemberSuccessMessage": "Membro da equipe atualizado com sucesso!",
+ "updateMemberErrorMessage": "Falha ao atualizar membro da equipe. Por favor, tente novamente.",
+ "memberText": "Membro da Equipe",
+ "adminText": "Administrador",
+ "ownerText": "Dono da Equipe",
+ "addedText": "Adicionado",
+ "updatedText": "Atualizado",
+ "noResultFound": "Digite um endereรงo de email e pressione enter...",
+ "jobTitlesFetchError": "Falha ao buscar cargos",
+ "invitationResent": "Convite reenviado com sucesso!"
+}
diff --git a/worklenz-backend/src/public/locales/pt/settings/teams.json b/worklenz-backend/src/public/locales/pt/settings/teams.json
new file mode 100644
index 00000000..e460318f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/settings/teams.json
@@ -0,0 +1,16 @@
+{
+ "title": "Equipes",
+ "team": "Equipe",
+ "teams": "Equipes",
+ "name": "Nome",
+ "created": "Criado",
+ "ownsBy": "Pertence a",
+ "edit": "Editar",
+ "editTeam": "Editar Equipe",
+ "pinTooltip": "Clique para fixar isso no menu principal",
+ "editTeamName": "Editar Nome da Equipe",
+ "updateName": "Atualizar Nome",
+ "namePlaceholder": "Nome",
+ "nameRequired": "Por favor digite um Nome",
+ "updateFailed": "Falha na alteraรงรฃo do nome da equipe!"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/pt/task-drawer/task-drawer-info-tab.json b/worklenz-backend/src/public/locales/pt/task-drawer/task-drawer-info-tab.json
new file mode 100644
index 00000000..cf26b1a3
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/task-drawer/task-drawer-info-tab.json
@@ -0,0 +1,30 @@
+{
+ "details": {
+ "task-key": "Chave da tarefa",
+ "phase": "Fase",
+ "assignees": "Responsรกveis",
+ "due-date": "Data de vencimento",
+ "time-estimation": "Estimativa de tempo",
+ "priority": "Prioridade",
+ "labels": "Etiquetas",
+ "billable": "Faturรกvel",
+ "notify": "Notificar",
+ "when-done-notify": "Quando concluรญda, notificar",
+ "start-date": "Data de inรญcio",
+ "end-date": "Data de tรฉrmino",
+ "hide-start-date": "Ocultar data de inรญcio",
+ "show-start-date": "Mostrar data de inรญcio",
+ "hours": "Horas",
+ "minutes": "Minutos",
+ "recurring": "Recorrente"
+ },
+ "description": {
+ "title": "Descriรงรฃo",
+ "placeholder": "Adicionar uma descriรงรฃo mais detalhada..."
+ },
+ "subTasks": {
+ "title": "Subtarefas",
+ "add-sub-task": "+ Adicionar subtarefa",
+ "refresh-sub-tasks": "Atualizar subtarefas"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/pt/task-drawer/task-drawer-recurring-config.json b/worklenz-backend/src/public/locales/pt/task-drawer/task-drawer-recurring-config.json
new file mode 100644
index 00000000..5592d897
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/task-drawer/task-drawer-recurring-config.json
@@ -0,0 +1,34 @@
+{
+ "recurring": "Recorrente",
+ "recurringTaskConfiguration": "Configuraรงรฃo de tarefa recorrente",
+ "repeats": "Repete",
+ "daily": "Diรกrio",
+ "weekly": "Semanal",
+ "everyXDays": "A cada X dias",
+ "everyXWeeks": "A cada X semanas",
+ "everyXMonths": "A cada X meses",
+ "monthly": "Mensal",
+ "selectDaysOfWeek": "Selecionar dias da semana",
+ "mon": "Seg",
+ "tue": "Ter",
+ "wed": "Qua",
+ "thu": "Qui",
+ "fri": "Sex",
+ "sat": "Sรกb",
+ "sun": "Dom",
+ "monthlyRepeatType": "Tipo de repetiรงรฃo mensal",
+ "onSpecificDate": "Em uma data especรญfica",
+ "onSpecificDay": "Em um dia especรญfico",
+ "dateOfMonth": "Data do mรชs",
+ "weekOfMonth": "Semana do mรชs",
+ "dayOfWeek": "Dia da semana",
+ "first": "Primeira",
+ "second": "Segunda",
+ "third": "Terceira",
+ "fourth": "Quarta",
+ "last": "รltima",
+ "intervalDays": "Intervalo (dias)",
+ "intervalWeeks": "Intervalo (semanas)",
+ "intervalMonths": "Intervalo (meses)",
+ "saveChanges": "Salvar alteraรงรตes"
+}
diff --git a/worklenz-backend/src/public/locales/pt/task-drawer/task-drawer.json b/worklenz-backend/src/public/locales/pt/task-drawer/task-drawer.json
new file mode 100644
index 00000000..c24e943e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/task-drawer/task-drawer.json
@@ -0,0 +1,123 @@
+{
+ "taskHeader": {
+ "taskNamePlaceholder": "Digite sua Tarefa",
+ "deleteTask": "Deletar Tarefa"
+ },
+ "taskInfoTab": {
+ "title": "Informaรงรตes",
+ "details": {
+ "title": "Detalhes",
+ "task-key": "Chave da Tarefa",
+ "phase": "Fase",
+ "assignees": "Responsรกveis",
+ "due-date": "Data de Vencimento",
+ "time-estimation": "Estimativa de Tempo",
+ "priority": "Prioridade",
+ "labels": "Etiquetas",
+ "billable": "Faturรกvel",
+ "notify": "Notificar",
+ "when-done-notify": "Quando concluรญdo, notificar",
+ "start-date": "Data de Inรญcio",
+ "end-date": "Data de Fim",
+ "hide-start-date": "Ocultar Data de Inรญcio",
+ "show-start-date": "Mostrar Data de Inรญcio",
+ "hours": "Horas",
+ "minutes": "Minutos",
+ "progressValue": "Valor do Progresso",
+ "progressValueTooltip": "Definir a porcentagem de progresso (0-100%)",
+ "progressValueRequired": "Por favor, insira um valor de progresso",
+ "progressValueRange": "O progresso deve estar entre 0 e 100",
+ "taskWeight": "Peso da Tarefa",
+ "taskWeightTooltip": "Definir o peso desta subtarefa (porcentagem)",
+ "taskWeightRequired": "Por favor, insira um peso da tarefa",
+ "taskWeightRange": "O peso deve estar entre 0 e 100",
+ "recurring": "Recorrente"
+ },
+ "labels": {
+ "labelInputPlaceholder": "Pesquisar ou criar",
+ "labelsSelectorInputTip": "Pressione Enter para criar"
+ },
+ "description": {
+ "title": "Descriรงรฃo",
+ "placeholder": "Adicionar uma descriรงรฃo mais detalhada..."
+ },
+ "subTasks": {
+ "title": "Sub Tarefas",
+ "addSubTask": "Adicionar Sub Tarefa",
+ "addSubTaskInputPlaceholder": "Digite sua tarefa e pressione enter",
+ "refreshSubTasks": "Atualizar Sub Tarefas",
+ "edit": "Editar",
+ "delete": "Deletar",
+ "confirmDeleteSubTask": "Tem certeza de que deseja deletar esta subtarefa?",
+ "deleteSubTask": "Deletar Sub Tarefa"
+ },
+ "dependencies": {
+ "title": "Dependรชncias",
+ "addDependency": "+ Adicionar nova dependรชncia",
+ "blockedBy": "Bloqueado por",
+ "searchTask": "Digite para pesquisar tarefa",
+ "noTasksFound": "Nenhuma tarefa encontrada",
+ "confirmDeleteDependency": "Tem certeza de que deseja deletar?"
+ },
+ "attachments": {
+ "title": "Anexos",
+ "chooseOrDropFileToUpload": "Escolha ou arraste um arquivo para upload",
+ "uploading": "Enviando..."
+ },
+ "comments": {
+ "title": "Comentรกrios",
+ "addComment": "+ Adicionar novo comentรกrio",
+ "noComments": "Ainda nรฃo hรก comentรกrios. Seja o primeiro a comentar!",
+ "delete": "Deletar",
+ "confirmDeleteComment": "Tem certeza de que deseja deletar este comentรกrio?",
+ "addCommentPlaceholder": "Adicionar um comentรกrio...",
+ "cancel": "Cancelar",
+ "commentButton": "Comentar",
+ "attachFiles": "Anexar arquivos",
+ "addMoreFiles": "Adicionar mais arquivos",
+ "selectedFiles": "Arquivos Selecionados (Atรฉ 25MB, Mรกximo {count})",
+ "maxFilesError": "Vocรช pode fazer upload de no mรกximo {count} arquivos",
+ "processFilesError": "Falha ao processar arquivos",
+ "addCommentError": "Por favor adicione um comentรกrio ou anexe arquivos",
+ "createdBy": "Criado {{time}} por {{user}}",
+ "updatedTime": "Atualizado {{time}}"
+ },
+ "searchInputPlaceholder": "Pesquisar por nome",
+ "pendingInvitation": "Convite Pendente"
+ },
+ "taskTimeLogTab": {
+ "title": "Registro de Tempo",
+ "addTimeLog": "Adicionar novo registro de tempo",
+ "totalLogged": "Total Registrado",
+ "exportToExcel": "Exportar para Excel",
+ "noTimeLogsFound": "Nenhum registro de tempo encontrado",
+ "timeLogForm": {
+ "date": "Data",
+ "startTime": "Hora de Inรญcio",
+ "endTime": "Hora de Fim",
+ "workDescription": "Descriรงรฃo do Trabalho",
+ "descriptionPlaceholder": "Adicionar uma descriรงรฃo",
+ "logTime": "Registrar tempo",
+ "updateTime": "Atualizar tempo",
+ "cancel": "Cancelar",
+ "selectDateError": "Por favor selecione uma data",
+ "selectStartTimeError": "Por favor selecione a hora de inรญcio",
+ "selectEndTimeError": "Por favor selecione a hora de fim",
+ "endTimeAfterStartError": "A hora de fim deve ser posterior ร hora de inรญcio"
+ }
+ },
+ "taskActivityLogTab": {
+ "title": "Registro de Atividade",
+ "add": "ADICIONAR",
+ "remove": "REMOVER",
+ "none": "Nenhum",
+ "weight": "Peso",
+ "createdTask": "criou a tarefa."
+ },
+ "taskProgress": {
+ "markAsDoneTitle": "Marcar Tarefa como Concluรญda?",
+ "confirmMarkAsDone": "Sim, marcar como concluรญda",
+ "cancelMarkAsDone": "Nรฃo, manter status atual",
+ "markAsDoneDescription": "Vocรช definiu o progresso para 100%. Gostaria de atualizar o status da tarefa para \"Concluรญda\"?"
+ }
+}
diff --git a/worklenz-backend/src/public/locales/pt/task-list-filters.json b/worklenz-backend/src/public/locales/pt/task-list-filters.json
new file mode 100644
index 00000000..21e8806b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/task-list-filters.json
@@ -0,0 +1,82 @@
+{
+ "searchButton": "Pesquisar",
+ "resetButton": "Redefinir",
+ "searchInputPlaceholder": "Pesquisar por nome",
+
+ "sortText": "Ordenar",
+ "statusText": "Status",
+ "phaseText": "Fase",
+ "priorityText": "Prioridade",
+ "labelsText": "Rรณtulos",
+ "membersText": "Membros",
+ "groupByText": "Agrupar por",
+ "showArchivedText": "Mostrar arquivados",
+ "showFieldsText": "Mostrar campos",
+ "keyText": "Chave",
+ "taskText": "Tarefa",
+ "descriptionText": "Descriรงรฃo",
+ "phasesText": "Fases",
+ "progressText": "Progresso",
+ "timeTrackingText": "Rastreamento de Tempo",
+ "estimationText": "Estimativa",
+ "startDateText": "Data de Inรญcio",
+ "endDateText": "Data de Fim",
+ "dueDateText": "Data de Vencimento",
+ "completedDateText": "Data de Conclusรฃo",
+ "createdDateText": "Data de Criaรงรฃo",
+ "lastUpdatedText": "รltima Atualizaรงรฃo",
+ "reporterText": "Relator",
+ "dueTimeText": "Hora de Vencimento",
+ "assigneesText": "Atribuiรงรตes",
+ "timetrackingText": "Rastreamento de Tempo",
+ "startdateText": "Data de Inรญcio",
+ "duedateText": "Data de Vencimento",
+ "completeddateText": "Data de Conclusรฃo",
+ "createddateText": "Data de Criaรงรฃo",
+ "lastupdatedText": "รltima Atualizaรงรฃo",
+
+ "lowText": "Baixa",
+ "mediumText": "Mรฉdia",
+ "highText": "Alta",
+
+ "createStatusButtonTooltip": "Configuraรงรตes de Status",
+ "configPhaseButtonTooltip": "Configuraรงรตes de Fase",
+ "noLabelsFound": "Nenhum rรณtulo encontrado",
+
+ "addStatusButton": "Adicionar Status",
+ "addPhaseButton": "Adicionar Fase",
+
+ "createStatus": "Criar Status",
+ "name": "Nome",
+ "category": "Categoria",
+ "selectCategory": "Selecionar uma categoria",
+ "pleaseEnterAName": "Por favor, insira um nome",
+ "pleaseSelectACategory": "Por favor, selecione uma categoria",
+ "create": "Criar",
+
+ "searchTasks": "Pesquisar tarefas...",
+ "searchPlaceholder": "Pesquisar...",
+ "fieldsText": "Campos",
+ "loadingFilters": "Carregando filtros...",
+ "noOptionsFound": "Nenhuma opรงรฃo encontrada",
+ "filtersActive": "filtros ativos",
+ "filterActive": "filtro ativo",
+ "clearAll": "Limpar tudo",
+ "clearing": "Limpando...",
+ "cancel": "Cancelar",
+ "search": "Pesquisar",
+ "groupedBy": "Agrupado por",
+ "manageStatuses": "Gerenciar Status",
+ "managePhases": "Gerenciar Fases",
+ "dragToReorderStatuses": "Arraste os status para reordenรก-los. Cada status pode ter uma categoria diferente.",
+ "enterNewStatusName": "Digite o novo nome do status...",
+ "addStatus": "Adicionar Status",
+ "noStatusesFound": "Nenhum status encontrado. Crie seu primeiro status acima.",
+ "deleteStatus": "Excluir Status",
+ "deleteStatusConfirm": "Tem certeza de que deseja excluir este status? Esta aรงรฃo nรฃo pode ser desfeita.",
+ "rename": "Renomear",
+ "delete": "Excluir",
+ "enterStatusName": "Digite o nome do status",
+ "selectCategory": "Selecionar categoria",
+ "close": "Fechar"
+}
diff --git a/worklenz-backend/src/public/locales/pt/task-list-table.json b/worklenz-backend/src/public/locales/pt/task-list-table.json
new file mode 100644
index 00000000..f53d834f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/task-list-table.json
@@ -0,0 +1,136 @@
+{
+ "keyColumn": "Chave",
+ "taskColumn": "Tarefa",
+ "descriptionColumn": "Descriรงรฃo",
+ "progressColumn": "Progresso",
+ "membersColumn": "Membros",
+ "assigneesColumn": "Atribuรญdos",
+ "labelsColumn": "Etiquetas",
+ "phasesColumn": "Fases",
+ "phaseColumn": "Fase",
+ "statusColumn": "Status",
+ "priorityColumn": "Prioridade",
+ "timeTrackingColumn": "Acompanhamento de Tempo",
+ "timetrackingColumn": "Acompanhamento de Tempo",
+ "estimationColumn": "Estimativa",
+ "startDateColumn": "Data de Inรญcio",
+ "startdateColumn": "Data de Inรญcio",
+ "dueDateColumn": "Data de Vencimento",
+ "duedateColumn": "Data de Vencimento",
+ "completedDateColumn": "Data de Conclusรฃo",
+ "completeddateColumn": "Data de Conclusรฃo",
+ "createdDateColumn": "Data de Criaรงรฃo",
+ "createddateColumn": "Data de Criaรงรฃo",
+ "lastUpdatedColumn": "รltima Atualizaรงรฃo",
+ "lastupdatedColumn": "รltima Atualizaรงรฃo",
+ "reporterColumn": "Reportador",
+ "dueTimeColumn": "Hora de Vencimento",
+ "todoSelectorText": "A Fazer",
+ "doingSelectorText": "Fazendo",
+ "doneSelectorText": "Feito",
+
+ "lowSelectorText": "Baixo",
+ "mediumSelectorText": "Mรฉdio",
+ "highSelectorText": "Alto",
+
+ "selectText": "Selecionar",
+ "labelsSelectorInputTip": "Pressione enter para criar!",
+
+ "addTaskText": "Adicionar Tarefa",
+ "addSubTaskText": "+ Adicionar Subtarefa",
+ "noTasksInGroup": "Nenhuma tarefa neste grupo",
+ "addTaskInputPlaceholder": "Digite sua tarefa e pressione enter",
+
+ "openButton": "Abrir",
+ "okButton": "Ok",
+
+ "noLabelsFound": "Nenhuma etiqueta encontrada",
+ "searchInputPlaceholder": "Buscar ou criar",
+ "assigneeSelectorInviteButton": "Convide um novo membro por e-mail",
+ "labelInputPlaceholder": "Buscar ou criar",
+ "searchLabelsPlaceholder": "Buscar etiquetas...",
+ "createLabelButton": "Criar \"{{name}}\"",
+ "manageLabelsPath": "Configuraรงรตes โ Etiquetas",
+
+ "pendingInvitation": "Convite Pendente",
+
+ "contextMenu": {
+ "assignToMe": "Atribuir a mim",
+ "moveTo": "Mover para",
+ "unarchive": "Desarquivar",
+ "archive": "Arquivar",
+ "convertToSubTask": "Converter em Subtarefa",
+ "convertToTask": "Converter em Tarefa",
+ "delete": "Excluir",
+ "searchByNameInputPlaceholder": "Buscar por nome"
+ },
+ "setDueDate": "Definir data de vencimento",
+ "setStartDate": "Definir data de inรญcio",
+ "clearDueDate": "Limpar data de vencimento",
+ "clearStartDate": "Limpar data de inรญcio",
+ "dueDatePlaceholder": "Data de vencimento",
+ "startDatePlaceholder": "Data de inรญcio",
+
+ "emptyStates": {
+ "noTaskGroups": "Nenhum grupo de tarefas encontrado",
+ "noTaskGroupsDescription": "As tarefas aparecerรฃo aqui quando forem criadas ou quando filtros forem aplicados.",
+ "errorPrefix": "Erro:",
+ "dragTaskFallback": "Tarefa"
+ },
+
+ "customColumns": {
+ "addCustomColumn": "Adicionar uma coluna personalizada",
+ "customColumnHeader": "Coluna Personalizada",
+ "customColumnSettings": "Configuraรงรตes da coluna personalizada",
+ "noCustomValue": "Sem valor",
+ "peopleField": "Campo de pessoas",
+ "noDate": "Sem data",
+ "unsupportedField": "Tipo de campo nรฃo suportado",
+
+ "modal": {
+ "addFieldTitle": "Adicionar campo",
+ "editFieldTitle": "Editar campo",
+ "fieldTitle": "Tรญtulo do campo",
+ "fieldTitleRequired": "O tรญtulo do campo รฉ obrigatรณrio",
+ "columnTitlePlaceholder": "Tรญtulo da coluna",
+ "type": "Tipo",
+ "deleteConfirmTitle": "Tem certeza de que deseja excluir esta coluna personalizada?",
+ "deleteConfirmDescription": "Esta aรงรฃo nรฃo pode ser desfeita. Todos os dados associados a esta coluna serรฃo excluรญdos permanentemente.",
+ "deleteButton": "Excluir",
+ "cancelButton": "Cancelar",
+ "createButton": "Criar",
+ "updateButton": "Atualizar",
+ "createSuccessMessage": "Coluna personalizada criada com sucesso",
+ "updateSuccessMessage": "Coluna personalizada atualizada com sucesso",
+ "deleteSuccessMessage": "Coluna personalizada excluรญda com sucesso",
+ "deleteErrorMessage": "Falha ao excluir a coluna personalizada",
+ "createErrorMessage": "Falha ao criar a coluna personalizada",
+ "updateErrorMessage": "Falha ao atualizar a coluna personalizada"
+ },
+
+ "fieldTypes": {
+ "people": "Pessoas",
+ "number": "Nรบmero",
+ "date": "Data",
+ "selection": "Seleรงรฃo",
+ "checkbox": "Caixa de seleรงรฃo",
+ "labels": "Etiquetas",
+ "key": "Chave",
+ "formula": "Fรณrmula"
+ }
+ },
+
+ "indicators": {
+ "tooltips": {
+ "subtasks": "{{count}} subtarefa",
+ "subtasks_plural": "{{count}} subtarefas",
+ "comments": "{{count}} comentรกrio",
+ "comments_plural": "{{count}} comentรกrios",
+ "attachments": "{{count}} anexo",
+ "attachments_plural": "{{count}} anexos",
+ "subscribers": "A tarefa tem assinantes",
+ "dependencies": "A tarefa tem dependรชncias",
+ "recurring": "Tarefa recorrente"
+ }
+ }
+}
diff --git a/worklenz-backend/src/public/locales/pt/task-management.json b/worklenz-backend/src/public/locales/pt/task-management.json
new file mode 100644
index 00000000..946b3162
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/task-management.json
@@ -0,0 +1,21 @@
+{
+ "noTasksInGroup": "Nenhuma tarefa neste grupo",
+ "noTasksInGroupDescription": "Adicione uma tarefa para comeรงar",
+ "addFirstTask": "Adicione sua primeira tarefa",
+ "openTask": "Abrir",
+ "subtask": "subtarefa",
+ "subtasks": "subtarefas",
+ "comment": "comentรกrio",
+ "comments": "comentรกrios",
+ "attachment": "anexo",
+ "attachments": "anexos",
+ "enterSubtaskName": "Digite o nome da subtarefa...",
+ "add": "Adicionar",
+ "cancel": "Cancelar",
+ "renameGroup": "Renomear Grupo",
+ "renameStatus": "Renomear Status",
+ "renamePhase": "Renomear Fase",
+ "changeCategory": "Alterar Categoria",
+ "clickToEditGroupName": "Clique para editar o nome do grupo",
+ "enterGroupName": "Digite o nome do grupo"
+}
diff --git a/worklenz-backend/src/public/locales/pt/task-template-drawer.json b/worklenz-backend/src/public/locales/pt/task-template-drawer.json
new file mode 100644
index 00000000..f1358349
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/task-template-drawer.json
@@ -0,0 +1,11 @@
+{
+ "createTaskTemplate": "Criar Template de Tarefa",
+ "editTaskTemplate": "Editar Template de Tarefa",
+ "cancelText": "Cancelar",
+ "saveText": "Salvar",
+ "templateNameText": "Nome do Template",
+ "selectedTasks": "Tarefas Selecionadas",
+ "removeTask": "Remover",
+ "cancelButton": "Cancelar",
+ "saveButton": "Salvar"
+}
diff --git a/worklenz-backend/src/public/locales/pt/tasks/task-table-bulk-actions.json b/worklenz-backend/src/public/locales/pt/tasks/task-table-bulk-actions.json
new file mode 100644
index 00000000..f4a3a10e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/tasks/task-table-bulk-actions.json
@@ -0,0 +1,41 @@
+{
+ "taskSelected": "Tarefa selecionada",
+ "tasksSelected": "Tarefas selecionadas",
+ "changeStatus": "Alterar Status/ Prioridade/ Fases",
+ "changeLabel": "Alterar Etiqueta",
+ "assignToMe": "Atribuir a mim",
+ "changeAssignees": "Alterar Assignados",
+ "archive": "Arquivar",
+ "unarchive": "Desarquivar",
+ "delete": "Deletar",
+ "moreOptions": "Mais opรงรตes",
+ "deselectAll": "Desmarcar todas",
+ "status": "Status",
+ "priority": "Prioridade",
+ "phase": "Fase",
+ "member": "Membro",
+ "createTaskTemplate": "Criar Modelo de Tarefa",
+ "apply": "Aplicar",
+ "createLabel": "+ Criar etiqueta",
+ "searchOrCreateLabel": "Pesquisar ou criar etiqueta...",
+ "hitEnterToCreate": "Pressione Enter para criar",
+ "labelExists": "A etiqueta jรก existe",
+ "pendingInvitation": "Convite Pendente",
+ "noMatchingLabels": "Nenhuma etiqueta correspondente",
+ "noLabels": "Sem etiquetas",
+ "CHANGE_STATUS": "Alterar Status",
+ "CHANGE_PRIORITY": "Alterar Prioridade",
+ "CHANGE_PHASE": "Alterar Fase",
+ "ADD_LABELS": "Adicionar Etiquetas",
+ "ASSIGN_TO_ME": "Atribuir a Mim",
+ "ASSIGN_MEMBERS": "Atribuir Membros",
+ "ARCHIVE": "Arquivar",
+ "DELETE": "Deletar",
+ "CANCEL": "Cancelar",
+ "CLEAR_SELECTION": "Limpar Seleรงรฃo",
+ "TASKS_SELECTED": "{{count}} tarefa selecionada",
+ "TASKS_SELECTED_plural": "{{count}} tarefas selecionadas",
+ "DELETE_TASKS_CONFIRM": "Deletar {{count}} tarefa?",
+ "DELETE_TASKS_CONFIRM_plural": "Deletar {{count}} tarefas?",
+ "DELETE_TASKS_WARNING": "Esta aรงรฃo nรฃo pode ser desfeita."
+}
diff --git a/worklenz-backend/src/public/locales/pt/template-drawer.json b/worklenz-backend/src/public/locales/pt/template-drawer.json
new file mode 100644
index 00000000..cb79d2bf
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/template-drawer.json
@@ -0,0 +1,19 @@
+{
+ "title": "Editar Template de Tarefa",
+ "cancelText": "Cancelar",
+ "saveText": "Salvar",
+ "templateNameText": "Nome do Template",
+ "selectedTasks": "Tarefas Selecionadas",
+ "removeTask": "Remover",
+ "description": "Descriรงรฃo",
+ "phase": "Fase",
+ "statuses": "Status",
+ "priorities": "Prioridades",
+ "labels": "Rรณtulos",
+ "tasks": "Tarefas",
+ "noTemplateSelected": "Nenhum template selecionado",
+ "noDescription": "Sem descriรงรฃo",
+ "worklenzTemplates": "Templates de Worklenz",
+ "yourTemplatesLibrary": "Sua Biblioteca",
+ "searchTemplates": "Pesquisar Templates"
+}
diff --git a/worklenz-backend/src/public/locales/pt/templateDrawer.json b/worklenz-backend/src/public/locales/pt/templateDrawer.json
new file mode 100644
index 00000000..c4d970c6
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/templateDrawer.json
@@ -0,0 +1,23 @@
+{
+ "bugTracking": "Rastreamento de Bugs",
+ "construction": "Construรงรฃo",
+ "designCreative": "Design e Criatividade",
+ "education": "Educaรงรฃo",
+ "finance": "Finanรงas",
+ "hrRecruiting": "RH e Recrutamento",
+ "informationTechnology": "Tecnologia da Informaรงรฃo",
+ "legal": "Jurรญdico",
+ "manufacturing": "Manufatura",
+ "marketing": "Marketing",
+ "nonprofit": "Sem Fins Lucrativos",
+ "personalUse": "Uso Pessoal",
+ "salesCRM": "Vendas e CRM",
+ "serviceConsulting": "Serviรงo e Consultoria",
+ "softwareDevelopment": "Desenvolvimento de Software",
+ "description": "Descriรงรฃo",
+ "phase": "Fase",
+ "statuses": "Status",
+ "priorities": "Prioridades",
+ "labels": "Rรณtulos",
+ "tasks": "Tarefas"
+}
diff --git a/worklenz-backend/src/public/locales/pt/time-report.json b/worklenz-backend/src/public/locales/pt/time-report.json
new file mode 100644
index 00000000..b40546e9
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/time-report.json
@@ -0,0 +1,57 @@
+{
+ "includeArchivedProjects": "Incluir Projetos Arquivados",
+ "export": "Exportar",
+ "timeSheet": "Folha de Tempo",
+
+ "searchByName": "Pesquisar por nome",
+ "selectAll": "Selecionar Tudo",
+ "teams": "Equipes",
+
+ "searchByProject": "Pesquisar por nome do projeto",
+ "projects": "Projetos",
+
+ "searchByCategory": "Pesquisar por nome da categoria",
+ "categories": "Categorias",
+
+ "billable": "Faturรกvel",
+ "nonBillable": "Nรฃo Faturรกvel",
+
+ "total": "Total",
+
+ "projectsTimeSheet": "Folha de Tempo de Projetos",
+
+ "loggedTime": "Tempo Registrado(horas)",
+
+ "exportToExcel": "Exportar para Excel",
+ "logged": "registrado",
+ "for": "para",
+
+ "membersTimeSheet": "Folha de Tempo de Membros",
+ "member": "Membro",
+
+ "estimatedVsActual": "Estimado vs Real",
+ "workingDays": "Dias รteis",
+ "manDays": "Dias Homem",
+ "days": "Dias",
+ "estimatedDays": "Dias Estimados",
+ "actualDays": "Dias Reais",
+
+ "noCategories": "Nenhuma categoria encontrada",
+ "noCategory": "Sem Categoria",
+ "noProjects": "Nenhum projeto encontrado",
+ "noTeams": "Nenhuma equipe encontrada",
+ "noData": "Nenhum dado encontrado",
+
+ "groupBy": "Agrupar por",
+ "groupByCategory": "Categoria",
+ "groupByTeam": "Equipe",
+ "groupByStatus": "Status",
+ "groupByNone": "Nenhum",
+ "clearSearch": "Limpar pesquisa",
+ "selectedProjects": "Projetos Selecionados",
+ "projectsSelected": "projetos selecionados",
+ "showSelected": "Mostrar Apenas Selecionados",
+ "expandAll": "Expandir Tudo",
+ "collapseAll": "Recolher Tudo",
+ "ungrouped": "Nรฃo Agrupado"
+}
diff --git a/worklenz-backend/src/public/locales/pt/unauthorized.json b/worklenz-backend/src/public/locales/pt/unauthorized.json
new file mode 100644
index 00000000..e67e0ffd
--- /dev/null
+++ b/worklenz-backend/src/public/locales/pt/unauthorized.json
@@ -0,0 +1,5 @@
+{
+ "title": "ยกNรฃo autorizado!",
+ "subtitle": "Vocรช nรฃo tem permissรฃo para acessar esta pรกgina",
+ "button": "Ir para Inรญcio"
+}
diff --git a/worklenz-backend/src/public/locales/zh/404-page.json b/worklenz-backend/src/public/locales/zh/404-page.json
new file mode 100644
index 00000000..24a74b3e
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/404-page.json
@@ -0,0 +1,4 @@
+{
+ "doesNotExistText": "ๆฑๆญ๏ผๆจ่ฎฟ้ฎ็้กต้ขไธๅญๅจใ",
+ "backHomeButton": "่ฟๅ้ฆ้กต"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/account-setup.json b/worklenz-backend/src/public/locales/zh/account-setup.json
new file mode 100644
index 00000000..51cac1eb
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/account-setup.json
@@ -0,0 +1,27 @@
+{
+ "continue": "็ปง็ปญ",
+ "setupYourAccount": "่ฎพ็ฝฎๆจ็Worklenz่ดฆๆทใ",
+ "organizationStepTitle": "ๅฝๅๆจ็็ป็ป",
+ "organizationStepLabel": "ไธบๆจ็Worklenz่ดฆๆท้ๆฉไธไธชๅ็งฐใ",
+ "projectStepTitle": "ๅๅปบๆจ็็ฌฌไธไธช้กน็ฎ",
+ "projectStepLabel": "ๆจ็ฐๅจๆญฃๅจๅไปไน้กน็ฎ๏ผ",
+ "projectStepPlaceholder": "ไพๅฆ๏ผ่ฅ้่ฎกๅ",
+ "tasksStepTitle": "ๅๅปบๆจ็็ฌฌไธไธชไปปๅก",
+ "tasksStepLabel": "่พๅ ฅๆจๅฐๅจๅ ถไธญๅฎๆ็ๅ ไธชไปปๅก",
+ "tasksStepAddAnother": "ๆทปๅ ๅฆไธไธช",
+ "emailPlaceholder": "็ตๅญ้ฎไปถๅฐๅ",
+ "invalidEmail": "่ฏท่พๅ ฅๆๆ็็ตๅญ้ฎไปถๅฐๅ",
+ "or": "ๆ",
+ "templateButton": "ไปๆจกๆฟๅฏผๅ ฅ",
+ "goBack": "่ฟๅ",
+ "cancel": "ๅๆถ",
+ "create": "ๅๅปบ",
+ "templateDrawerTitle": "ไปๆจกๆฟไธญ้ๆฉ",
+ "step3InputLabel": "้่ฟ็ตๅญ้ฎไปถ้่ฏท",
+ "addAnother": "ๆทปๅ ๅฆไธไธช",
+ "skipForNow": "ๆๆถ่ทณ่ฟ",
+ "formTitle": "ๅๅปบๆจ็็ฌฌไธไธชไปปๅกใ",
+ "step3Title": "้่ฏทๆจ็ๅข้ไธ่ตทๅทฅไฝ",
+ "maxMembers": "๏ผๆจๆๅคๅฏไปฅ้่ฏท5ๅๆๅ๏ผ",
+ "maxTasks": "๏ผๆจๆๅคๅฏไปฅๅๅปบ5ไธชไปปๅก๏ผ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/admin-center/current-bill.json b/worklenz-backend/src/public/locales/zh/admin-center/current-bill.json
new file mode 100644
index 00000000..e18e8761
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/admin-center/current-bill.json
@@ -0,0 +1,96 @@
+{
+ "title": "่ดฆๅ",
+ "currentBill": "ๅฝๅ่ดฆๅ",
+ "configuration": "้ ็ฝฎ",
+ "currentPlanDetails": "ๅฝๅ่ฎกๅ่ฏฆๆ ",
+ "upgradePlan": "ๅ็บง่ฎกๅ",
+ "cardBodyText01": "ๅ ่ดน่ฏ็จ",
+ "cardBodyText02": "๏ผๆจ็่ฏ็จ่ฎกๅๅฐๅจ1ไธชๆ19ๅคฉๅๅฐๆ๏ผ",
+ "redeemCode": "ๅ ๆข็ ",
+ "accountStorage": "่ดฆๆทๅญๅจ",
+ "used": "ๅทฒ็จ๏ผ",
+ "remaining": "ๅฉไฝ๏ผ",
+ "charges": "่ดน็จ",
+ "tooltip": "ๅฝๅ่ดฆๅๅจๆ็่ดน็จ",
+ "description": "ๆ่ฟฐ",
+ "billingPeriod": "่ดฆๅๅจๆ",
+ "billStatus": "่ดฆๅ็ถๆ",
+ "perUserValue": "ๆฏ็จๆท่ดน็จ",
+ "users": "็จๆท",
+ "amount": "้้ข",
+ "invoices": "ๅ็ฅจ",
+ "transactionId": "ไบคๆID",
+ "transactionDate": "ไบคๆๆฅๆ",
+ "paymentMethod": "ๆฏไปๆนๅผ",
+ "status": "็ถๆ",
+ "ltdUsers": "ๆจๆๅคๅฏไปฅๆทปๅ {{ltd_users}}ๅ็จๆทใ",
+ "totalSeats": "ๆปๅธญไฝ",
+ "availableSeats": "ๅฏ็จๅธญไฝ",
+ "addMoreSeats": "ๆทปๅ ๆดๅคๅธญไฝ",
+ "drawerTitle": "ๅ ๆข็ ",
+ "label": "ๅ ๆข็ ",
+ "drawerPlaceholder": "่พๅ ฅๆจ็ๅ ๆข็ ",
+ "redeemSubmit": "ๆไบค",
+ "modalTitle": "ไธบๆจ็ๅข้้ๆฉๆไฝณ่ฎกๅ",
+ "seatLabel": "ๅธญไฝๆฐ้",
+ "freePlan": "ๅ ่ดน่ฎกๅ",
+ "startup": "ๅๅ",
+ "business": "ๅไธ",
+ "tag": "ๆๅๆฌข่ฟ",
+ "enterprise": "ไผไธ",
+ "freeSubtitle": "ๆฐธ่ฟๅ ่ดน",
+ "freeUsers": "ๆ้ๅไธชไบบไฝฟ็จ",
+ "freeText01": "100MBๅญๅจ",
+ "freeText02": "3ไธช้กน็ฎ",
+ "freeText03": "5ๅๅข้ๆๅ",
+ "startupSubtitle": "ๅบๅฎ่ดน็/ๆ",
+ "startupUsers": "ๆๅค15ๅ็จๆท",
+ "startupText01": "25GBๅญๅจ",
+ "startupText02": "ๆ ้ๆดป่ท้กน็ฎ",
+ "startupText03": "ๆฅ็จ",
+ "startupText04": "ๆฅๅ",
+ "startupText05": "่ฎข้ ้กน็ฎ",
+ "businessSubtitle": "ๆฏ็จๆท/ๆ",
+ "businessUsers": "16 - 200ๅ็จๆท",
+ "enterpriseUsers": "200 - 500+ๅ็จๆท",
+ "footerTitle": "่ฏทๆไพไธไธชๆไปฌๅฏไปฅ่็ณปๆจ็็ต่ฏๅท็ ใ",
+ "footerLabel": "่็ณป็ต่ฏ",
+ "footerButton": "่็ณปๆไปฌ",
+ "redeemCodePlaceHolder": "่พๅ ฅๆจ็ๅ ๆข็ ",
+ "submit": "ๆไบค",
+ "trialPlan": "ๅ ่ดน่ฏ็จ",
+ "trialExpireDate": "ๆๆๆ่ณ{{trial_expire_date}}",
+ "trialExpired": "ๆจ็ๅ ่ดน่ฏ็จๅทฒไบ{{trial_expire_string}}ๅฐๆ",
+ "trialInProgress": "ๆจ็ๅ ่ดน่ฏ็จๅฐๅจ{{trial_expire_string}}ๅฐๆ",
+ "required": "ๆญคๅญๆฎตไธบๅฟ ๅกซ้กน",
+ "invalidCode": "ๆ ๆ็ไปฃ็ ",
+ "selectPlan": "ไธบๆจ็ๅข้้ๆฉๆไฝณ่ฎกๅ",
+ "changeSubscriptionPlan": "ๆดๆนๆจ็่ฎข้ ่ฎกๅ",
+ "noOfSeats": "ๅธญไฝๆฐ้",
+ "annualPlan": "ไธไธ - ๅนดๅบฆ",
+ "monthlyPlan": "ไธไธ - ๆๅบฆ",
+ "freeForever": "ๆฐธ่ฟๅ ่ดน",
+ "bestForPersonalUse": "ๆ้ๅไธชไบบไฝฟ็จ",
+ "storage": "ๅญๅจ",
+ "projects": "้กน็ฎ",
+ "teamMembers": "ๅข้ๆๅ",
+ "unlimitedTeamMembers": "ๆ ้ๅข้ๆๅ",
+ "unlimitedActiveProjects": "ๆ ้ๆดป่ท้กน็ฎ",
+ "schedule": "ๆฅ็จ",
+ "reporting": "ๆฅๅ",
+ "subscribeToProjects": "่ฎข้ ้กน็ฎ",
+ "billedAnnually": "ๆๅนด่ฎก่ดน",
+ "billedMonthly": "ๆๆ่ฎก่ดน",
+ "pausePlan": "ๆๅ่ฎกๅ",
+ "resumePlan": "ๆขๅค่ฎกๅ",
+ "changePlan": "ๆดๆน่ฎกๅ",
+ "cancelPlan": "ๅๆถ่ฎกๅ",
+ "perMonthPerUser": "ๆฏ็จๆท/ๆ",
+ "viewInvoice": "ๆฅ็ๅ็ฅจ",
+ "switchToFreePlan": "ๅๆขๅฐๅ ่ดน่ฎกๅ",
+ "expirestoday": "ไปๅคฉ",
+ "expirestomorrow": "ๆๅคฉ",
+ "expiredDaysAgo": "{{days}}ๅคฉๅ",
+ "continueWith": "็ปง็ปญไฝฟ็จ{{plan}}",
+ "changeToPlan": "ๆดๆนไธบ{{plan}}"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/admin-center/overview.json b/worklenz-backend/src/public/locales/zh/admin-center/overview.json
new file mode 100644
index 00000000..9c70093f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/admin-center/overview.json
@@ -0,0 +1,8 @@
+{
+ "overview": "ๆฆ่ง",
+ "name": "็ป็ปๅ็งฐ",
+ "owner": "็ป็ปๆๆ่ ",
+ "admins": "็ป็ป็ฎก็ๅ",
+ "contactNumber": "ๆทปๅ ่็ณป็ต่ฏ",
+ "edit": "็ผ่พ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/admin-center/projects.json b/worklenz-backend/src/public/locales/zh/admin-center/projects.json
new file mode 100644
index 00000000..ca2eded2
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/admin-center/projects.json
@@ -0,0 +1,12 @@
+{
+ "membersCount": "ๆๅๆฐ้",
+ "createdAt": "ๅๅปบไบ",
+ "projectName": "้กน็ฎๅ็งฐ",
+ "teamName": "ๅข้ๅ็งฐ",
+ "refreshProjects": "ๅทๆฐ้กน็ฎ",
+ "searchPlaceholder": "ๆ้กน็ฎๅ็งฐๆ็ดข",
+ "deleteProject": "ๆจ็กฎๅฎ่ฆๅ ้คๆญค้กน็ฎๅ๏ผ",
+ "confirm": "็กฎ่ฎค",
+ "cancel": "ๅๆถ",
+ "delete": "ๅ ้ค้กน็ฎ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/admin-center/sidebar.json b/worklenz-backend/src/public/locales/zh/admin-center/sidebar.json
new file mode 100644
index 00000000..ab8808c3
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/admin-center/sidebar.json
@@ -0,0 +1,8 @@
+{
+ "overview": "ๆฆ่ง",
+ "users": "็จๆท",
+ "teams": "ๅข้",
+ "billing": "่ดฆๅ",
+ "projects": "้กน็ฎ",
+ "adminCenter": "็ฎก็ไธญๅฟ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/admin-center/teams.json b/worklenz-backend/src/public/locales/zh/admin-center/teams.json
new file mode 100644
index 00000000..4244d848
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/admin-center/teams.json
@@ -0,0 +1,33 @@
+{
+ "title": "ๅข้",
+ "subtitle": "ๅข้",
+ "tooltip": "ๅทๆฐๅข้",
+ "placeholder": "ๆๅ็งฐๆ็ดข",
+ "addTeam": "ๆทปๅ ๅข้",
+ "team": "ๅข้",
+ "membersCount": "ๆๅๆฐ้",
+ "members": "ๆๅ",
+ "drawerTitle": "ๅๅปบๆฐๅข้",
+ "label": "ๅข้ๅ็งฐ",
+ "drawerPlaceholder": "ๅ็งฐ",
+ "create": "ๅๅปบ",
+ "delete": "ๅ ้ค",
+ "settings": "่ฎพ็ฝฎ",
+ "popTitle": "ๆจ็กฎๅฎๅ๏ผ",
+ "message": "่ฏท่พๅ ฅๅ็งฐ",
+ "teamSettings": "ๅข้่ฎพ็ฝฎ",
+ "teamName": "ๅข้ๅ็งฐ",
+ "teamDescription": "ๅข้ๆ่ฟฐ",
+ "teamMembers": "ๅข้ๆๅ",
+ "teamMembersCount": "ๅข้ๆๅๆฐ้",
+ "teamMembersPlaceholder": "ๆๅ็งฐๆ็ดข",
+ "addMember": "ๆทปๅ ๆๅ",
+ "add": "ๆทปๅ ",
+ "update": "ๆดๆฐ",
+ "teamNamePlaceholder": "ๅข้ๅ็งฐ",
+ "user": "็จๆท",
+ "role": "่ง่ฒ",
+ "owner": "ๆๆ่ ",
+ "admin": "็ฎก็ๅ",
+ "member": "ๆๅ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/admin-center/users.json b/worklenz-backend/src/public/locales/zh/admin-center/users.json
new file mode 100644
index 00000000..83800c09
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/admin-center/users.json
@@ -0,0 +1,9 @@
+{
+ "title": "็จๆท",
+ "subTitle": "็จๆท",
+ "placeholder": "ๆๅ็งฐๆ็ดข",
+ "user": "็จๆท",
+ "email": "็ตๅญ้ฎไปถ",
+ "lastActivity": "ๆๅๆดปๅจ",
+ "refresh": "ๅทๆฐ็จๆท"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/all-project-list.json b/worklenz-backend/src/public/locales/zh/all-project-list.json
new file mode 100644
index 00000000..a6c72c06
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/all-project-list.json
@@ -0,0 +1,34 @@
+{
+ "name": "ๅ็งฐ",
+ "client": "ๅฎขๆท",
+ "category": "็ฑปๅซ",
+ "status": "็ถๆ",
+ "tasksProgress": "ไปปๅก่ฟๅบฆ",
+ "updated_at": "ๆๅๆดๆฐ",
+ "members": "ๆๅ",
+ "setting": "่ฎพ็ฝฎ",
+ "projects": "้กน็ฎ",
+ "refreshProjects": "ๅทๆฐ้กน็ฎ",
+ "all": "ๅ จ้จ",
+ "favorites": "ๆถ่",
+ "archived": "ๅทฒๅฝๆกฃ",
+ "placeholder": "ๆๅ็งฐๆ็ดข",
+ "archive": "ๅฝๆกฃ",
+ "unarchive": "ๅๆถๅฝๆกฃ",
+ "archiveConfirm": "ๆจ็กฎๅฎ่ฆๅฝๆกฃๆญค้กน็ฎๅ๏ผ",
+ "unarchiveConfirm": "ๆจ็กฎๅฎ่ฆๅๆถๅฝๆกฃๆญค้กน็ฎๅ๏ผ",
+ "yes": "ๆฏ",
+ "no": "ๅฆ",
+ "clickToFilter": "็นๅป็ญ้",
+ "noProjects": "ๆชๆพๅฐ้กน็ฎ",
+ "addToFavourites": "ๆทปๅ ๅฐๆถ่",
+ "list": "ๅ่กจ",
+ "group": "ๅ็ป",
+ "listView": "ๅ่กจ่งๅพ",
+ "groupView": "ๅ็ป่งๅพ",
+ "groupBy": {
+ "category": "็ฑปๅซ",
+ "client": "ๅฎขๆท"
+ },
+ "noPermission": "ๆจๆฒกๆๆ้ๆง่กๆญคๆไฝ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/auth/auth-common.json b/worklenz-backend/src/public/locales/zh/auth/auth-common.json
new file mode 100644
index 00000000..df57a70d
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/auth/auth-common.json
@@ -0,0 +1,5 @@
+{
+ "loggingOut": "ๆญฃๅจ็ปๅบ...",
+ "authenticating": "ๆญฃๅจ่ฎค่ฏ...",
+ "gettingThingsReady": "ๆญฃๅจไธบๆจๅๅค..."
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/auth/forgot-password.json b/worklenz-backend/src/public/locales/zh/auth/forgot-password.json
new file mode 100644
index 00000000..de1529a4
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/auth/forgot-password.json
@@ -0,0 +1,12 @@
+{
+ "headerDescription": "้็ฝฎๆจ็ๅฏ็ ",
+ "emailLabel": "็ตๅญ้ฎไปถ",
+ "emailPlaceholder": "่พๅ ฅๆจ็็ตๅญ้ฎไปถ",
+ "emailRequired": "่ฏท่พๅ ฅๆจ็็ตๅญ้ฎไปถ๏ผ",
+ "resetPasswordButton": "้็ฝฎๅฏ็ ",
+ "returnToLoginButton": "่ฟๅ็ปๅฝ",
+ "passwordResetSuccessMessage": "ๅฏ็ ้็ฝฎ้พๆฅๅทฒๅ้ๅฐๆจ็็ตๅญ้ฎไปถใ",
+ "orText": "ๆ",
+ "successTitle": "้็ฝฎๆไปคๅทฒๅ้๏ผ",
+ "successMessage": "้็ฝฎไฟกๆฏๅทฒๅ้ๅฐๆจ็็ตๅญ้ฎไปถใ่ฏทๆฃๆฅๆจ็็ตๅญ้ฎไปถใ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/auth/login.json b/worklenz-backend/src/public/locales/zh/auth/login.json
new file mode 100644
index 00000000..e53d5fc5
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/auth/login.json
@@ -0,0 +1,27 @@
+{
+ "headerDescription": "็ปๅฝๅฐๆจ็่ดฆๆท",
+ "emailLabel": "็ตๅญ้ฎไปถ",
+ "emailPlaceholder": "่พๅ ฅๆจ็็ตๅญ้ฎไปถ",
+ "emailRequired": "่ฏท่พๅ ฅๆจ็็ตๅญ้ฎไปถ๏ผ",
+ "passwordLabel": "ๅฏ็ ",
+ "passwordPlaceholder": "่พๅ ฅๆจ็ๅฏ็ ",
+ "passwordRequired": "่ฏท่พๅ ฅๆจ็ๅฏ็ ๏ผ",
+ "rememberMe": "่ฎฐไฝๆ",
+ "loginButton": "็ปๅฝ",
+ "signupButton": "ๆณจๅ",
+ "forgotPasswordButton": "ๅฟ่ฎฐๅฏ็ ๏ผ",
+ "signInWithGoogleButton": "ไฝฟ็จGoogle็ปๅฝ",
+ "dontHaveAccountText": "ๆฒกๆ่ดฆๆท๏ผ",
+ "orText": "ๆ",
+ "successMessage": "ๆจๅทฒๆๅ็ปๅฝ๏ผ",
+ "loginError": "็ปๅฝๅคฑ่ดฅ",
+ "googleLoginError": "Google็ปๅฝๅคฑ่ดฅ",
+ "validationMessages": {
+ "email": "่ฏท่พๅ ฅๆๆ็็ตๅญ้ฎไปถๅฐๅ",
+ "password": "ๅฏ็ ๅฟ ้กป่ณๅฐๅ ๅซ8ไธชๅญ็ฌฆ"
+ },
+ "errorMessages": {
+ "loginErrorTitle": "็ปๅฝๅคฑ่ดฅ",
+ "loginErrorMessage": "่ฏทๆฃๆฅๆจ็็ตๅญ้ฎไปถๅๅฏ็ ๅนถ้่ฏ"
+ }
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/auth/signup.json b/worklenz-backend/src/public/locales/zh/auth/signup.json
new file mode 100644
index 00000000..a2b34e57
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/auth/signup.json
@@ -0,0 +1,29 @@
+{
+ "headerDescription": "ๆณจๅไปฅๅผๅงไฝฟ็จ",
+ "nameLabel": "ๅ จๅ",
+ "namePlaceholder": "่พๅ ฅๆจ็ๅ จๅ",
+ "nameRequired": "่ฏท่พๅ ฅๆจ็ๅ จๅ๏ผ",
+ "nameMinCharacterRequired": "ๅ จๅๅฟ ้กป่ณๅฐๅ ๅซ4ไธชๅญ็ฌฆ๏ผ",
+ "emailLabel": "็ตๅญ้ฎไปถ",
+ "emailPlaceholder": "่พๅ ฅๆจ็็ตๅญ้ฎไปถ",
+ "emailRequired": "่ฏท่พๅ ฅๆจ็็ตๅญ้ฎไปถ๏ผ",
+ "passwordLabel": "ๅฏ็ ",
+ "passwordPlaceholder": "่พๅ ฅๆจ็ๅฏ็ ",
+ "passwordRequired": "่ฏท่พๅ ฅๆจ็ๅฏ็ ๏ผ",
+ "passwordMinCharacterRequired": "ๅฏ็ ๅฟ ้กป่ณๅฐๅ ๅซ8ไธชๅญ็ฌฆ๏ผ",
+ "passwordPatternRequired": "ๅฏ็ ไธ็ฌฆๅ่ฆๆฑ๏ผ",
+ "strongPasswordPlaceholder": "่พๅ ฅๆดๅผบ็ๅฏ็ ",
+ "passwordValidationAltText": "ๅฏ็ ๅฟ ้กป่ณๅฐๅ ๅซ8ไธชๅญ็ฌฆ๏ผๅ ๆฌๅคงๅฐๅๅญๆฏใไธไธชๆฐๅญๅไธไธช็ฌฆๅทใ",
+ "signupSuccessMessage": "ๆจๅทฒๆๅๆณจๅ๏ผ",
+ "privacyPolicyLink": "้็งๆฟ็ญ",
+ "termsOfUseLink": "ไฝฟ็จๆกๆฌพ",
+ "bySigningUpText": "้่ฟๆณจๅ๏ผๆจๅๆๆไปฌ็",
+ "andText": "ๅ",
+ "signupButton": "ๆณจๅ",
+ "signInWithGoogleButton": "ไฝฟ็จGoogle็ปๅฝ",
+ "alreadyHaveAccountText": "ๅทฒ็ปๆ่ดฆๆทไบ๏ผ",
+ "loginButton": "็ปๅฝ",
+ "orText": "ๆ",
+ "reCAPTCHAVerificationError": "reCAPTCHA้ช่ฏ้่ฏฏ",
+ "reCAPTCHAVerificationErrorMessage": "ๆไปฌๆ ๆณ้ช่ฏๆจ็reCAPTCHAใ่ฏท้่ฏใ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/auth/verify-reset-email.json b/worklenz-backend/src/public/locales/zh/auth/verify-reset-email.json
new file mode 100644
index 00000000..11222523
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/auth/verify-reset-email.json
@@ -0,0 +1,14 @@
+{
+ "title": "้ช่ฏ้็ฝฎ็ตๅญ้ฎไปถ",
+ "description": "่พๅ ฅๆจ็ๆฐๅฏ็ ",
+ "placeholder": "่พๅ ฅๆจ็ๆฐๅฏ็ ",
+ "confirmPasswordPlaceholder": "็กฎ่ฎคๆจ็ๆฐๅฏ็ ",
+ "passwordHint": "่ณๅฐ8ไธชๅญ็ฌฆ๏ผๅ ๆฌๅคงๅฐๅๅญๆฏใไธไธชๆฐๅญๅไธไธช็ฌฆๅทใ",
+ "resetPasswordButton": "้็ฝฎๅฏ็ ",
+ "orText": "ๆ",
+ "resendResetEmail": "้ๆฐๅ้้็ฝฎ็ตๅญ้ฎไปถ",
+ "passwordRequired": "่ฏท่พๅ ฅๆจ็ๆฐๅฏ็ ",
+ "returnToLoginButton": "่ฟๅ็ปๅฝ",
+ "confirmPasswordRequired": "่ฏท็กฎ่ฎคๆจ็ๆฐๅฏ็ ",
+ "passwordMismatch": "ไธคๆฌก่พๅ ฅ็ๅฏ็ ไธๅน้ "
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/common.json b/worklenz-backend/src/public/locales/zh/common.json
new file mode 100644
index 00000000..520ee5e2
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/common.json
@@ -0,0 +1,9 @@
+{
+ "login-success": "็ปๅฝๆๅ๏ผ",
+ "login-failed": "็ปๅฝๅคฑ่ดฅใ่ฏทๆฃๆฅๆจ็ๅญๆฎๅนถ้่ฏใ",
+ "signup-success": "ๆณจๅๆๅ๏ผๆฌข่ฟๅ ๅ ฅใ",
+ "signup-failed": "ๆณจๅๅคฑ่ดฅใ่ฏท็กฎไฟๅกซๅๆๆๅฟ ๅกซๅญๆฎตๅนถ้่ฏใ",
+ "reconnecting": "ไธๆๅกๅจๆญๅผ่ฟๆฅใ",
+ "connection-lost": "ๆ ๆณ่ฟๆฅๅฐๆๅกๅจใ่ฏทๆฃๆฅๆจ็ไบ่็ฝ่ฟๆฅใ",
+ "connection-restored": "ๆๅ่ฟๆฅๅฐๆๅกๅจ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/create-first-project-form.json b/worklenz-backend/src/public/locales/zh/create-first-project-form.json
new file mode 100644
index 00000000..95ea4099
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/create-first-project-form.json
@@ -0,0 +1,13 @@
+{
+ "formTitle": "ๅๅปบๆจ็็ฌฌไธไธช้กน็ฎ",
+ "inputLabel": "ๆจ็ฐๅจๆญฃๅจๅไปไน้กน็ฎ๏ผ",
+ "or": "ๆ",
+ "templateButton": "ไปๆจกๆฟๅฏผๅ ฅ",
+ "createFromTemplate": "ไปๆจกๆฟๅๅปบ",
+ "goBack": "่ฟๅ",
+ "continue": "็ปง็ปญ",
+ "cancel": "ๅๆถ",
+ "create": "ๅๅปบ",
+ "templateDrawerTitle": "ไปๆจกๆฟไธญ้ๆฉ",
+ "createProject": "ๅๅปบ้กน็ฎ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/create-first-tasks.json b/worklenz-backend/src/public/locales/zh/create-first-tasks.json
new file mode 100644
index 00000000..810d5aff
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/create-first-tasks.json
@@ -0,0 +1,7 @@
+{
+ "formTitle": "ๅๅปบๆจ็็ฌฌไธไธชไปปๅกใ",
+ "inputLable": "่พๅ ฅๆจๅฐๅจๅ ถไธญๅฎๆ็ๅ ไธชไปปๅก",
+ "addAnother": "ๆทปๅ ๅฆไธไธช",
+ "goBack": "่ฟๅ",
+ "continue": "็ปง็ปญ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/home.json b/worklenz-backend/src/public/locales/zh/home.json
new file mode 100644
index 00000000..184b4f1a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/home.json
@@ -0,0 +1,46 @@
+{
+ "todoList": {
+ "title": "ๅพ ๅไบ้กนๅ่กจ",
+ "refreshTasks": "ๅทๆฐไปปๅก",
+ "addTask": "+ ๆทปๅ ไปปๅก",
+ "noTasks": "ๆฒกๆไปปๅก",
+ "pressEnter": "ๆ",
+ "toCreate": "ๅๅปบใ",
+ "markAsDone": "ๆ ่ฎฐไธบๅฎๆ"
+ },
+ "projects": {
+ "title": "้กน็ฎ",
+ "refreshProjects": "ๅทๆฐ้กน็ฎ",
+ "noRecentProjects": "ๆจๅฝๅๆช่ขซๅ้ ๅฐไปปไฝ้กน็ฎใ",
+ "noFavouriteProjects": "ๆฒกๆ้กน็ฎ่ขซๆ ่ฎฐไธบๆถ่ใ",
+ "recent": "ๆ่ฟ",
+ "favourites": "ๆถ่"
+ },
+ "tasks": {
+ "assignedToMe": "ๅ้ ็ปๆ",
+ "assignedByMe": "็ฑๆๅ้ ",
+ "all": "ๅ จ้จ",
+ "today": "ไปๅคฉ",
+ "upcoming": "ๅณๅฐๅฐๆฅ",
+ "overdue": "้พๆ",
+ "noDueDate": "ๆฒกๆๆชๆญขๆฅๆ",
+ "noTasks": "ๆฒกๆไปปๅกๅฏๆพ็คบใ",
+ "addTask": "+ ๆทปๅ ไปปๅก",
+ "name": "ๅ็งฐ",
+ "project": "้กน็ฎ",
+ "status": "็ถๆ",
+ "dueDate": "ๆชๆญขๆฅๆ",
+ "dueDatePlaceholder": "่ฎพ็ฝฎๆชๆญขๆฅๆ",
+ "tomorrow": "ๆๅคฉ",
+ "nextWeek": "ไธๅจ",
+ "nextMonth": "ไธไธชๆ",
+ "projectRequired": "่ฏท้ๆฉไธไธช้กน็ฎ",
+ "pressTabToSelectDueDateAndProject": "ๆTab้ฎ้ๆฉๆชๆญขๆฅๆๅ้กน็ฎ",
+ "dueOn": "ไปปๅกๆชๆญขไบ",
+ "taskRequired": "่ฏทๆทปๅ ไธไธชไปปๅก",
+ "list": "ๅ่กจ",
+ "calendar": "ๆฅๅ",
+ "tasks": "ไปปๅก",
+ "refresh": "ๅทๆฐ"
+ }
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/invite-initial-team-members.json b/worklenz-backend/src/public/locales/zh/invite-initial-team-members.json
new file mode 100644
index 00000000..6ebb9fbf
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/invite-initial-team-members.json
@@ -0,0 +1,8 @@
+{
+ "formTitle": "้่ฏทๆจ็ๅข้ไธ่ตทๅทฅไฝ",
+ "inputLable": "้่ฟ็ตๅญ้ฎไปถ้่ฏท",
+ "addAnother": "ๆทปๅ ๅฆไธไธช",
+ "goBack": "่ฟๅ",
+ "continue": "็ปง็ปญ",
+ "skipForNow": "ๆๆถ่ทณ่ฟ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/kanban-board.json b/worklenz-backend/src/public/locales/zh/kanban-board.json
new file mode 100644
index 00000000..7b72c5d5
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/kanban-board.json
@@ -0,0 +1,19 @@
+{
+ "rename": "้ๅฝๅ",
+ "delete": "ๅ ้ค",
+ "addTask": "ๆทปๅ ไปปๅก",
+ "addSectionButton": "ๆทปๅ ้จๅ",
+ "changeCategory": "ๆดๆน็ฑปๅซ",
+ "deleteTooltip": "ๅ ้ค",
+ "deleteConfirmationTitle": "ๆจ็กฎๅฎๅ๏ผ",
+ "deleteConfirmationOk": "ๆฏ",
+ "deleteConfirmationCancel": "ๅๆถ",
+ "dueDate": "ๆชๆญขๆฅๆ",
+ "cancel": "ๅๆถ",
+ "today": "ไปๅคฉ",
+ "tomorrow": "ๆๅคฉ",
+ "assignToMe": "ๅ้ ็ปๆ",
+ "archive": "ๅฝๆกฃ",
+ "newTaskNamePlaceholder": "ๅไธไธชไปปๅกๅ็งฐ",
+ "newSubtaskNamePlaceholder": "ๅไธไธชๅญไปปๅกๅ็งฐ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/license-expired.json b/worklenz-backend/src/public/locales/zh/license-expired.json
new file mode 100644
index 00000000..838125c2
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/license-expired.json
@@ -0,0 +1,6 @@
+{
+ "title": "ๆจ็Worklenz่ฏ็จๅทฒ่ฟๆ๏ผ",
+ "subtitle": "่ฏท็ซๅณๅ็บงใ",
+ "button": "็ซๅณๅ็บง",
+ "checking": "ๆญฃๅจๆฃๆฅ่ฎข้ ็ถๆ..."
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/navbar.json b/worklenz-backend/src/public/locales/zh/navbar.json
new file mode 100644
index 00000000..c4ed67ab
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/navbar.json
@@ -0,0 +1,31 @@
+{
+ "logoAlt": "Worklenz Logo",
+ "home": "้ฆ้กต",
+ "projects": "้กน็ฎ",
+ "schedule": "ๆฅ็จ",
+ "reporting": "ๆฅๅ",
+ "clients": "ๅฎขๆท",
+ "teams": "ๅข้",
+ "labels": "ๆ ็ญพ",
+ "jobTitles": "่ไฝ",
+ "upgradePlan": "ๅ็บง่ฎกๅ",
+ "upgradePlanTooltip": "ๅ็บง่ฎกๅ",
+ "invite": "้่ฏท",
+ "inviteTooltip": "้่ฏทๅข้ๆๅๅ ๅ ฅ",
+ "switchTeamTooltip": "ๅๆขๅข้",
+ "help": "ๅธฎๅฉ",
+ "notificationTooltip": "ๆฅ็้็ฅ",
+ "profileTooltip": "ๆฅ็ไธชไบบ่ตๆ",
+ "adminCenter": "็ฎก็ไธญๅฟ",
+ "settings": "่ฎพ็ฝฎ",
+ "logOut": "็ปๅบ",
+ "notificationsDrawer": {
+ "read": "ๅทฒ่ฏป้็ฅ",
+ "unread": "ๆช่ฏป้็ฅ",
+ "markAsRead": "ๆ ่ฎฐไธบๅทฒ่ฏป",
+ "readAndJoin": "้ ่ฏปๅนถๅ ๅ ฅ",
+ "accept": "ๆฅๅ",
+ "acceptAndJoin": "ๆฅๅๅนถๅ ๅ ฅ",
+ "noNotifications": "ๆฒกๆ้็ฅ"
+ }
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/organization-name-form.json b/worklenz-backend/src/public/locales/zh/organization-name-form.json
new file mode 100644
index 00000000..df8727d8
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/organization-name-form.json
@@ -0,0 +1,5 @@
+{
+ "nameYourOrganization": "ๅฝๅๆจ็็ป็ปใ",
+ "worklenzAccountTitle": "ไธบๆจ็Worklenz่ดฆๆท้ๆฉไธไธชๅ็งฐใ",
+ "continue": "็ปง็ปญ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/phases-drawer.json b/worklenz-backend/src/public/locales/zh/phases-drawer.json
new file mode 100644
index 00000000..24d21b38
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/phases-drawer.json
@@ -0,0 +1,19 @@
+{
+ "configurePhases": "้ ็ฝฎ้ถๆฎต",
+ "phaseLabel": "้ถๆฎตๆ ็ญพ",
+ "enterPhaseName": "่พๅ ฅ้ถๆฎตๆ ็ญพๅ็งฐ",
+ "addOption": "ๆทปๅ ้้กน",
+ "phaseOptions": "้ถๆฎต้้กน๏ผ",
+ "dragToReorderPhases": "ๆๆฝ้ถๆฎตไปฅ้ๆฐๆๅบใๆฏไธช้ถๆฎตๅฏไปฅๆไธๅ็้ข่ฒใ",
+ "enterNewPhaseName": "่พๅ ฅๆฐ้ถๆฎตๅ็งฐ...",
+ "addPhase": "ๆทปๅ ้ถๆฎต",
+ "noPhasesFound": "ๆชๆพๅฐ้ถๆฎตใ่ฏทๅจไธ้ขๅๅปบๆจ็็ฌฌไธไธช้ถๆฎตใ",
+ "deletePhase": "ๅ ้ค้ถๆฎต",
+ "deletePhaseConfirm": "ๆจ็กฎๅฎ่ฆๅ ้คๆญค้ถๆฎตๅ๏ผๆญคๆไฝๆ ๆณๆค้ใ",
+ "rename": "้ๅฝๅ",
+ "delete": "ๅ ้ค",
+ "enterPhaseName": "่พๅ ฅ้ถๆฎตๅ็งฐ",
+ "selectColor": "้ๆฉ้ข่ฒ",
+ "managePhases": "็ฎก็้ถๆฎต",
+ "close": "ๅ ณ้ญ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/project-drawer.json b/worklenz-backend/src/public/locales/zh/project-drawer.json
new file mode 100644
index 00000000..1649dfde
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/project-drawer.json
@@ -0,0 +1,42 @@
+{
+ "createProject": "ๅๅปบ้กน็ฎ",
+ "editProject": "็ผ่พ้กน็ฎ",
+ "enterCategoryName": "่พๅ ฅ็ฑปๅซๅ็งฐ",
+ "hitEnterToCreate": "ๆๅ่ฝฆ้ฎๅๅปบ๏ผ",
+ "enterNotes": "ๅคๆณจ",
+ "youCanManageClientsUnderSettings": "ๆจๅฏไปฅๅจ่ฎพ็ฝฎไธญ็ฎก็ๅฎขๆท",
+ "addCategory": "ๅ้กน็ฎๆทปๅ ็ฑปๅซ",
+ "newCategory": "ๆฐ็ฑปๅซ",
+ "notes": "ๅคๆณจ",
+ "startDate": "ๅผๅงๆฅๆ",
+ "endDate": "็ปๆๆฅๆ",
+ "estimateWorkingDays": "ไผฐ็ฎๅทฅไฝๆฅ",
+ "estimateManDays": "ไผฐ็ฎไบบๅคฉ",
+ "hoursPerDay": "ๆฏๅคฉๅฐๆถๆฐ",
+ "create": "ๅๅปบ",
+ "update": "ๆดๆฐ",
+ "delete": "ๅ ้ค",
+ "typeToSearchClients": "่พๅ ฅไปฅๆ็ดขๅฎขๆท",
+ "projectColor": "้กน็ฎ้ข่ฒ",
+ "pleaseEnterAName": "่ฏท่พๅ ฅๅ็งฐ",
+ "enterProjectName": "่พๅ ฅ้กน็ฎๅ็งฐ",
+ "name": "ๅ็งฐ",
+ "status": "็ถๆ",
+ "health": "ๅฅๅบท็ถๅต",
+ "category": "็ฑปๅซ",
+ "projectManager": "้กน็ฎ็ป็",
+ "client": "ๅฎขๆท",
+ "deleteConfirmation": "ๆจ็กฎๅฎ่ฆๅ ้คๅ๏ผ",
+ "deleteConfirmationDescription": "่ฟๅฐๅ ้คๆๆ็ธๅ ณๆฐๆฎไธๆ ๆณๆค้ใ",
+ "yes": "ๆฏ",
+ "no": "ๅฆ",
+ "createdAt": "ๅๅปบไบ",
+ "updatedAt": "ๆดๆฐไบ",
+ "by": "็ฑ",
+ "add": "ๆทปๅ ",
+ "asClient": "ไฝไธบๅฎขๆท",
+ "createClient": "ๅๅปบๅฎขๆท",
+ "searchInputPlaceholder": "ๆๅ็งฐๆ็ตๅญ้ฎไปถๆ็ดข",
+ "hoursPerDayValidationMessage": "ๆฏๅคฉๅฐๆถๆฐๅฟ ้กปๆฏ1ๅฐ24ไน้ด็ๆฐๅญ",
+ "noPermission": "ๆ ๆ้"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/project-view-files.json b/worklenz-backend/src/public/locales/zh/project-view-files.json
new file mode 100644
index 00000000..9cbf8ef6
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/project-view-files.json
@@ -0,0 +1,14 @@
+{
+ "nameColumn": "ๅ็งฐ",
+ "attachedTaskColumn": "้ๅ ไปปๅก",
+ "sizeColumn": "ๅคงๅฐ",
+ "uploadedByColumn": "ไธไผ ่ ",
+ "uploadedAtColumn": "ไธไผ ๆถ้ด",
+ "fileIconAlt": "ๆไปถๅพๆ ",
+ "titleDescriptionText": "ๆญค้กน็ฎไธญไปปๅก็ๆๆ้ไปถๅฐๆพ็คบๅจ่ฟ้ใ",
+ "deleteConfirmationTitle": "ๆจ็กฎๅฎๅ๏ผ",
+ "deleteConfirmationOk": "ๆฏ",
+ "deleteConfirmationCancel": "ๅๆถ",
+ "segmentedTooltip": "ๅณๅฐๆจๅบ๏ผๅจๅ่กจ่งๅพๅ็ผฉ็ฅๅพ่งๅพไน้ดๅๆขใ",
+ "emptyText": "้กน็ฎไธญๆฒกๆ้ไปถใ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/project-view-insights.json b/worklenz-backend/src/public/locales/zh/project-view-insights.json
new file mode 100644
index 00000000..903d73d2
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/project-view-insights.json
@@ -0,0 +1,41 @@
+{
+ "overview": {
+ "title": "ๆฆ่ง",
+ "statusOverview": "็ถๆๆฆ่ง",
+ "priorityOverview": "ไผๅ ็บงๆฆ่ง",
+ "lastUpdatedTasks": "ๆ่ฟๆดๆฐ็ไปปๅก"
+ },
+ "members": {
+ "title": "ๆๅ",
+ "tooltip": "ๆๅ",
+ "tasksByMembers": "ๆๆๅๅ็ฑปไปปๅก",
+ "tasksByMembersTooltip": "ๆๆๅๅ็ฑปไปปๅก",
+ "name": "ๅ็งฐ",
+ "taskCount": "ไปปๅก่ฎกๆฐ",
+ "contribution": "่ดก็ฎ",
+ "completed": "ๅทฒๅฎๆ",
+ "incomplete": "ๆชๅฎๆ",
+ "overdue": "้พๆ",
+ "progress": "่ฟๅบฆ"
+ },
+ "tasks": {
+ "overdueTasks": "้พๆไปปๅก",
+ "overLoggedTasks": "่ถ ้ข่ฎฐๅฝไปปๅก",
+ "tasksCompletedEarly": "ๆๅๅฎๆ็ไปปๅก",
+ "tasksCompletedLate": "ๅปถ่ฟๅฎๆ็ไปปๅก",
+ "overLoggedTasksTooltip": "่ฎฐๅฝๆถ้ด่ถ ่ฟ้ข่ฎกๆถ้ด็ไปปๅก",
+ "overdueTasksTooltip": "่ถ ่ฟๆชๆญขๆฅๆ็ไปปๅก"
+ },
+ "common": {
+ "seeAll": "ๆฅ็ๅ จ้จ",
+ "totalLoggedHours": "ๆป่ฎฐๅฝๅฐๆถๆฐ",
+ "totalEstimation": "ๆปไผฐ็ฎ",
+ "completedTasks": "ๅทฒๅฎๆไปปๅก",
+ "incompleteTasks": "ๆชๅฎๆไปปๅก",
+ "overdueTasks": "้พๆไปปๅก",
+ "overdueTasksTooltip": "่ถ ่ฟๆชๆญขๆฅๆ็ไปปๅก",
+ "totalLoggedHoursTooltip": "ไปปๅกไผฐ็ฎๅไปปๅก่ฎฐๅฝๆถ้ดใ",
+ "includeArchivedTasks": "ๅ ๅซๅทฒๅฝๆกฃไปปๅก",
+ "export": "ๅฏผๅบ"
+ }
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/project-view-members.json b/worklenz-backend/src/public/locales/zh/project-view-members.json
new file mode 100644
index 00000000..3d217694
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/project-view-members.json
@@ -0,0 +1,17 @@
+{
+ "nameColumn": "ๅ็งฐ",
+ "jobTitleColumn": "่ไฝ",
+ "emailColumn": "็ตๅญ้ฎไปถ",
+ "tasksColumn": "ไปปๅก",
+ "taskProgressColumn": "ไปปๅก่ฟๅบฆ",
+ "accessColumn": "่ฎฟ้ฎๆ้",
+ "fileIconAlt": "ๆไปถๅพๆ ",
+ "deleteConfirmationTitle": "ๆจ็กฎๅฎๅ๏ผ",
+ "deleteConfirmationOk": "ๆฏ",
+ "deleteConfirmationCancel": "ๅๆถ",
+ "refreshButtonTooltip": "ๅทๆฐๆๅ",
+ "deleteButtonTooltip": "ไป้กน็ฎไธญ็งป้ค",
+ "memberCount": "ๆๅ",
+ "membersCountPlural": "ๆๅ",
+ "emptyText": "้กน็ฎไธญๆฒกๆ้ไปถใ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/project-view-updates.json b/worklenz-backend/src/public/locales/zh/project-view-updates.json
new file mode 100644
index 00000000..b34c71ea
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/project-view-updates.json
@@ -0,0 +1,6 @@
+{
+ "inputPlaceholder": "ๆทปๅ ่ฏ่ฎบ",
+ "addButton": "ๆทปๅ ",
+ "cancelButton": "ๅๆถ",
+ "deleteButton": "ๅ ้ค"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/project-view.json b/worklenz-backend/src/public/locales/zh/project-view.json
new file mode 100644
index 00000000..ff756ea5
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/project-view.json
@@ -0,0 +1,14 @@
+{
+ "taskList": "ไปปๅกๅ่กจ",
+ "board": "็ๆฟ",
+ "insights": "ๆฐๆฎๆดๅฏ",
+ "files": "ๆไปถ",
+ "members": "ๆๅ",
+ "updates": "ๅจๆๆดๆฐ",
+ "projectView": "้กน็ฎ่งๅพ",
+ "loading": "ๆญฃๅจๅ ่ฝฝ้กน็ฎ...",
+ "error": "ๅ ่ฝฝ้กน็ฎๆถๅบ้",
+ "pinnedTab": "ๅทฒๅบๅฎไธบ้ป่ฎคๆ ็ญพ้กต",
+ "pinTab": "ๅบๅฎไธบ้ป่ฎคๆ ็ญพ้กต",
+ "unpinTab": "ๅๆถๅบๅฎ้ป่ฎคๆ ็ญพ้กต"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/project-view/import-task-templates.json b/worklenz-backend/src/public/locales/zh/project-view/import-task-templates.json
new file mode 100644
index 00000000..3dae9403
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/project-view/import-task-templates.json
@@ -0,0 +1,11 @@
+{
+ "importTaskTemplate": "ๅฏผๅ ฅไปปๅกๆจกๆฟ",
+ "templateName": "ๆจกๆฟๅ็งฐ",
+ "templateDescription": "ๆจกๆฟๆ่ฟฐ",
+ "selectedTasks": "ๅทฒ้ไปปๅก",
+ "tasks": "ไปปๅก",
+ "templates": "ๆจกๆฟ",
+ "remove": "็งป้ค",
+ "cancel": "ๅๆถ",
+ "import": "ๅฏผๅ ฅ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/project-view/project-member-drawer.json b/worklenz-backend/src/public/locales/zh/project-view/project-member-drawer.json
new file mode 100644
index 00000000..f412f22b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/project-view/project-member-drawer.json
@@ -0,0 +1,7 @@
+{
+ "title": "้กน็ฎๆๅ",
+ "searchLabel": "้่ฟๆทปๅ ๅ็งฐๆ็ตๅญ้ฎไปถๆทปๅ ๆๅ",
+ "searchPlaceholder": "่พๅ ฅๅ็งฐๆ็ตๅญ้ฎไปถ",
+ "inviteAsAMember": "้่ฏทไธบๆๅ",
+ "inviteNewMemberByEmail": "้่ฟ็ตๅญ้ฎไปถ้่ฏทๆฐๆๅ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/project-view/project-view-header.json b/worklenz-backend/src/public/locales/zh/project-view/project-view-header.json
new file mode 100644
index 00000000..9f8ca8ed
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/project-view/project-view-header.json
@@ -0,0 +1,30 @@
+{
+ "importTasks": "ๅฏผๅ ฅไปปๅก",
+ "importTask": "ๅฏผๅ ฅไปปๅก",
+ "createTask": "ๅๅปบไปปๅก",
+ "settings": "่ฎพ็ฝฎ",
+ "subscribe": "่ฎข้ ",
+ "unsubscribe": "ๅๆถ่ฎข้ ",
+ "deleteProject": "ๅ ้ค้กน็ฎ",
+ "startDate": "ๅผๅงๆฅๆ",
+ "endDate": "็ปๆๆฅๆ",
+ "projectSettings": "้กน็ฎ่ฎพ็ฝฎ",
+ "projectSummary": "้กน็ฎๆ่ฆ",
+ "receiveProjectSummary": "ๆฏๆๆฅๆถ้กน็ฎๆ่ฆใ",
+ "refreshProject": "ๅทๆฐ้กน็ฎ",
+ "saveAsTemplate": "ไฟๅญไธบๆจกๆฟ",
+ "invite": "้่ฏท",
+ "share": "ๅไบซ",
+ "subscribeTooltip": "่ฎข้ ้กน็ฎ้็ฅ",
+ "unsubscribeTooltip": "ๅๆถ่ฎข้ ้กน็ฎ้็ฅ",
+ "refreshTooltip": "ๅทๆฐ้กน็ฎๆฐๆฎ",
+ "settingsTooltip": "ๆๅผ้กน็ฎ่ฎพ็ฝฎ",
+ "saveAsTemplateTooltip": "ๅฐๆญค้กน็ฎไฟๅญไธบๆจกๆฟ",
+ "inviteTooltip": "้่ฏทๅข้ๆๅๅ ๅ ฅๆญค้กน็ฎ",
+ "createTaskTooltip": "ๅๅปบๆฐไปปๅก",
+ "importTaskTooltip": "ไปๆจกๆฟๅฏผๅ ฅไปปๅก",
+ "navigateBackTooltip": "่ฟๅ้กน็ฎๅ่กจ",
+ "projectStatusTooltip": "้กน็ฎ็ถๆ",
+ "projectDatesInfo": "้กน็ฎๆถ้ดๅฎๆไฟกๆฏ",
+ "projectCategoryTooltip": "้กน็ฎ็ฑปๅซ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/project-view/save-as-template.json b/worklenz-backend/src/public/locales/zh/project-view/save-as-template.json
new file mode 100644
index 00000000..d1d3dfa8
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/project-view/save-as-template.json
@@ -0,0 +1,27 @@
+{
+ "title": "ไฟๅญไธบๆจกๆฟ",
+ "templateName": "ๆจกๆฟๅ็งฐ",
+ "includes": "้กน็ฎไธญๅบๅ ๅซๅชไบๅ ๅฎนๅฐๆจกๆฟไธญ๏ผ",
+ "includesOptions": {
+ "statuses": "็ถๆ",
+ "phases": "้ถๆฎต",
+ "labels": "ๆ ็ญพ"
+ },
+ "taskIncludes": "ไปปๅกไธญๅบๅ ๅซๅชไบๅ ๅฎนๅฐๆจกๆฟไธญ๏ผ",
+ "taskIncludesOptions": {
+ "statuses": "็ถๆ",
+ "phases": "้ถๆฎต",
+ "labels": "ๆ ็ญพ",
+ "name": "ๅ็งฐ",
+ "priority": "ไผๅ ็บง",
+ "status": "็ถๆ",
+ "phase": "้ถๆฎต",
+ "label": "ๆ ็ญพ",
+ "timeEstimate": "้ข่ฎก็จๆถ",
+ "description": "ๆ่ฟฐ",
+ "subTasks": "ๅญไปปๅก"
+ },
+ "cancel": "ๅๆถ",
+ "save": "ไฟๅญ",
+ "templateNamePlaceholder": "่พๅ ฅๆจกๆฟๅ็งฐ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/reporting-members-drawer.json b/worklenz-backend/src/public/locales/zh/reporting-members-drawer.json
new file mode 100644
index 00000000..db42a74b
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/reporting-members-drawer.json
@@ -0,0 +1,76 @@
+{
+ "exportButton": "ๅฏผๅบ",
+ "timeLogsButton": "ๆถ้ดๆฅๅฟ",
+ "activityLogsButton": "ๆดปๅจๆฅๅฟ",
+ "tasksButton": "ไปปๅก",
+ "searchByNameInputPlaceholder": "ๆๅ็งฐๆ็ดข",
+ "overviewTab": "ๆฆ่ง",
+ "timeLogsTab": "ๆถ้ดๆฅๅฟ",
+ "activityLogsTab": "ๆดปๅจๆฅๅฟ",
+ "tasksTab": "ไปปๅก",
+ "projectsText": "้กน็ฎ",
+ "totalTasksText": "ไปปๅกๆปๆฐ",
+ "assignedTasksText": "ๅทฒๅ้ ไปปๅก",
+ "completedTasksText": "ๅทฒๅฎๆไปปๅก",
+ "ongoingTasksText": "่ฟ่กไธญไปปๅก",
+ "overdueTasksText": "้พๆไปปๅก",
+ "loggedHoursText": "่ฎฐๅฝๅฐๆถๆฐ",
+ "tasksText": "ไปปๅก",
+ "allText": "ๅ จ้จ",
+ "tasksByProjectsText": "ๆ้กน็ฎๅ็ฑปไปปๅก",
+ "tasksByStatusText": "ๆ็ถๆๅ็ฑปไปปๅก",
+ "tasksByPriorityText": "ๆไผๅ ็บงๅ็ฑปไปปๅก",
+ "todoText": "ๅพ ๅ",
+ "doingText": "่ฟ่กไธญ",
+ "doneText": "ๅทฒๅฎๆ",
+ "lowText": "ไฝ",
+ "mediumText": "ไธญ",
+ "highText": "้ซ",
+ "billableButton": "ๅฏ่ฎก่ดน",
+ "billableText": "ๅฏ่ฎก่ดน",
+ "nonBillableText": "ไธๅฏ่ฎก่ดน",
+ "timeLogsEmptyPlaceholder": "ๆฒกๆๆถ้ดๆฅๅฟๅฏๆพ็คบ",
+ "loggedText": "่ฎฐๅฝ",
+ "forText": "ไธบ",
+ "inText": "ๅจ",
+ "updatedText": "ๆดๆฐ",
+ "fromText": "ไป",
+ "toText": "ๅฐ",
+ "withinText": "ๅจ...ไนๅ ",
+ "activityLogsEmptyPlaceholder": "ๆฒกๆๆดปๅจๆฅๅฟๅฏๆพ็คบ",
+ "filterByText": "็ญ้ไพๆฎ๏ผ",
+ "selectProjectPlaceholder": "้ๆฉ้กน็ฎ",
+ "taskColumn": "ไปปๅก",
+ "nameColumn": "ๅ็งฐ",
+ "projectColumn": "้กน็ฎ",
+ "statusColumn": "็ถๆ",
+ "priorityColumn": "ไผๅ ็บง",
+ "dueDateColumn": "ๆชๆญขๆฅๆ",
+ "completedDateColumn": "ๅฎๆๆฅๆ",
+ "estimatedTimeColumn": "้ข่ฎก็จๆถ",
+ "loggedTimeColumn": "่ฎฐๅฝๆถ้ด",
+ "overloggedTimeColumn": "่ถ ้ข่ฎฐๅฝๆถ้ด",
+ "daysLeftColumn": "ๅฉไฝๅคฉๆฐ/้พๆ",
+ "startDateColumn": "ๅผๅงๆฅๆ",
+ "endDateColumn": "็ปๆๆฅๆ",
+ "actualTimeColumn": "ๅฎ้ ๆถ้ด",
+ "projectHealthColumn": "้กน็ฎๅฅๅบท็ถๅต",
+ "categoryColumn": "็ฑปๅซ",
+ "projectManagerColumn": "้กน็ฎ็ป็",
+ "tasksStatsOverviewDrawerTitle": "็ไปปๅก",
+ "projectsStatsOverviewDrawerTitle": "็้กน็ฎ",
+ "cancelledText": "ๅทฒๅๆถ",
+ "blockedText": "ๅทฒ้ปๅก",
+ "onHoldText": "ๆๅ",
+ "proposedText": "ๆ่ฎฎ",
+ "inPlanningText": "่งๅไธญ",
+ "inProgressText": "่ฟ่กไธญ",
+ "completedText": "ๅทฒๅฎๆ",
+ "continuousText": "ๆ็ปญ",
+ "daysLeftText": "ๅคฉๅฉไฝ",
+ "daysOverdueText": "ๅคฉ้พๆ",
+ "notSetText": "ๆช่ฎพ็ฝฎ",
+ "needsAttentionText": "้่ฆๅ ณๆณจ",
+ "atRiskText": "ๆ้ฃ้ฉ",
+ "goodText": "่ฏๅฅฝ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/reporting-members.json b/worklenz-backend/src/public/locales/zh/reporting-members.json
new file mode 100644
index 00000000..de4c23bb
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/reporting-members.json
@@ -0,0 +1,31 @@
+{
+ "yesterdayText": "ๆจๅคฉ",
+ "lastSevenDaysText": "่ฟๅป7ๅคฉ",
+ "lastWeekText": "ไธๅจ",
+ "lastThirtyDaysText": "่ฟๅป30ๅคฉ",
+ "lastMonthText": "ไธไธชๆ",
+ "lastThreeMonthsText": "่ฟๅป3ไธชๆ",
+ "allTimeText": "ๆๆๆถ้ด",
+ "customRangeText": "่ชๅฎไน่ๅด",
+ "startDateInputPlaceholder": "ๅผๅงๆฅๆ",
+ "EndDateInputPlaceholder": "็ปๆๆฅๆ",
+ "filterButton": "็ญ้",
+ "membersTitle": "ๆๅ",
+ "includeArchivedButton": "ๅ ๅซๅทฒๅฝๆกฃ้กน็ฎ",
+ "exportButton": "ๅฏผๅบ",
+ "excelButton": "Excel",
+ "searchByNameInputPlaceholder": "ๆๅ็งฐๆ็ดข",
+ "memberColumn": "ๆๅ",
+ "tasksProgressColumn": "ไปปๅก่ฟๅบฆ",
+ "tasksAssignedColumn": "ๅ้ ไปปๅก",
+ "completedTasksColumn": "ๅทฒๅฎๆไปปๅก",
+ "overdueTasksColumn": "้พๆไปปๅก",
+ "ongoingTasksColumn": "่ฟ่กไธญไปปๅก",
+ "tasksAssignedColumnTooltip": "ๅจ้ๅฎๆฅๆ่ๅดๅ ๅ้ ็ไปปๅก",
+ "overdueTasksColumnTooltip": "ๅจ้ๅฎๆฅๆ่ๅด็ปๆๆถ้พๆ็ไปปๅก",
+ "completedTasksColumnTooltip": "ๅจ้ๅฎๆฅๆ่ๅดๅ ๅฎๆ็ไปปๅก",
+ "ongoingTasksColumnTooltip": "ๅทฒๅผๅงไฝๅฐๆชๅฎๆ็ไปปๅก",
+ "todoText": "ๅพ ๅ",
+ "doingText": "่ฟ่กไธญ",
+ "doneText": "ๅทฒๅฎๆ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/reporting-overview-drawer.json b/worklenz-backend/src/public/locales/zh/reporting-overview-drawer.json
new file mode 100644
index 00000000..a02b318f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/reporting-overview-drawer.json
@@ -0,0 +1,33 @@
+{
+ "exportButton": "ๅฏผๅบ",
+ "projectsButton": "้กน็ฎ",
+ "membersButton": "ๆๅ",
+ "searchByNameInputPlaceholder": "ๆๅ็งฐๆ็ดข",
+ "overviewTab": "ๆฆ่ง",
+ "projectsTab": "้กน็ฎ",
+ "membersTab": "ๆๅ",
+ "projectsByStatusText": "ๆ็ถๆๅ็ฑป้กน็ฎ",
+ "projectsByCategoryText": "ๆ็ฑปๅซๅ็ฑป้กน็ฎ",
+ "projectsByHealthText": "ๆๅฅๅบท็ถๅตๅ็ฑป้กน็ฎ",
+ "projectsText": "้กน็ฎ",
+ "allText": "ๅ จ้จ",
+ "cancelledText": "ๅทฒๅๆถ",
+ "blockedText": "ๅทฒ้ปๅก",
+ "onHoldText": "ๆๅ",
+ "proposedText": "ๆ่ฎฎ",
+ "inPlanningText": "่งๅไธญ",
+ "inProgressText": "่ฟ่กไธญ",
+ "completedText": "ๅทฒๅฎๆ",
+ "continuousText": "ๆ็ปญ",
+ "notSetText": "ๆช่ฎพ็ฝฎ",
+ "needsAttentionText": "้่ฆๅ ณๆณจ",
+ "atRiskText": "ๆ้ฃ้ฉ",
+ "goodText": "่ฏๅฅฝ",
+ "nameColumn": "ๅ็งฐ",
+ "emailColumn": "็ตๅญ้ฎไปถ",
+ "projectsColumn": "้กน็ฎ",
+ "tasksColumn": "ไปปๅก",
+ "overdueTasksColumn": "้พๆไปปๅก",
+ "completedTasksColumn": "ๅทฒๅฎๆไปปๅก",
+ "ongoingTasksColumn": "่ฟ่กไธญไปปๅก"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/reporting-overview.json b/worklenz-backend/src/public/locales/zh/reporting-overview.json
new file mode 100644
index 00000000..fb172817
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/reporting-overview.json
@@ -0,0 +1,22 @@
+{
+ "overviewTitle": "ๆฆ่ง",
+ "includeArchivedButton": "ๅ ๅซๅทฒๅฝๆกฃ้กน็ฎ",
+ "teamCount": "ๅข้",
+ "teamCountPlural": "ๅข้",
+ "projectCount": "้กน็ฎ",
+ "projectCountPlural": "้กน็ฎ",
+ "memberCount": "ๆๅ",
+ "memberCountPlural": "ๆๅ",
+ "activeProjectCount": "ๆดป่ท้กน็ฎ",
+ "activeProjectCountPlural": "ๆดป่ท้กน็ฎ",
+ "overdueProjectCount": "้พๆ้กน็ฎ",
+ "overdueProjectCountPlural": "้พๆ้กน็ฎ",
+ "unassignedMemberCount": "ๆชๅ้ ๆๅ",
+ "unassignedMemberCountPlural": "ๆชๅ้ ๆๅ",
+ "memberWithOverdueTaskCount": "ๆ้พๆไปปๅก็ๆๅ",
+ "memberWithOverdueTaskCountPlural": "ๆ้พๆไปปๅก็ๆๅ",
+ "teamsText": "ๅข้",
+ "nameColumn": "ๅ็งฐ",
+ "projectsColumn": "้กน็ฎ",
+ "membersColumn": "ๆๅ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/reporting-projects-drawer.json b/worklenz-backend/src/public/locales/zh/reporting-projects-drawer.json
new file mode 100644
index 00000000..d2f2f6ef
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/reporting-projects-drawer.json
@@ -0,0 +1,52 @@
+{
+ "exportButton": "ๅฏผๅบ",
+ "membersButton": "ๆๅ",
+ "tasksButton": "ไปปๅก",
+ "searchByNameInputPlaceholder": "ๆๅ็งฐๆ็ดข",
+ "overviewTab": "ๆฆ่ง",
+ "membersTab": "ๆๅ",
+ "tasksTab": "ไปปๅก",
+ "completedTasksText": "ๅทฒๅฎๆไปปๅก",
+ "incompleteTasksText": "ๆชๅฎๆไปปๅก",
+ "overdueTasksText": "้พๆไปปๅก",
+ "allocatedHoursText": "ๅทฒๅ้ ๅฐๆถๆฐ",
+ "loggedHoursText": "ๅทฒ่ฎฐๅฝๅฐๆถๆฐ",
+ "tasksText": "ไปปๅก",
+ "allText": "ๅ จ้จ",
+ "tasksByStatusText": "ๆ็ถๆๅ็ฑปไปปๅก",
+ "tasksByPriorityText": "ๆไผๅ ็บงๅ็ฑปไปปๅก",
+ "tasksByDueDateText": "ๆๆชๆญขๆฅๆๅ็ฑปไปปๅก",
+ "todoText": "ๅพ ๅ",
+ "doingText": "่ฟ่กไธญ",
+ "doneText": "ๅทฒๅฎๆ",
+ "lowText": "ไฝ",
+ "mediumText": "ไธญ",
+ "highText": "้ซ",
+ "completedText": "ๅทฒๅฎๆ",
+ "upcomingText": "ๅณๅฐๅฐๆฅ",
+ "overdueText": "้พๆ",
+ "noDueDateText": "ๆ ๆชๆญขๆฅๆ",
+ "nameColumn": "ๅ็งฐ",
+ "tasksCountColumn": "ไปปๅก่ฎกๆฐ",
+ "completedTasksColumn": "ๅทฒๅฎๆไปปๅก",
+ "incompleteTasksColumn": "ๆชๅฎๆไปปๅก",
+ "overdueTasksColumn": "้พๆไปปๅก",
+ "contributionColumn": "่ดก็ฎ",
+ "progressColumn": "่ฟๅบฆ",
+ "loggedTimeColumn": "่ฎฐๅฝๆถ้ด",
+ "taskColumn": "ไปปๅก",
+ "projectColumn": "้กน็ฎ",
+ "statusColumn": "็ถๆ",
+ "priorityColumn": "ไผๅ ็บง",
+ "phaseColumn": "้ถๆฎต",
+ "dueDateColumn": "ๆชๆญขๆฅๆ",
+ "completedDateColumn": "ๅฎๆๆฅๆ",
+ "estimatedTimeColumn": "้ข่ฎก็จๆถ",
+ "overloggedTimeColumn": "่ถ ้ข่ฎฐๅฝๆถ้ด",
+ "completedOnColumn": "ๅฎๆไบ",
+ "daysOverdueColumn": "้พๆๅคฉๆฐ",
+ "groupByText": "ๅ็ปไพๆฎ๏ผ",
+ "statusText": "็ถๆ",
+ "priorityText": "ไผๅ ็บง",
+ "phaseText": "้ถๆฎต"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/reporting-projects-filters.json b/worklenz-backend/src/public/locales/zh/reporting-projects-filters.json
new file mode 100644
index 00000000..ddfbe104
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/reporting-projects-filters.json
@@ -0,0 +1,31 @@
+{
+ "searchByNamePlaceholder": "ๆๅ็งฐๆ็ดข",
+ "searchByCategoryPlaceholder": "ๆ็ฑปๅซๆ็ดข",
+ "statusText": "็ถๆ",
+ "healthText": "ๅฅๅบท็ถๅต",
+ "categoryText": "็ฑปๅซ",
+ "projectManagerText": "้กน็ฎ็ป็",
+ "showFieldsText": "ๆพ็คบๅญๆฎต",
+ "cancelledText": "ๅทฒๅๆถ",
+ "blockedText": "ๅทฒ้ปๅก",
+ "onHoldText": "ๆๅ",
+ "proposedText": "ๆ่ฎฎ",
+ "inPlanningText": "่งๅไธญ",
+ "inProgressText": "่ฟ่กไธญ",
+ "completedText": "ๅทฒๅฎๆ",
+ "continuousText": "ๆ็ปญ",
+ "notSetText": "ๆช่ฎพ็ฝฎ",
+ "needsAttentionText": "้่ฆๅ ณๆณจ",
+ "atRiskText": "ๆ้ฃ้ฉ",
+ "goodText": "่ฏๅฅฝ",
+ "nameText": "้กน็ฎ",
+ "estimatedVsActualText": "้ข่ฎก็จๆถ vs ๅฎ้ ็จๆถ",
+ "tasksProgressText": "ไปปๅก่ฟๅบฆ",
+ "lastActivityText": "ๆๅๆดปๅจ",
+ "datesText": "ๅผๅง/็ปๆๆฅๆ",
+ "daysLeftText": "ๅฉไฝๅคฉๆฐ/้พๆ",
+ "projectHealthText": "้กน็ฎๅฅๅบท็ถๅต",
+ "projectUpdateText": "้กน็ฎๆดๆฐ",
+ "clientText": "ๅฎขๆท",
+ "teamText": "ๅข้"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/reporting-projects.json b/worklenz-backend/src/public/locales/zh/reporting-projects.json
new file mode 100644
index 00000000..0ff7d415
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/reporting-projects.json
@@ -0,0 +1,44 @@
+{
+ "projectCount": "้กน็ฎ",
+ "projectCountPlural": "้กน็ฎ",
+ "includeArchivedButton": "ๅ ๅซๅทฒๅฝๆกฃ้กน็ฎ",
+ "exportButton": "ๅฏผๅบ",
+ "excelButton": "Excel",
+ "projectColumn": "้กน็ฎ",
+ "estimatedVsActualColumn": "้ข่ฎก็จๆถ vs ๅฎ้ ็จๆถ",
+ "tasksProgressColumn": "ไปปๅก่ฟๅบฆ",
+ "lastActivityColumn": "ๆๅๆดปๅจ",
+ "statusColumn": "็ถๆ",
+ "datesColumn": "ๅผๅง/็ปๆๆฅๆ",
+ "daysLeftColumn": "ๅฉไฝๅคฉๆฐ/้พๆ",
+ "projectHealthColumn": "้กน็ฎๅฅๅบท็ถๅต",
+ "categoryColumn": "็ฑปๅซ",
+ "projectUpdateColumn": "้กน็ฎๆดๆฐ",
+ "clientColumn": "ๅฎขๆท",
+ "teamColumn": "ๅข้",
+ "projectManagerColumn": "้กน็ฎ็ป็",
+ "openButton": "ๆๅผ",
+ "estimatedText": "้ข่ฎก",
+ "actualText": "ๅฎ้ ",
+ "todoText": "ๅพ ๅ",
+ "doingText": "่ฟ่กไธญ",
+ "doneText": "ๅทฒๅฎๆ",
+ "cancelledText": "ๅทฒๅๆถ",
+ "blockedText": "ๅทฒ้ปๅก",
+ "onHoldText": "ๆๅ",
+ "proposedText": "ๆ่ฎฎ",
+ "inPlanningText": "่งๅไธญ",
+ "inProgressText": "่ฟ่กไธญ",
+ "completedText": "ๅทฒๅฎๆ",
+ "continuousText": "ๆ็ปญ",
+ "daysLeftText": "ๅคฉๅฉไฝ",
+ "dayLeftText": "ๅคฉๅฉไฝ",
+ "daysOverdueText": "ๅคฉ้พๆ",
+ "notSetText": "ๆช่ฎพ็ฝฎ",
+ "needsAttentionText": "้่ฆๅ ณๆณจ",
+ "atRiskText": "ๆ้ฃ้ฉ",
+ "goodText": "่ฏๅฅฝ",
+ "setCategoryText": "่ฎพ็ฝฎ็ฑปๅซ",
+ "searchByNameInputPlaceholder": "ๆๅ็งฐๆ็ดข",
+ "todayText": "ไปๅคฉ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/reporting-sidebar.json b/worklenz-backend/src/public/locales/zh/reporting-sidebar.json
new file mode 100644
index 00000000..8a8206fb
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/reporting-sidebar.json
@@ -0,0 +1,8 @@
+{
+ "overview": "ๆฆ่ง",
+ "projects": "้กน็ฎ",
+ "members": "ๆๅ",
+ "timeReports": "็จๆถๆฅๅ",
+ "estimateVsActual": "้ข่ฎก็จๆถ vs ๅฎ้ ็จๆถ",
+ "currentOrganizationTooltip": "ๅฝๅ็็ป็ป"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/schedule.json b/worklenz-backend/src/public/locales/zh/schedule.json
new file mode 100644
index 00000000..53fa8a97
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/schedule.json
@@ -0,0 +1,34 @@
+{
+ "today": "ไปๅคฉ",
+ "week": "ๅจ",
+ "month": "ๆ",
+ "settings": "่ฎพ็ฝฎ",
+ "workingDays": "ๅทฅไฝๆฅ",
+ "monday": "ๆๆไธ",
+ "tuesday": "ๆๆไบ",
+ "wednesday": "ๆๆไธ",
+ "thursday": "ๆๆๅ",
+ "friday": "ๆๆไบ",
+ "saturday": "ๆๆๅ ญ",
+ "sunday": "ๆๆๆฅ",
+ "workingHours": "ๅทฅไฝๆถ้ด",
+ "hours": "ๅฐๆถ",
+ "saveButton": "ไฟๅญ",
+ "totalAllocation": "ๆปๅ้ ",
+ "timeLogged": "่ฎฐๅฝๆถ้ด",
+ "remainingTime": "ๅฉไฝๆถ้ด",
+ "total": "ๆป่ฎก",
+ "perDay": "ๆฏๅคฉ",
+ "tasks": "ไปปๅก",
+ "startDate": "ๅผๅงๆฅๆ",
+ "endDate": "็ปๆๆฅๆ",
+ "hoursPerDay": "ๆฏๅคฉๅฐๆถๆฐ",
+ "totalHours": "ๆปๅฐๆถๆฐ",
+ "deleteButton": "ๅ ้ค",
+ "cancelButton": "ๅๆถ",
+ "tabTitle": "ๆฒกๆๅผๅงๅ็ปๆๆฅๆ็ไปปๅก",
+ "allocatedTime": "ๅ้ ๆถ้ด",
+ "totalLogged": "ๆป่ฎฐๅฝ",
+ "loggedBillable": "ๅทฒ่ฎฐๅฝๅฏ่ฎก่ดน",
+ "loggedNonBillable": "ๅทฒ่ฎฐๅฝไธๅฏ่ฎก่ดน"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/settings/categories.json b/worklenz-backend/src/public/locales/zh/settings/categories.json
new file mode 100644
index 00000000..00027081
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/settings/categories.json
@@ -0,0 +1,10 @@
+{
+ "categoryColumn": "็ฑปๅซ",
+ "deleteConfirmationTitle": "ๆจ็กฎๅฎๅ๏ผ",
+ "deleteConfirmationOk": "ๆฏ",
+ "deleteConfirmationCancel": "ๅๆถ",
+ "associatedTaskColumn": "ๅ ณ่้กน็ฎ",
+ "searchPlaceholder": "ๆๅ็งฐๆ็ดข",
+ "emptyText": "ๅจๆดๆฐๆๅๅปบ้กน็ฎๆถๅฏไปฅๅๅปบ็ฑปๅซใ",
+ "colorChangeTooltip": "็นๅปๆดๆน้ข่ฒ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/settings/change-password.json b/worklenz-backend/src/public/locales/zh/settings/change-password.json
new file mode 100644
index 00000000..30cec581
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/settings/change-password.json
@@ -0,0 +1,15 @@
+{
+ "title": "ๆดๆนๅฏ็ ",
+ "currentPassword": "ๅฝๅๅฏ็ ",
+ "newPassword": "ๆฐๅฏ็ ",
+ "confirmPassword": "็กฎ่ฎคๅฏ็ ",
+ "currentPasswordPlaceholder": "่พๅ ฅๆจ็ๅฝๅๅฏ็ ",
+ "newPasswordPlaceholder": "ๆฐๅฏ็ ",
+ "confirmPasswordPlaceholder": "็กฎ่ฎคๅฏ็ ",
+ "currentPasswordRequired": "่ฏท่พๅ ฅๆจ็ๅฝๅๅฏ็ ๏ผ",
+ "newPasswordRequired": "่ฏท่พๅ ฅๆจ็ๆฐๅฏ็ ๏ผ",
+ "passwordValidationError": "ๅฏ็ ๅฟ ้กป่ณๅฐๅ ๅซ8ไธชๅญ็ฌฆ๏ผๅ ๆฌไธไธชๅคงๅๅญๆฏใไธไธชๆฐๅญๅไธไธช็ฌฆๅทใ",
+ "passwordMismatch": "ๅฏ็ ไธๅน้ ๏ผ",
+ "passwordRequirements": "ๆฐๅฏ็ ๅบ่ณๅฐๅ ๅซ8ไธชๅญ็ฌฆ๏ผๅ ๆฌไธไธชๅคงๅๅญๆฏใไธไธชๆฐๅญๅไธไธช็ฌฆๅทใ",
+ "updateButton": "ๆดๆฐๅฏ็ "
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/settings/clients.json b/worklenz-backend/src/public/locales/zh/settings/clients.json
new file mode 100644
index 00000000..c06b1adc
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/settings/clients.json
@@ -0,0 +1,22 @@
+{
+ "nameColumn": "ๅ็งฐ",
+ "projectColumn": "้กน็ฎ",
+ "noProjectsAvailable": "ๆฒกๆๅฏ็จ็้กน็ฎ",
+ "deleteConfirmationTitle": "ๆจ็กฎๅฎๅ๏ผ",
+ "deleteConfirmationOk": "ๆฏ",
+ "deleteConfirmationCancel": "ๅๆถ",
+ "searchPlaceholder": "ๆๅ็งฐๆ็ดข",
+ "createClient": "ๅๅปบๅฎขๆท",
+ "pinTooltip": "็นๅปๅฐๅ ถๅบๅฎๅฐไธป่ๅ",
+ "createClientDrawerTitle": "ๅๅปบๅฎขๆท",
+ "updateClientDrawerTitle": "ๆดๆฐๅฎขๆท",
+ "nameLabel": "ๅ็งฐ",
+ "namePlaceholder": "ๅ็งฐ",
+ "nameRequiredError": "่ฏท่พๅ ฅๅ็งฐ",
+ "createButton": "ๅๅปบ",
+ "updateButton": "ๆดๆฐ",
+ "createClientSuccessMessage": "ๅฎขๆทๅๅปบๆๅ๏ผ",
+ "createClientErrorMessage": "ๅฎขๆทๅๅปบๅคฑ่ดฅ๏ผ",
+ "updateClientSuccessMessage": "ๅฎขๆทๆดๆฐๆๅ๏ผ",
+ "updateClientErrorMessage": "ๅฎขๆทๆดๆฐๅคฑ่ดฅ๏ผ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/settings/job-titles.json b/worklenz-backend/src/public/locales/zh/settings/job-titles.json
new file mode 100644
index 00000000..c0458bb6
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/settings/job-titles.json
@@ -0,0 +1,20 @@
+{
+ "nameColumn": "ๅ็งฐ",
+ "deleteConfirmationTitle": "ๆจ็กฎๅฎๅ๏ผ",
+ "deleteConfirmationOk": "ๆฏ",
+ "deleteConfirmationCancel": "ๅๆถ",
+ "searchPlaceholder": "ๆๅ็งฐๆ็ดข",
+ "createJobTitleButton": "ๅๅปบ่ไฝ",
+ "pinTooltip": "็นๅปๅฐๅ ถๅบๅฎๅฐไธป่ๅ",
+ "createJobTitleDrawerTitle": "ๅๅปบ่ไฝ",
+ "updateJobTitleDrawerTitle": "ๆดๆฐ่ไฝ",
+ "nameLabel": "ๅ็งฐ",
+ "namePlaceholder": "ๅ็งฐ",
+ "nameRequiredError": "่ฏท่พๅ ฅๅ็งฐ",
+ "createButton": "ๅๅปบ",
+ "updateButton": "ๆดๆฐ",
+ "createJobTitleSuccessMessage": "่ไฝๅๅปบๆๅ๏ผ",
+ "createJobTitleErrorMessage": "่ไฝๅๅปบๅคฑ่ดฅ๏ผ",
+ "updateJobTitleSuccessMessage": "่ไฝๆดๆฐๆๅ๏ผ",
+ "updateJobTitleErrorMessage": "่ไฝๆดๆฐๅคฑ่ดฅ๏ผ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/settings/labels.json b/worklenz-backend/src/public/locales/zh/settings/labels.json
new file mode 100644
index 00000000..ab0d01cd
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/settings/labels.json
@@ -0,0 +1,11 @@
+{
+ "labelColumn": "ๆ ็ญพ",
+ "deleteConfirmationTitle": "ๆจ็กฎๅฎๅ๏ผ",
+ "deleteConfirmationOk": "ๆฏ",
+ "deleteConfirmationCancel": "ๅๆถ",
+ "associatedTaskColumn": "ๅ ณ่ไปปๅก่ฎกๆฐ",
+ "searchPlaceholder": "ๆๅ็งฐๆ็ดข",
+ "emptyText": "ๆ ็ญพๅฏไปฅๅจๆดๆฐๆๅๅปบไปปๅกๆถๅๅปบใ",
+ "pinTooltip": "็นๅปๅฐๅ ถๅบๅฎๅฐไธป่ๅ",
+ "colorChangeTooltip": "็นๅปๆดๆน้ข่ฒ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/settings/language.json b/worklenz-backend/src/public/locales/zh/settings/language.json
new file mode 100644
index 00000000..631eac11
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/settings/language.json
@@ -0,0 +1,7 @@
+{
+ "language": "่ฏญ่จ",
+ "language_required": "่ฏญ่จๆฏๅฟ ้็",
+ "time_zone": "ๆถๅบ",
+ "time_zone_required": "ๆถๅบๆฏๅฟ ้็",
+ "save_changes": "ไฟๅญๆดๆน"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/settings/notifications.json b/worklenz-backend/src/public/locales/zh/settings/notifications.json
new file mode 100644
index 00000000..f15784bf
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/settings/notifications.json
@@ -0,0 +1,11 @@
+{
+ "title": "้็ฅ่ฎพ็ฝฎ",
+ "emailTitle": "ๅๆๅ้็ตๅญ้ฎไปถ้็ฅ",
+ "emailDescription": "ๅ ๆฌๆฐ็ไปปๅกๅ้ ",
+ "dailyDigestTitle": "ๅๆๅ้ๆฏๆฅๆ่ฆ",
+ "dailyDigestDescription": "ๆฏๅคฉๆไธ๏ผๆจๅฐๆถๅฐไปปๅกไธญๆ่ฟๆดปๅจ็ๆ่ฆใ",
+ "popupTitle": "ๅฝWorklenzๆๅผๆถ๏ผๅจๆ็็ต่ไธๅผนๅบ้็ฅ",
+ "popupDescription": "ๅผนๅบ้็ฅๅฏ่ฝไผ่ขซๆจ็ๆต่งๅจ็ฆ็จใๆดๆนๆจ็ๆต่งๅจ่ฎพ็ฝฎไปฅๅ ่ฎธๅฎไปฌใ",
+ "unreadItemsTitle": "ๆพ็คบๆช่ฏป้กน็ฎ็ๆฐ้",
+ "unreadItemsDescription": "ๆจๅฐ็ๅฐๆฏไธช้็ฅ็่ฎกๆฐใ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/settings/profile.json b/worklenz-backend/src/public/locales/zh/settings/profile.json
new file mode 100644
index 00000000..cfafeb12
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/settings/profile.json
@@ -0,0 +1,14 @@
+{
+ "uploadError": "ๆจๅช่ฝไธไผ JPG/PNGๆไปถ๏ผ",
+ "uploadSizeError": "ๅพ็ๅฟ ้กปๅฐไบ2MB๏ผ",
+ "upload": "ไธไผ ",
+ "nameLabel": "ๅ็งฐ",
+ "nameRequiredError": "ๅ็งฐๆฏๅฟ ้็",
+ "emailLabel": "็ตๅญ้ฎไปถ",
+ "emailRequiredError": "็ตๅญ้ฎไปถๆฏๅฟ ้็",
+ "saveChanges": "ไฟๅญๆดๆน",
+ "profileJoinedText": "ไธไธชๆๅๅ ๅ ฅ",
+ "profileLastUpdatedText": "ไธไธชๆๅๆดๆฐ",
+ "avatarTooltip": "็นๅปไธไผ ๅคดๅ",
+ "title": "ไธชไบบ่ตๆ่ฎพ็ฝฎ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/settings/project-templates.json b/worklenz-backend/src/public/locales/zh/settings/project-templates.json
new file mode 100644
index 00000000..5dcc866c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/settings/project-templates.json
@@ -0,0 +1,8 @@
+{
+ "nameColumn": "ๅ็งฐ",
+ "editToolTip": "็ผ่พ",
+ "deleteToolTip": "ๅ ้ค",
+ "confirmText": "ๆจ็กฎๅฎๅ๏ผ",
+ "okText": "ๆฏ",
+ "cancelText": "ๅๆถ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/settings/sidebar.json b/worklenz-backend/src/public/locales/zh/settings/sidebar.json
new file mode 100644
index 00000000..b9f74709
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/settings/sidebar.json
@@ -0,0 +1,15 @@
+{
+ "profile": "ไธชไบบ่ตๆ",
+ "appearance": "ๅค่ง",
+ "notifications": "้็ฅ",
+ "clients": "ๅฎขๆท",
+ "job-titles": "่ไฝ",
+ "labels": "ๆ ็ญพ",
+ "categories": "็ฑปๅซ",
+ "project-templates": "้กน็ฎๆจกๆฟ",
+ "task-templates": "ไปปๅกๆจกๆฟ",
+ "team-members": "ๅข้ๆๅ",
+ "teams": "ๅข้",
+ "change-password": "ๆดๆนๅฏ็ ",
+ "language-and-region": "่ฏญ่จๅๅฐๅบ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/settings/task-templates.json b/worklenz-backend/src/public/locales/zh/settings/task-templates.json
new file mode 100644
index 00000000..3fd9124a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/settings/task-templates.json
@@ -0,0 +1,9 @@
+{
+ "nameColumn": "ๅ็งฐ",
+ "createdColumn": "ๅๅปบๆถ้ด",
+ "editToolTip": "็ผ่พ",
+ "deleteToolTip": "ๅ ้ค",
+ "confirmText": "ๆจ็กฎๅฎๅ๏ผ",
+ "okText": "ๆฏ",
+ "cancelText": "ๅๆถ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/settings/team-members.json b/worklenz-backend/src/public/locales/zh/settings/team-members.json
new file mode 100644
index 00000000..8b39483c
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/settings/team-members.json
@@ -0,0 +1,47 @@
+{
+ "title": "ๅข้ๆๅ",
+ "nameColumn": "ๅ็งฐ",
+ "projectsColumn": "้กน็ฎ",
+ "emailColumn": "็ตๅญ้ฎไปถ",
+ "teamAccessColumn": "ๅข้่ฎฟ้ฎ",
+ "memberCount": "ๆๅ",
+ "membersCountPlural": "ๆๅ",
+ "searchPlaceholder": "ๆๅ็งฐๆ็ดขๆๅ",
+ "pinTooltip": "ๅทๆฐๆๅๅ่กจ",
+ "addMemberButton": "ๆทปๅ ๆฐๆๅ",
+ "editTooltip": "็ผ่พๆๅ",
+ "deactivateTooltip": "ๅ็จๆๅ",
+ "activateTooltip": "ๆฟๆดปๆๅ",
+ "deleteTooltip": "ๅ ้คๆๅ",
+ "confirmDeleteTitle": "ๆจ็กฎๅฎ่ฆๅ ้คๆญคๆๅๅ๏ผ",
+ "confirmActivateTitle": "ๆจ็กฎๅฎ่ฆๆดๆนๆญคๆๅ็็ถๆๅ๏ผ",
+ "okText": "ๆฏ๏ผ็ปง็ปญ",
+ "cancelText": "ๅฆ๏ผๅๆถ",
+ "deactivatedText": "๏ผๅฝๅๅทฒๅ็จ๏ผ",
+ "pendingInvitationText": "๏ผ้่ฏทๅพ ๅค็๏ผ",
+ "addMemberDrawerTitle": "ๆทปๅ ๆฐๅข้ๆๅ",
+ "updateMemberDrawerTitle": "ๆดๆฐๅข้ๆๅ",
+ "addMemberEmailHint": "ๆ ่ฎบๆฏๅฆๆฅๅ้่ฏท๏ผๆๅ้ฝๅฐ่ขซๆทปๅ ๅฐๅข้ไธญ",
+ "memberEmailLabel": "็ตๅญ้ฎไปถ",
+ "memberEmailPlaceholder": "่พๅ ฅๅข้ๆๅ็็ตๅญ้ฎไปถๅฐๅ",
+ "memberEmailRequiredError": "่ฏท่พๅ ฅๆๆ็็ตๅญ้ฎไปถๅฐๅ",
+ "jobTitleLabel": "่ไฝ",
+ "jobTitlePlaceholder": "้ๆฉๆๆ็ดข่ไฝ๏ผๅฏ้๏ผ",
+ "memberAccessLabel": "่ฎฟ้ฎ็บงๅซ",
+ "addToTeamButton": "ๅฐๆๅๆทปๅ ๅฐๅข้",
+ "updateButton": "ไฟๅญๆดๆน",
+ "resendInvitationButton": "้ๆฐๅ้้่ฏท้ฎไปถ",
+ "invitationSentSuccessMessage": "ๅข้้่ฏทๅทฒๆๅๅ้๏ผ",
+ "createMemberSuccessMessage": "ๆฐๅข้ๆๅๅทฒๆๅๆทปๅ ๏ผ",
+ "createMemberErrorMessage": "ๆทปๅ ๅข้ๆๅๅคฑ่ดฅใ่ฏท้่ฏใ",
+ "updateMemberSuccessMessage": "ๅข้ๆๅๅทฒๆๅๆดๆฐ๏ผ",
+ "updateMemberErrorMessage": "ๆดๆฐๅข้ๆๅๅคฑ่ดฅใ่ฏท้่ฏใ",
+ "memberText": "ๆๅ",
+ "adminText": "็ฎก็ๅ",
+ "ownerText": "ๅข้ๆๆ่ ",
+ "addedText": "ๅทฒๆทปๅ ",
+ "updatedText": "ๅทฒๆดๆฐ",
+ "noResultFound": "่พๅ ฅ็ตๅญ้ฎไปถๅฐๅๅนถๆๅ่ฝฆ้ฎ...",
+ "jobTitlesFetchError": "่ทๅ่ไฝๅคฑ่ดฅ",
+ "invitationResent": "้่ฏท้ๆฐๅ้ๆๅ๏ผ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/settings/teams.json b/worklenz-backend/src/public/locales/zh/settings/teams.json
new file mode 100644
index 00000000..af2064ae
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/settings/teams.json
@@ -0,0 +1,16 @@
+{
+ "title": "ๅข้",
+ "team": "ๅข้",
+ "teams": "ๅข้",
+ "name": "ๅ็งฐ",
+ "created": "ๅๅปบๆถ้ด",
+ "ownsBy": "ๆๆ่ ",
+ "edit": "็ผ่พ",
+ "editTeam": "็ผ่พๅข้",
+ "pinTooltip": "็นๅปๅฐๆญค้กนๅบๅฎๅฐไธป่ๅ",
+ "editTeamName": "็ผ่พๅข้ๅ็งฐ",
+ "updateName": "ๆดๆฐๅ็งฐ",
+ "namePlaceholder": "ๅ็งฐ",
+ "nameRequired": "่ฏท่พๅ ฅๅ็งฐ",
+ "updateFailed": "ๅข้ๅ็งฐๆดๆนๅคฑ่ดฅ๏ผ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/task-drawer/task-drawer-info-tab.json b/worklenz-backend/src/public/locales/zh/task-drawer/task-drawer-info-tab.json
new file mode 100644
index 00000000..b0b36689
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/task-drawer/task-drawer-info-tab.json
@@ -0,0 +1,29 @@
+{
+ "details": {
+ "task-key": "ไปปๅกID",
+ "phase": "้ถๆฎต",
+ "assignees": "ๅๆไบบ",
+ "due-date": "ๆชๆญขๆฅๆ",
+ "time-estimation": "ไผฐ่ฎกๆถ้ด",
+ "priority": "ไผๅ ็บง",
+ "labels": "ๆ ็ญพ",
+ "billable": "ๅฏ่ฎก่ดน",
+ "notify": "้็ฅ",
+ "when-done-notify": "ๅฎๆๆถ้็ฅ",
+ "start-date": "ๅผๅงๆฅๆ",
+ "end-date": "็ปๆๆฅๆ",
+ "hide-start-date": "้่ๅผๅงๆฅๆ",
+ "show-start-date": "ๆพ็คบๅผๅงๆฅๆ",
+ "hours": "ๅฐๆถ",
+ "minutes": "ๅ้"
+ },
+ "description": {
+ "title": "ๆ่ฟฐ",
+ "placeholder": "ๆทปๅ ๆด่ฏฆ็ป็ๆ่ฟฐ..."
+ },
+ "subTasks": {
+ "title": "ๅญไปปๅก",
+ "add-sub-task": "+ ๆทปๅ ๅญไปปๅก",
+ "refresh-sub-tasks": "ๅทๆฐๅญไปปๅก"
+ }
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/task-drawer/task-drawer.json b/worklenz-backend/src/public/locales/zh/task-drawer/task-drawer.json
new file mode 100644
index 00000000..dfe304fe
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/task-drawer/task-drawer.json
@@ -0,0 +1,123 @@
+{
+ "taskHeader": {
+ "taskNamePlaceholder": "่พๅ ฅๆจ็ไปปๅก",
+ "deleteTask": "ๅ ้คไปปๅก"
+ },
+ "taskInfoTab": {
+ "title": "ไฟกๆฏ",
+ "details": {
+ "title": "่ฏฆๆ ",
+ "task-key": "ไปปๅก้ฎ",
+ "phase": "้ถๆฎต",
+ "assignees": "ๅ่ฎฉไบบ",
+ "due-date": "ๆชๆญขๆฅๆ",
+ "time-estimation": "ๆถ้ดไผฐ็ฎ",
+ "priority": "ไผๅ ็บง",
+ "labels": "ๆ ็ญพ",
+ "billable": "ๅฏ่ฎก่ดน",
+ "notify": "้็ฅ",
+ "when-done-notify": "ๅฎๆๆถ๏ผ้็ฅ",
+ "start-date": "ๅผๅงๆฅๆ",
+ "end-date": "็ปๆๆฅๆ",
+ "hide-start-date": "้่ๅผๅงๆฅๆ",
+ "show-start-date": "ๆพ็คบๅผๅงๆฅๆ",
+ "hours": "ๅฐๆถ",
+ "minutes": "ๅ้",
+ "progressValue": "่ฟๅบฆๅผ",
+ "progressValueTooltip": "่ฎพ็ฝฎ่ฟๅบฆ็พๅๆฏ๏ผ0-100%๏ผ",
+ "progressValueRequired": "่ฏท่พๅ ฅ่ฟๅบฆๅผ",
+ "progressValueRange": "่ฟๅบฆๅฟ ้กปๅจ0ๅฐ100ไน้ด",
+ "taskWeight": "ไปปๅกๆ้",
+ "taskWeightTooltip": "่ฎพ็ฝฎๆญคๅญไปปๅก็ๆ้๏ผ็พๅๆฏ๏ผ",
+ "taskWeightRequired": "่ฏท่พๅ ฅไปปๅกๆ้",
+ "taskWeightRange": "ๆ้ๅฟ ้กปๅจ0ๅฐ100ไน้ด",
+ "recurring": "้ๅค"
+ },
+ "labels": {
+ "labelInputPlaceholder": "ๆ็ดขๆๅๅปบ",
+ "labelsSelectorInputTip": "ๆๅ่ฝฆๅๅปบ"
+ },
+ "description": {
+ "title": "ๆ่ฟฐ",
+ "placeholder": "ๆทปๅ ๆด่ฏฆ็ป็ๆ่ฟฐ..."
+ },
+ "subTasks": {
+ "title": "ๅญไปปๅก",
+ "addSubTask": "ๆทปๅ ๅญไปปๅก",
+ "addSubTaskInputPlaceholder": "่พๅ ฅๆจ็ไปปๅกๅนถๆๅ่ฝฆ",
+ "refreshSubTasks": "ๅทๆฐๅญไปปๅก",
+ "edit": "็ผ่พ",
+ "delete": "ๅ ้ค",
+ "confirmDeleteSubTask": "ๆจ็กฎๅฎ่ฆๅ ้คๆญคๅญไปปๅกๅ๏ผ",
+ "deleteSubTask": "ๅ ้คๅญไปปๅก"
+ },
+ "dependencies": {
+ "title": "ไพ่ตๅ ณ็ณป",
+ "addDependency": "+ ๆทปๅ ๆฐไพ่ต",
+ "blockedBy": "่ขซ้ปๆญข",
+ "searchTask": "่พๅ ฅๆ็ดขไปปๅก",
+ "noTasksFound": "ๆชๆพๅฐไปปๅก",
+ "confirmDeleteDependency": "ๆจ็กฎๅฎ่ฆๅ ้คๅ๏ผ"
+ },
+ "attachments": {
+ "title": "้ไปถ",
+ "chooseOrDropFileToUpload": "้ๆฉๆๆๆพๆไปถไธไผ ",
+ "uploading": "ไธไผ ไธญ..."
+ },
+ "comments": {
+ "title": "่ฏ่ฎบ",
+ "addComment": "+ ๆทปๅ ๆฐ่ฏ่ฎบ",
+ "noComments": "่ฟๆฒกๆ่ฏ่ฎบใๆไธบ็ฌฌไธไธช่ฏ่ฎบ็ไบบ๏ผ",
+ "delete": "ๅ ้ค",
+ "confirmDeleteComment": "ๆจ็กฎๅฎ่ฆๅ ้คๆญค่ฏ่ฎบๅ๏ผ",
+ "addCommentPlaceholder": "ๆทปๅ ่ฏ่ฎบ...",
+ "cancel": "ๅๆถ",
+ "commentButton": "่ฏ่ฎบ",
+ "attachFiles": "้ๅ ๆไปถ",
+ "addMoreFiles": "ๆทปๅ ๆดๅคๆไปถ",
+ "selectedFiles": "ๅทฒ้ๆฉ็ๆไปถ๏ผๆๅค25MB๏ผๆๅคง{count}ไธช๏ผ",
+ "maxFilesError": "ๆจๆๅคๅช่ฝไธไผ {count}ไธชๆไปถ",
+ "processFilesError": "ๅค็ๆไปถๅคฑ่ดฅ",
+ "addCommentError": "่ฏทๆทปๅ ่ฏ่ฎบๆ้ๅ ๆไปถ",
+ "createdBy": "{{time}}็ฑ{{user}}ๅๅปบ",
+ "updatedTime": "ๆดๆฐไบ{{time}}"
+ },
+ "searchInputPlaceholder": "ๆๅ็งฐๆ็ดข",
+ "pendingInvitation": "ๅพ ๅค็้่ฏท"
+ },
+ "taskTimeLogTab": {
+ "title": "ๆถ้ดๆฅๅฟ",
+ "addTimeLog": "ๆทปๅ ๆฐๆถ้ดๆฅๅฟ",
+ "totalLogged": "ๆป่ฎฐๅฝๆถ้ด",
+ "exportToExcel": "ๅฏผๅบๅฐExcel",
+ "noTimeLogsFound": "ๆชๆพๅฐๆถ้ดๆฅๅฟ",
+ "timeLogForm": {
+ "date": "ๆฅๆ",
+ "startTime": "ๅผๅงๆถ้ด",
+ "endTime": "็ปๆๆถ้ด",
+ "workDescription": "ๅทฅไฝๆ่ฟฐ",
+ "descriptionPlaceholder": "ๆทปๅ ๆ่ฟฐ",
+ "logTime": "่ฎฐๅฝๆถ้ด",
+ "updateTime": "ๆดๆฐๆถ้ด",
+ "cancel": "ๅๆถ",
+ "selectDateError": "่ฏท้ๆฉๆฅๆ",
+ "selectStartTimeError": "่ฏท้ๆฉๅผๅงๆถ้ด",
+ "selectEndTimeError": "่ฏท้ๆฉ็ปๆๆถ้ด",
+ "endTimeAfterStartError": "็ปๆๆถ้ดๅฟ ้กปๅจๅผๅงๆถ้ดไนๅ"
+ }
+ },
+ "taskActivityLogTab": {
+ "title": "ๆดปๅจๆฅๅฟ",
+ "add": "ๆทปๅ ",
+ "remove": "็งป้ค",
+ "none": "ๆ ",
+ "weight": "ๆ้",
+ "createdTask": "ๅๅปบไบไปปๅกใ"
+ },
+ "taskProgress": {
+ "markAsDoneTitle": "ๅฐไปปๅกๆ ่ฎฐไธบๅฎๆ๏ผ",
+ "confirmMarkAsDone": "ๆฏ็๏ผๆ ่ฎฐไธบๅฎๆ",
+ "cancelMarkAsDone": "ไธ๏ผไฟๆๅฝๅ็ถๆ",
+ "markAsDoneDescription": "ๆจๅทฒๅฐ่ฟๅบฆ่ฎพ็ฝฎไธบ100%ใๆจๆณๅฐไปปๅก็ถๆๆดๆฐไธบ\"ๅฎๆ\"ๅ๏ผ"
+ }
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/task-list-filters.json b/worklenz-backend/src/public/locales/zh/task-list-filters.json
new file mode 100644
index 00000000..84387509
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/task-list-filters.json
@@ -0,0 +1,79 @@
+{
+ "searchButton": "ๆ็ดข",
+ "resetButton": "้็ฝฎ",
+ "searchInputPlaceholder": "ๆๅ็งฐๆ็ดข",
+ "sortText": "ๆๅบ",
+ "statusText": "็ถๆ",
+ "phaseText": "้ถๆฎต",
+ "memberText": "ๆๅ",
+ "assigneesText": "ๅๆไบบ",
+ "priorityText": "ไผๅ ็บง",
+ "labelsText": "ๆ ็ญพ",
+ "membersText": "ๆๅ",
+ "groupByText": "ๅ็ปไพๆฎ",
+ "showArchivedText": "ๆพ็คบๅทฒๅฝๆกฃ็ไปปๅก",
+ "showFieldsText": "ๆพ็คบๅญๆฎต",
+ "keyText": "ID",
+ "taskText": "ไปปๅก",
+ "descriptionText": "ๆ่ฟฐ",
+ "phasesText": "้ถๆฎต",
+ "listText": "ๅ่กจ",
+ "progressText": "่ฟๅบฆ",
+ "timeTrackingText": "ๆถ้ด่ท่ธช",
+ "timetrackingText": "ๆถ้ด่ท่ธช",
+ "estimationText": "ไผฐ่ฎก",
+ "startDateText": "ๅผๅงๆฅๆ",
+ "startdateText": "ๅผๅงๆฅๆ",
+ "endDateText": "็ปๆๆฅๆ",
+ "dueDateText": "ๆชๆญขๆฅๆ",
+ "duedateText": "ๆชๆญขๆฅๆ",
+ "completedDateText": "ๅฎๆๆฅๆ",
+ "completeddateText": "ๅฎๆๆฅๆ",
+ "createdDateText": "ๅๅปบๆฅๆ",
+ "createddateText": "ๅๅปบๆฅๆ",
+ "lastUpdatedText": "ๆๅๆดๆฐ",
+ "lastupdatedText": "ๆๅๆดๆฐ",
+ "reporterText": "ๆฅๅไบบ",
+ "dueTimeText": "ๆชๆญขๆถ้ด",
+ "duetimeText": "ๆชๆญขๆถ้ด",
+ "lowText": "ไฝ",
+ "mediumText": "ไธญ",
+ "highText": "้ซ",
+ "createStatusButtonTooltip": "็ถๆ่ฎพ็ฝฎ",
+ "configPhaseButtonTooltip": "้ถๆฎต่ฎพ็ฝฎ",
+ "noLabelsFound": "ๆชๆพๅฐๆ ็ญพ",
+ "addStatusButton": "ๆทปๅ ็ถๆ",
+ "addPhaseButton": "ๆทปๅ ้ถๆฎต",
+ "createStatus": "ๅๅปบ็ถๆ",
+ "name": "ๅ็งฐ",
+ "category": "็ฑปๅซ",
+ "selectCategory": "้ๆฉ็ฑปๅซ",
+ "pleaseEnterAName": "่ฏท่พๅ ฅๅ็งฐ",
+ "pleaseSelectACategory": "่ฏท้ๆฉ็ฑปๅซ",
+ "create": "ๅๅปบ",
+ "searchTasks": "ๆ็ดขไปปๅก...",
+ "searchPlaceholder": "ๆ็ดข...",
+ "fieldsText": "ๅญๆฎต",
+ "loadingFilters": "ๅ ่ฝฝ็ญ้ๅจ...",
+ "noOptionsFound": "ๆชๆพๅฐ้้กน",
+ "filtersActive": "ไธช็ญ้ๅจๅทฒๆฟๆดป",
+ "filterActive": "ไธช็ญ้ๅจๅทฒๆฟๆดป",
+ "clearAll": "ๆธ ้คๅ จ้จ",
+ "clearing": "ๆธ ้คไธญ...",
+ "cancel": "ๅๆถ",
+ "search": "ๆ็ดข",
+ "groupedBy": "ๅ็ปไพๆฎ",
+ "manageStatuses": "็ฎก็็ถๆ",
+ "managePhases": "็ฎก็้ถๆฎต",
+ "dragToReorderStatuses": "ๆๆฝ็ถๆไปฅ้ๆฐๆๅบใๆฏไธช็ถๆๅฏไปฅๆไธๅ็็ฑปๅซใ",
+ "enterNewStatusName": "่พๅ ฅๆฐ็ถๆๅ็งฐ...",
+ "addStatus": "ๆทปๅ ็ถๆ",
+ "noStatusesFound": "ๆชๆพๅฐ็ถๆใ่ฏทๅจไธ้ขๅๅปบๆจ็็ฌฌไธไธช็ถๆใ",
+ "deleteStatus": "ๅ ้ค็ถๆ",
+ "deleteStatusConfirm": "ๆจ็กฎๅฎ่ฆๅ ้คๆญค็ถๆๅ๏ผๆญคๆไฝๆ ๆณๆค้ใ",
+ "rename": "้ๅฝๅ",
+ "delete": "ๅ ้ค",
+ "enterStatusName": "่พๅ ฅ็ถๆๅ็งฐ",
+ "selectCategory": "้ๆฉ็ฑปๅซ",
+ "close": "ๅ ณ้ญ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/task-list-table.json b/worklenz-backend/src/public/locales/zh/task-list-table.json
new file mode 100644
index 00000000..f3ec040f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/task-list-table.json
@@ -0,0 +1,129 @@
+{
+ "keyColumn": "ID",
+ "taskColumn": "ไปปๅก",
+ "descriptionColumn": "ๆ่ฟฐ",
+ "progressColumn": "่ฟๅบฆ",
+ "membersColumn": "ๆๅ",
+ "assigneesColumn": "ๅๆไบบ",
+ "labelsColumn": "ๆ ็ญพ",
+ "phasesColumn": "้ถๆฎต",
+ "phaseColumn": "้ถๆฎต",
+ "statusColumn": "็ถๆ",
+ "priorityColumn": "ไผๅ ็บง",
+ "timeTrackingColumn": "ๆถ้ด่ฟฝ่ธช",
+ "timetrackingColumn": "ๆถ้ด่ฟฝ่ธช",
+ "estimationColumn": "ไผฐ็ฎ",
+ "startDateColumn": "ๅผๅงๆฅๆ",
+ "startdateColumn": "ๅผๅงๆฅๆ",
+ "dueDateColumn": "ๆชๆญขๆฅๆ",
+ "duedateColumn": "ๆชๆญขๆฅๆ",
+ "completedDateColumn": "ๅฎๆๆฅๆ",
+ "completeddateColumn": "ๅฎๆๆฅๆ",
+ "createdDateColumn": "ๅๅปบๆฅๆ",
+ "createddateColumn": "ๅๅปบๆฅๆ",
+ "lastUpdatedColumn": "ๆๅๆดๆฐ",
+ "lastupdatedColumn": "ๆๅๆดๆฐ",
+ "reporterColumn": "ๆฅๅไบบ",
+ "dueTimeColumn": "ๆชๆญขๆถ้ด",
+ "todoSelectorText": "ๅพ ๅ",
+ "doingSelectorText": "่ฟ่กไธญ",
+ "doneSelectorText": "ๅทฒๅฎๆ",
+ "lowSelectorText": "ไฝ",
+ "mediumSelectorText": "ไธญ",
+ "highSelectorText": "้ซ",
+ "selectText": "้ๆฉ",
+ "labelsSelectorInputTip": "ๆๅ่ฝฆ้ฎๅๅปบ๏ผ",
+ "addTaskText": "+ ๆทปๅ ไปปๅก",
+ "addSubTaskText": "+ ๆทปๅ ๅญไปปๅก",
+ "addTaskInputPlaceholder": "่พๅ ฅไปปๅกๅนถๆๅ่ฝฆ้ฎ",
+ "noTasksInGroup": "ๆญค็ปไธญๆฒกๆไปปๅก",
+ "openButton": "ๆๅผ",
+ "okButton": "็กฎๅฎ",
+ "noLabelsFound": "ๆชๆพๅฐๆ ็ญพ",
+ "searchInputPlaceholder": "ๆ็ดขๆๅๅปบ",
+ "assigneeSelectorInviteButton": "้่ฟ็ตๅญ้ฎไปถ้่ฏทๆฐๆๅ",
+ "labelInputPlaceholder": "ๆ็ดขๆๅๅปบ",
+ "searchLabelsPlaceholder": "ๆ็ดขๆ ็ญพ...",
+ "createLabelButton": "ๅๅปบ \"{{name}}\"",
+ "manageLabelsPath": "่ฎพ็ฝฎ โ ๆ ็ญพ",
+ "pendingInvitation": "ๅพ ๅค็้่ฏท",
+ "contextMenu": {
+ "assignToMe": "ๅ้ ็ปๆ",
+ "moveTo": "็งปๅจๅฐ",
+ "unarchive": "ๅๆถๅฝๆกฃ",
+ "archive": "ๅฝๆกฃ",
+ "convertToSubTask": "่ฝฌๆขไธบๅญไปปๅก",
+ "convertToTask": "่ฝฌๆขไธบไปปๅก",
+ "delete": "ๅ ้ค",
+ "searchByNameInputPlaceholder": "ๆๅ็งฐๆ็ดข"
+ },
+ "setDueDate": "่ฎพ็ฝฎๆชๆญขๆฅๆ",
+ "setStartDate": "่ฎพ็ฝฎๅผๅงๆฅๆ",
+ "clearDueDate": "ๆธ ้คๆชๆญขๆฅๆ",
+ "clearStartDate": "ๆธ ้คๅผๅงๆฅๆ",
+ "dueDatePlaceholder": "ๆชๆญขๆฅๆ",
+ "startDatePlaceholder": "ๅผๅงๆฅๆ",
+
+ "emptyStates": {
+ "noTaskGroups": "ๆชๆพๅฐไปปๅก็ป",
+ "noTaskGroupsDescription": "ๅๅปบไปปๅกๆๅบ็จ็ญ้ๅจๅ๏ผไปปๅกๅฐๆพ็คบๅจๆญคๅคใ",
+ "errorPrefix": "้่ฏฏ๏ผ",
+ "dragTaskFallback": "ไปปๅก"
+ },
+
+ "customColumns": {
+ "addCustomColumn": "ๆทปๅ ่ชๅฎไนๅ",
+ "customColumnHeader": "่ชๅฎไนๅ",
+ "customColumnSettings": "่ชๅฎไนๅ่ฎพ็ฝฎ",
+ "noCustomValue": "ๆ ๅผ",
+ "peopleField": "ไบบๅๅญๆฎต",
+ "noDate": "ๆ ๆฅๆ",
+ "unsupportedField": "ไธๆฏๆ็ๅญๆฎต็ฑปๅ",
+
+ "modal": {
+ "addFieldTitle": "ๆทปๅ ๅญๆฎต",
+ "editFieldTitle": "็ผ่พๅญๆฎต",
+ "fieldTitle": "ๅญๆฎตๆ ้ข",
+ "fieldTitleRequired": "ๅญๆฎตๆ ้ขไธบๅฟ ๅกซ้กน",
+ "columnTitlePlaceholder": "ๅๆ ้ข",
+ "type": "็ฑปๅ",
+ "deleteConfirmTitle": "็กฎๅฎ่ฆๅ ้คๆญค่ชๅฎไนๅๅ๏ผ",
+ "deleteConfirmDescription": "ๆญคๆไฝๆ ๆณๆค้ใไธๆญคๅๅ ณ่็ๆๆๆฐๆฎๅฐ่ขซๆฐธไน ๅ ้คใ",
+ "deleteButton": "ๅ ้ค",
+ "cancelButton": "ๅๆถ",
+ "createButton": "ๅๅปบ",
+ "updateButton": "ๆดๆฐ",
+ "createSuccessMessage": "่ชๅฎไนๅๅๅปบๆๅ",
+ "updateSuccessMessage": "่ชๅฎไนๅๆดๆฐๆๅ",
+ "deleteSuccessMessage": "่ชๅฎไนๅๅ ้คๆๅ",
+ "deleteErrorMessage": "ๅ ้ค่ชๅฎไนๅๅคฑ่ดฅ",
+ "createErrorMessage": "ๅๅปบ่ชๅฎไนๅๅคฑ่ดฅ",
+ "updateErrorMessage": "ๆดๆฐ่ชๅฎไนๅๅคฑ่ดฅ"
+ },
+
+ "fieldTypes": {
+ "people": "ไบบๅ",
+ "number": "ๆฐๅญ",
+ "date": "ๆฅๆ",
+ "selection": "้ๆฉ",
+ "checkbox": "ๅค้ๆก",
+ "labels": "ๆ ็ญพ",
+ "key": "้ฎ",
+ "formula": "ๅ ฌๅผ"
+ }
+ },
+
+ "indicators": {
+ "tooltips": {
+ "subtasks": "{{count}} ไธชๅญไปปๅก",
+ "subtasks_plural": "{{count}} ไธชๅญไปปๅก",
+ "comments": "{{count}} ๆก่ฏ่ฎบ",
+ "comments_plural": "{{count}} ๆก่ฏ่ฎบ",
+ "attachments": "{{count}} ไธช้ไปถ",
+ "attachments_plural": "{{count}} ไธช้ไปถ",
+ "subscribers": "ไปปๅกๆ่ฎข้ ่ ",
+ "dependencies": "ไปปๅกๆไพ่ต้กน",
+ "recurring": "้ๅคไปปๅก"
+ }
+ }
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/task-management.json b/worklenz-backend/src/public/locales/zh/task-management.json
new file mode 100644
index 00000000..341ecc64
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/task-management.json
@@ -0,0 +1,35 @@
+{
+ "noTasksInGroup": "ๆญค็ปไธญๆฒกๆไปปๅก",
+ "noTasksInGroupDescription": "ๆทปๅ ไปปๅกๅผๅงไฝฟ็จ",
+ "addFirstTask": "ๆทปๅ ไฝ ็็ฌฌไธไธชไปปๅก",
+ "openTask": "ๆๅผ",
+ "subtask": "ๅญไปปๅก",
+ "subtasks": "ๅญไปปๅก",
+ "comment": "่ฏ่ฎบ",
+ "comments": "่ฏ่ฎบ",
+ "attachment": "้ไปถ",
+ "attachments": "้ไปถ",
+ "enterSubtaskName": "่พๅ ฅๅญไปปๅกๅ็งฐ...",
+ "add": "ๆทปๅ ",
+ "cancel": "ๅๆถ",
+ "renameGroup": "้ๅฝๅ็ป",
+ "renameStatus": "้ๅฝๅ็ถๆ",
+ "renamePhase": "้ๅฝๅ้ถๆฎต",
+ "changeCategory": "ๆดๆน็ฑปๅซ",
+ "clickToEditGroupName": "็นๅป็ผ่พ็ปๅ็งฐ",
+ "enterGroupName": "่พๅ ฅ็ปๅ็งฐ",
+
+ "indicators": {
+ "tooltips": {
+ "subtasks": "{{count}} ไธชๅญไปปๅก",
+ "subtasks_plural": "{{count}} ไธชๅญไปปๅก",
+ "comments": "{{count}} ๆก่ฏ่ฎบ",
+ "comments_plural": "{{count}} ๆก่ฏ่ฎบ",
+ "attachments": "{{count}} ไธช้ไปถ",
+ "attachments_plural": "{{count}} ไธช้ไปถ",
+ "subscribers": "ไปปๅกๆ่ฎข้ ่ ",
+ "dependencies": "ไปปๅกๆไพ่ต้กน",
+ "recurring": "้ๅคไปปๅก"
+ }
+ }
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/task-template-drawer.json b/worklenz-backend/src/public/locales/zh/task-template-drawer.json
new file mode 100644
index 00000000..53e99119
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/task-template-drawer.json
@@ -0,0 +1,11 @@
+{
+ "createTaskTemplate": "ๅๅปบไปปๅกๆจกๆฟ",
+ "editTaskTemplate": "็ผ่พไปปๅกๆจกๆฟ",
+ "cancelText": "ๅๆถ",
+ "saveText": "ไฟๅญ",
+ "templateNameText": "ๆจกๆฟๅ็งฐ",
+ "selectedTasks": "ๅทฒ้ไปปๅก",
+ "removeTask": "็งป้ค",
+ "cancelButton": "ๅๆถ",
+ "saveButton": "ไฟๅญ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/tasks/task-table-bulk-actions.json b/worklenz-backend/src/public/locales/zh/tasks/task-table-bulk-actions.json
new file mode 100644
index 00000000..2a4c89d6
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/tasks/task-table-bulk-actions.json
@@ -0,0 +1,24 @@
+{
+ "taskSelected": "ไปปๅกๅทฒ้ๆฉ",
+ "tasksSelected": "ไปปๅกๅทฒ้ๆฉ",
+ "changeStatus": "ๆดๆน็ถๆ/ไผๅ ็บง/้ถๆฎต",
+ "changeLabel": "ๆดๆนๆ ็ญพ",
+ "assignToMe": "ๅ้ ็ปๆ",
+ "changeAssignees": "ๆดๆนๅๆไบบ",
+ "archive": "ๅฝๆกฃ",
+ "unarchive": "ๅๆถๅฝๆกฃ",
+ "delete": "ๅ ้ค",
+ "moreOptions": "ๆดๅค้้กน",
+ "deselectAll": "ๅๆถๅ จ้",
+ "status": "็ถๆ",
+ "priority": "ไผๅ ็บง",
+ "phase": "้ถๆฎต",
+ "member": "ๆๅ",
+ "createTaskTemplate": "ๅๅปบไปปๅกๆจกๆฟ",
+ "apply": "ๅบ็จ",
+ "createLabel": "+ ๅๅปบๆ ็ญพ",
+ "hitEnterToCreate": "ๆๅ่ฝฆ้ฎๅๅปบ",
+ "pendingInvitation": "ๅพ ๅค็้่ฏท",
+ "noMatchingLabels": "ๆฒกๆๅน้ ็ๆ ็ญพ",
+ "noLabels": "ๆฒกๆๆ ็ญพ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/template-drawer.json b/worklenz-backend/src/public/locales/zh/template-drawer.json
new file mode 100644
index 00000000..64fd242f
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/template-drawer.json
@@ -0,0 +1,19 @@
+{
+ "title": "็ผ่พไปปๅกๆจกๆฟ",
+ "cancelText": "ๅๆถ",
+ "saveText": "ไฟๅญ",
+ "templateNameText": "ๆจกๆฟๅ็งฐ",
+ "selectedTasks": "ๅทฒ้ไปปๅก",
+ "removeTask": "็งป้ค",
+ "description": "ๆ่ฟฐ",
+ "phase": "้ถๆฎต",
+ "statuses": "็ถๆ",
+ "priorities": "ไผๅ ็บง",
+ "labels": "ๆ ็ญพ",
+ "tasks": "ไปปๅก",
+ "noTemplateSelected": "ๆช้ๆฉๆจกๆฟ",
+ "noDescription": "ๆ ๆ่ฟฐ",
+ "worklenzTemplates": "Worklenzๆจกๆฟ",
+ "yourTemplatesLibrary": "ๆจ็ๆจกๆฟๅบ",
+ "searchTemplates": "ๆ็ดขๆจกๆฟ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/templateDrawer.json b/worklenz-backend/src/public/locales/zh/templateDrawer.json
new file mode 100644
index 00000000..8405f8ab
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/templateDrawer.json
@@ -0,0 +1,23 @@
+{
+ "bugTracking": "้่ฏฏ่ท่ธช",
+ "construction": "ๅปบ็ญไธๆฝๅทฅ",
+ "designCreative": "่ฎพ่ฎกไธๅๆ",
+ "education": "ๆ่ฒ",
+ "finance": "้่",
+ "hrRecruiting": "ไบบๅ่ตๆบไธๆ่",
+ "informationTechnology": "ไฟกๆฏๆๆฏ",
+ "legal": "ๆณๅพ",
+ "manufacturing": "ๅถ้ ไธ",
+ "marketing": "ๅธๅบ่ฅ้",
+ "nonprofit": "้่ฅๅฉ",
+ "personalUse": "ไธชไบบไฝฟ็จ",
+ "salesCRM": "้ๅฎไธๅฎขๆทๅ ณ็ณป็ฎก็",
+ "serviceConsulting": "ๆๅกไธๅจ่ฏข",
+ "softwareDevelopment": "่ฝฏไปถๅผๅ",
+ "description": "ๆ่ฟฐ",
+ "phase": "้ถๆฎต",
+ "statuses": "็ถๆ",
+ "priorities": "ไผๅ ็บง",
+ "labels": "ๆ ็ญพ",
+ "tasks": "ไปปๅก"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/time-report.json b/worklenz-backend/src/public/locales/zh/time-report.json
new file mode 100644
index 00000000..c376954a
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/time-report.json
@@ -0,0 +1,33 @@
+{
+ "includeArchivedProjects": "ๅ ๅซๅทฒๅฝๆกฃ้กน็ฎ",
+ "export": "ๅฏผๅบ",
+ "timeSheet": "ๆถ้ด่กจ",
+ "searchByName": "ๆๅ็งฐๆ็ดข",
+ "selectAll": "ๅ จ้",
+ "teams": "ๅข้",
+ "searchByProject": "ๆ้กน็ฎๅ็งฐๆ็ดข",
+ "projects": "้กน็ฎ",
+ "searchByCategory": "ๆ็ฑปๅซๅ็งฐๆ็ดข",
+ "categories": "็ฑปๅซ",
+ "billable": "ๅฏ่ฎก่ดน",
+ "nonBillable": "ไธๅฏ่ฎก่ดน",
+ "total": "ๆป่ฎก",
+ "projectsTimeSheet": "้กน็ฎๆถ้ด่กจ",
+ "loggedTime": "ๅทฒ่ฎฐๅฝๆถ้ด๏ผๅฐๆถ๏ผ",
+ "exportToExcel": "ๅฏผๅบๅฐExcel",
+ "logged": "ๅทฒ่ฎฐๅฝ",
+ "for": "ไธบ",
+ "membersTimeSheet": "ๆๅๆถ้ด่กจ",
+ "member": "ๆๅ",
+ "estimatedVsActual": "้ข่ฎก็จๆถ vs ๅฎ้ ็จๆถ",
+ "workingDays": "ๅทฅไฝๆฅ",
+ "manDays": "ไบบๅคฉ",
+ "days": "ๅคฉ",
+ "estimatedDays": "้ข่ฎกๅคฉๆฐ",
+ "actualDays": "ๅฎ้ ๅคฉๆฐ",
+ "noCategories": "ๆชๆพๅฐ็ฑปๅซ",
+ "noCategory": "ๆ ็ฑปๅซ",
+ "noProjects": "ๆชๆพๅฐ้กน็ฎ",
+ "noTeams": "ๆชๆพๅฐๅข้",
+ "noData": "ๆชๆพๅฐๆฐๆฎ"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/locales/zh/unauthorized.json b/worklenz-backend/src/public/locales/zh/unauthorized.json
new file mode 100644
index 00000000..985b1d08
--- /dev/null
+++ b/worklenz-backend/src/public/locales/zh/unauthorized.json
@@ -0,0 +1,5 @@
+{
+ "title": "ๆชๆๆ๏ผ",
+ "subtitle": "ๆจๆ ๆ่ฎฟ้ฎๆญค้กต้ข",
+ "button": "่ฟๅ้ฆ้กต"
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/public/tinymce/package-lock.json b/worklenz-backend/src/public/tinymce/package-lock.json
new file mode 100644
index 00000000..686dcc86
--- /dev/null
+++ b/worklenz-backend/src/public/tinymce/package-lock.json
@@ -0,0 +1,20 @@
+{
+ "name": "tinymce",
+ "version": "6.8.4",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "tinymce",
+ "version": "6.8.4",
+ "license": "MIT",
+ "dependencies": {
+ "tinymce": "file:"
+ }
+ },
+ "node_modules/tinymce": {
+ "resolved": "",
+ "link": true
+ }
+ }
+}
diff --git a/worklenz-backend/src/public/tinymce/package.json b/worklenz-backend/src/public/tinymce/package.json
index 151b0166..39711f51 100644
--- a/worklenz-backend/src/public/tinymce/package.json
+++ b/worklenz-backend/src/public/tinymce/package.json
@@ -28,5 +28,8 @@
"homepage": "https://www.tiny.cloud/",
"bugs": {
"url": "https://github.com/tinymce/tinymce/issues"
+ },
+ "dependencies": {
+ "tinymce": "file:"
}
-}
\ No newline at end of file
+}
diff --git a/worklenz-backend/src/routes/apis/projects-api-router.ts b/worklenz-backend/src/routes/apis/projects-api-router.ts
index 6718b370..56fd2654 100644
--- a/worklenz-backend/src/routes/apis/projects-api-router.ts
+++ b/worklenz-backend/src/routes/apis/projects-api-router.ts
@@ -18,6 +18,7 @@ projectsApiRouter.get("/update-exist-sort-order", safeControllerFunction(Project
projectsApiRouter.post("/", teamOwnerOrAdminValidator, projectsBodyValidator, safeControllerFunction(ProjectsController.create));
projectsApiRouter.get("/", safeControllerFunction(ProjectsController.get));
+projectsApiRouter.get("/grouped", safeControllerFunction(ProjectsController.getGrouped));
projectsApiRouter.get("/my-task-projects", safeControllerFunction(ProjectsController.getMyProjectsToTasks));
projectsApiRouter.get("/my-projects", safeControllerFunction(ProjectsController.getMyProjects));
projectsApiRouter.get("/all", safeControllerFunction(ProjectsController.getAllProjects));
diff --git a/worklenz-backend/src/routes/apis/statuses-api-router.ts b/worklenz-backend/src/routes/apis/statuses-api-router.ts
index f9f6f560..07b00f26 100644
--- a/worklenz-backend/src/routes/apis/statuses-api-router.ts
+++ b/worklenz-backend/src/routes/apis/statuses-api-router.ts
@@ -18,6 +18,7 @@ statusesApiRouter.put("/order", statusOrderValidator, safeControllerFunction(Tas
statusesApiRouter.get("/categories", safeControllerFunction(TaskStatusesController.getCategories));
statusesApiRouter.get("/:id", idParamValidator, safeControllerFunction(TaskStatusesController.getById));
statusesApiRouter.put("/name/:id", projectManagerValidator, idParamValidator, taskStatusBodyValidator, safeControllerFunction(TaskStatusesController.updateName));
+statusesApiRouter.put("/category/:id", projectManagerValidator, idParamValidator, safeControllerFunction(TaskStatusesController.updateCategory));
statusesApiRouter.put("/:id", projectManagerValidator, idParamValidator, taskStatusBodyValidator, safeControllerFunction(TaskStatusesController.update));
statusesApiRouter.delete("/:id", projectManagerValidator, idParamValidator, statusDeleteValidator, safeControllerFunction(TaskStatusesController.deleteById));
diff --git a/worklenz-backend/src/routes/apis/tasks-api-router.ts b/worklenz-backend/src/routes/apis/tasks-api-router.ts
index bb6af547..6a192abe 100644
--- a/worklenz-backend/src/routes/apis/tasks-api-router.ts
+++ b/worklenz-backend/src/routes/apis/tasks-api-router.ts
@@ -42,6 +42,9 @@ tasksApiRouter.get("/list/columns/:id", idParamValidator, safeControllerFunction
tasksApiRouter.put("/list/columns/:id", idParamValidator, safeControllerFunction(TaskListColumnsController.toggleColumn));
tasksApiRouter.get("/list/v2/:id", idParamValidator, safeControllerFunction(getList));
+tasksApiRouter.get("/list/v3/:id", idParamValidator, safeControllerFunction(TasksControllerV2.getTasksV3));
+tasksApiRouter.post("/refresh-progress/:id", idParamValidator, safeControllerFunction(TasksControllerV2.refreshTaskProgress));
+tasksApiRouter.get("/progress-status/:id", idParamValidator, safeControllerFunction(TasksControllerV2.getTaskProgressStatus));
tasksApiRouter.get("/assignees/:id", idParamValidator, safeControllerFunction(TasksController.getProjectTaskAssignees));
tasksApiRouter.put("/bulk/status", mapTasksToBulkUpdate, bulkTasksStatusValidator, safeControllerFunction(TasksController.bulkChangeStatus));
diff --git a/worklenz-backend/src/services/activity-logs/activity-logs.service.ts b/worklenz-backend/src/services/activity-logs/activity-logs.service.ts
index 85d20977..cf049f7e 100644
--- a/worklenz-backend/src/services/activity-logs/activity-logs.service.ts
+++ b/worklenz-backend/src/services/activity-logs/activity-logs.service.ts
@@ -204,3 +204,29 @@ export async function logPhaseChange(activityLog: IActivityLog) {
insertToActivityLogs(activityLog);
}
}
+
+export async function logProgressChange(activityLog: IActivityLog) {
+ const { task_id, new_value, old_value } = activityLog;
+ if (!task_id || !activityLog.socket) return;
+
+ if (old_value !== new_value) {
+ activityLog.user_id = getLoggedInUserIdFromSocket(activityLog.socket);
+ activityLog.attribute_type = IActivityLogAttributeTypes.PROGRESS;
+ activityLog.log_type = IActivityLogChangeType.UPDATE;
+
+ insertToActivityLogs(activityLog);
+ }
+}
+
+export async function logWeightChange(activityLog: IActivityLog) {
+ const { task_id, new_value, old_value } = activityLog;
+ if (!task_id || !activityLog.socket) return;
+
+ if (old_value !== new_value) {
+ activityLog.user_id = getLoggedInUserIdFromSocket(activityLog.socket);
+ activityLog.attribute_type = IActivityLogAttributeTypes.WEIGHT;
+ activityLog.log_type = IActivityLogChangeType.UPDATE;
+
+ insertToActivityLogs(activityLog);
+ }
+}
diff --git a/worklenz-backend/src/services/activity-logs/interfaces.ts b/worklenz-backend/src/services/activity-logs/interfaces.ts
index c0c43143..bab97e11 100644
--- a/worklenz-backend/src/services/activity-logs/interfaces.ts
+++ b/worklenz-backend/src/services/activity-logs/interfaces.ts
@@ -29,6 +29,8 @@ export enum IActivityLogAttributeTypes {
COMMENT = "comment",
ARCHIVE = "archive",
PHASE = "phase",
+ PROGRESS = "progress",
+ WEIGHT = "weight",
}
export enum IActivityLogChangeType {
diff --git a/worklenz-backend/src/shared/constants.ts b/worklenz-backend/src/shared/constants.ts
index 28fc60fc..c814c603 100644
--- a/worklenz-backend/src/shared/constants.ts
+++ b/worklenz-backend/src/shared/constants.ts
@@ -117,11 +117,11 @@ export const TASK_DUE_NO_DUE_COLOR = "#a9a9a9";
export const DEFAULT_PAGE_SIZE = 20;
// S3 Credentials
-export const REGION = process.env.AWS_REGION || "us-east-1";
-export const BUCKET = process.env.AWS_BUCKET || "your-bucket-name";
+export const REGION = process.env.S3_REGION || "us-east-1";
+export const BUCKET = process.env.S3_BUCKET || "your-bucket-name";
export const S3_URL = process.env.S3_URL || "https://your-s3-url";
-export const S3_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID || "";
-export const S3_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY || "";
+export const S3_ACCESS_KEY_ID = process.env.S3_ACCESS_KEY_ID || "";
+export const S3_SECRET_ACCESS_KEY = process.env.S3_SECRET_ACCESS_KEY || "";
// Azure Blob Storage Credentials
export const STORAGE_PROVIDER = process.env.STORAGE_PROVIDER || "s3";
diff --git a/worklenz-backend/src/shared/email.ts b/worklenz-backend/src/shared/email.ts
index 83e93651..e0a0f679 100644
--- a/worklenz-backend/src/shared/email.ts
+++ b/worklenz-backend/src/shared/email.ts
@@ -1,7 +1,7 @@
import {SendEmailCommand, SESClient} from "@aws-sdk/client-ses";
import {Validator} from "jsonschema";
import {QueryResult} from "pg";
-import {log_error} from "./utils";
+import {log_error, isValidateEmail} from "./utils";
import emailRequestSchema from "../json_schemas/email-request-schema";
import db from "../config/db";
@@ -33,7 +33,7 @@ function isValidMailBody(body: IEmail) {
async function removeMails(query: string, emails: string[]) {
const result: QueryResult<{ email: string; }> = await db.query(query, []);
const bouncedEmails = result.rows.map(e => e.email);
- for (let i = 0; i < emails.length; i++) {
+ for (let i = emails.length - 1; i >= 0; i--) {
const email = emails[i];
if (bouncedEmails.includes(email)) {
emails.splice(i, 1);
@@ -54,11 +54,20 @@ export async function sendEmail(email: IEmail): Promise {
const options = {...email} as IEmail;
options.to = Array.isArray(options.to) ? Array.from(new Set(options.to)) : [];
+ // Filter out empty, null, undefined, and invalid emails
+ options.to = options.to
+ .filter(email => email && typeof email === 'string' && email.trim().length > 0)
+ .map(email => email.trim())
+ .filter(email => isValidateEmail(email));
+
if (options.to.length) {
await filterBouncedEmails(options.to);
await filterSpamEmails(options.to);
}
+ // Double-check that we still have valid emails after filtering
+ if (!options.to.length) return null;
+
if (!isValidMailBody(options)) return null;
const charset = "UTF-8";
diff --git a/worklenz-backend/src/socket.io/commands/on-get-done-statuses.ts b/worklenz-backend/src/socket.io/commands/on-get-done-statuses.ts
new file mode 100644
index 00000000..4783f4f5
--- /dev/null
+++ b/worklenz-backend/src/socket.io/commands/on-get-done-statuses.ts
@@ -0,0 +1,49 @@
+import { Socket } from "socket.io";
+import db from "../../config/db";
+import { log_error } from "../util";
+
+// Define a type for the callback function
+type DoneStatusesCallback = (statuses: Array<{
+ id: string;
+ name: string;
+ sort_order: number;
+ color_code: string;
+}>) => void;
+
+/**
+ * Socket handler to get task statuses in the "done" category for a project
+ * Used when prompting users to mark a task as done when progress reaches 100%
+ */
+export async function on_get_done_statuses(
+ io: any,
+ socket: Socket,
+ projectId: string,
+ callback: DoneStatusesCallback
+) {
+ try {
+ if (!projectId) {
+ return callback([]);
+ }
+
+ // Query to get all statuses in the "done" category for the project
+ const result = await db.query(`
+ SELECT ts.id, ts.name, ts.sort_order, stsc.color_code
+ FROM task_statuses ts
+ INNER JOIN sys_task_status_categories stsc ON ts.category_id = stsc.id
+ WHERE ts.project_id = $1
+ AND stsc.is_done = TRUE
+ ORDER BY ts.sort_order ASC
+ `, [projectId]);
+
+ const doneStatuses = result.rows;
+
+ console.log(`Found ${doneStatuses.length} "done" statuses for project ${projectId}`);
+
+ // Use callback to return the result
+ callback(doneStatuses);
+
+ } catch (error) {
+ log_error(`Error getting "done" statuses for project ${projectId}: ${error}`);
+ callback([]);
+ }
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/socket.io/commands/on-get-task-progress.ts b/worklenz-backend/src/socket.io/commands/on-get-task-progress.ts
index 586bfc9f..2471a149 100644
--- a/worklenz-backend/src/socket.io/commands/on-get-task-progress.ts
+++ b/worklenz-backend/src/socket.io/commands/on-get-task-progress.ts
@@ -5,6 +5,8 @@ import TasksControllerV2 from "../../controllers/tasks-controller-v2";
export async function on_get_task_progress(_io: Server, socket: Socket, taskId?: string) {
try {
+ console.log(`GET_TASK_PROGRESS requested for task: ${taskId}`);
+
const task: any = {};
task.id = taskId;
@@ -13,6 +15,8 @@ export async function on_get_task_progress(_io: Server, socket: Socket, taskId?:
task.complete_ratio = info.ratio;
task.completed_count = info.total_completed;
task.total_tasks_count = info.total_tasks;
+
+ console.log(`Sending task progress for task ${taskId}: complete_ratio=${task.complete_ratio}`);
}
return socket.emit(SocketEvents.GET_TASK_PROGRESS.toString(), task);
diff --git a/worklenz-backend/src/socket.io/commands/on-get-task-subtasks-count.ts b/worklenz-backend/src/socket.io/commands/on-get-task-subtasks-count.ts
new file mode 100644
index 00000000..c0c14cfe
--- /dev/null
+++ b/worklenz-backend/src/socket.io/commands/on-get-task-subtasks-count.ts
@@ -0,0 +1,89 @@
+import { Socket } from "socket.io";
+import db from "../../config/db";
+import { SocketEvents } from "../events";
+import { log_error } from "../util";
+
+/**
+ * Socket handler to retrieve the number of subtasks for a given task
+ * Used to validate on the client side whether a task should show progress inputs
+ */
+export async function on_get_task_subtasks_count(io: any, socket: Socket, taskId: string) {
+ try {
+ if (!taskId) {
+ return;
+ }
+
+ // Get the count of subtasks for this task
+ const result = await db.query(
+ "SELECT COUNT(*) as subtask_count FROM tasks WHERE parent_task_id = $1 AND archived IS FALSE",
+ [taskId]
+ );
+
+ const subtaskCount = parseInt(result.rows[0]?.subtask_count || "0");
+
+ // Emit the subtask count back to the client
+ socket.emit(
+ "TASK_SUBTASKS_COUNT",
+ {
+ task_id: taskId,
+ subtask_count: subtaskCount,
+ has_subtasks: subtaskCount > 0
+ }
+ );
+
+ console.log(`Emitted subtask count for task ${taskId}: ${subtaskCount}`);
+
+ // If there are subtasks, also get their progress information
+ if (subtaskCount > 0) {
+ // Get all subtasks for this parent task with their progress information
+ const subtasksResult = await db.query(`
+ SELECT
+ t.id,
+ t.progress_value,
+ t.manual_progress,
+ t.weight,
+ CASE
+ WHEN t.manual_progress = TRUE THEN t.progress_value
+ ELSE COALESCE(
+ (SELECT (CASE WHEN tl.total_minutes > 0 THEN
+ (tl.total_minutes_spent / tl.total_minutes * 100)
+ ELSE 0 END)
+ FROM (
+ SELECT
+ t2.id,
+ t2.total_minutes,
+ COALESCE(SUM(twl.time_spent), 0) as total_minutes_spent
+ FROM tasks t2
+ LEFT JOIN task_work_log twl ON t2.id = twl.task_id
+ WHERE t2.id = t.id
+ GROUP BY t2.id, t2.total_minutes
+ ) tl
+ ), 0)
+ END as calculated_progress
+ FROM tasks t
+ WHERE t.parent_task_id = $1 AND t.archived IS FALSE
+ `, [taskId]);
+
+ // Emit progress updates for each subtask
+ for (const subtask of subtasksResult.rows) {
+ const progressValue = subtask.manual_progress ?
+ subtask.progress_value :
+ Math.floor(subtask.calculated_progress);
+
+ socket.emit(
+ SocketEvents.TASK_PROGRESS_UPDATED.toString(),
+ {
+ task_id: subtask.id,
+ progress_value: progressValue,
+ weight: subtask.weight
+ }
+ );
+ }
+
+ console.log(`Emitted progress updates for ${subtasksResult.rows.length} subtasks of task ${taskId}`);
+ }
+
+ } catch (error) {
+ log_error(`Error getting subtask count for task ${taskId}: ${error}`);
+ }
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/socket.io/commands/on-project-subscriber-change.ts b/worklenz-backend/src/socket.io/commands/on-project-subscriber-change.ts
index 6057e88f..bbe90425 100644
--- a/worklenz-backend/src/socket.io/commands/on-project-subscriber-change.ts
+++ b/worklenz-backend/src/socket.io/commands/on-project-subscriber-change.ts
@@ -19,7 +19,8 @@ export async function on_project_subscriber_change(_io: Server, socket: Socket,
const isSubscribe = data.mode == 0;
const q = isSubscribe
? `INSERT INTO project_subscribers (user_id, project_id, team_member_id)
- VALUES ($1, $2, $3);`
+ VALUES ($1, $2, $3)
+ ON CONFLICT (user_id, project_id, team_member_id) DO NOTHING;`
: `DELETE
FROM project_subscribers
WHERE user_id = $1
@@ -27,7 +28,7 @@ export async function on_project_subscriber_change(_io: Server, socket: Socket,
AND team_member_id = $3;`;
await db.query(q, [data.user_id, data.project_id, data.team_member_id]);
- const subscribers = await TasksControllerV2.getTaskSubscribers(data.project_id);
+ const subscribers = await TasksControllerV2.getProjectSubscribers(data.project_id);
socket.emit(SocketEvents.PROJECT_SUBSCRIBERS_CHANGE.toString(), subscribers);
return;
diff --git a/worklenz-backend/src/socket.io/commands/on-quick-task.ts b/worklenz-backend/src/socket.io/commands/on-quick-task.ts
index 859cbf58..066b52d0 100644
--- a/worklenz-backend/src/socket.io/commands/on-quick-task.ts
+++ b/worklenz-backend/src/socket.io/commands/on-quick-task.ts
@@ -56,6 +56,8 @@ export async function on_quick_task(_io: Server, socket: Socket, data?: string)
const q = `SELECT create_quick_task($1) AS task;`;
const body = JSON.parse(data as string);
+
+
body.name = (body.name || "").trim();
body.priority_id = body.priority_id?.trim() || null;
body.status_id = body.status_id?.trim() || null;
@@ -111,10 +113,12 @@ export async function on_quick_task(_io: Server, socket: Socket, data?: string)
notifyProjectUpdates(socket, d.task.id);
}
+ } else {
+ // Empty task name, emit null to indicate no task was created
+ socket.emit(SocketEvents.QUICK_TASK.toString(), null);
}
} catch (error) {
log_error(error);
+ socket.emit(SocketEvents.QUICK_TASK.toString(), null);
}
-
- socket.emit(SocketEvents.QUICK_TASK.toString(), null);
}
diff --git a/worklenz-backend/src/socket.io/commands/on-task-sort-order-change.ts b/worklenz-backend/src/socket.io/commands/on-task-sort-order-change.ts
index 13875901..11ec09cd 100644
--- a/worklenz-backend/src/socket.io/commands/on-task-sort-order-change.ts
+++ b/worklenz-backend/src/socket.io/commands/on-task-sort-order-change.ts
@@ -24,6 +24,14 @@ interface ChangeRequest {
priority: string;
};
team_id: string;
+ // New simplified approach
+ task_updates?: Array<{
+ task_id: string;
+ sort_order: number;
+ status_id?: string;
+ priority_id?: string;
+ phase_id?: string;
+ }>;
}
interface Config {
@@ -64,38 +72,72 @@ function updateUnmappedStatus(config: Config) {
export async function on_task_sort_order_change(_io: Server, socket: Socket, data: ChangeRequest) {
try {
- const q = `SELECT handle_task_list_sort_order_change($1);`;
-
- const config: Config = {
- from_index: data.from_index,
- to_index: data.to_index,
- task_id: data.task.id,
- from_group: data.from_group,
- to_group: data.to_group,
- project_id: data.project_id,
- group_by: data.group_by,
- to_last_index: Boolean(data.to_last_index)
- };
-
- if ((config.group_by === GroupBy.STATUS) && config.to_group) {
- const canContinue = await TasksControllerV2.checkForCompletedDependencies(config.task_id, config?.to_group);
- if (!canContinue) {
- return socket.emit(SocketEvents.TASK_SORT_ORDER_CHANGE.toString(), {
- completed_deps: canContinue
- });
+ // New simplified approach - use bulk updates if provided
+ if (data.task_updates && data.task_updates.length > 0) {
+ // Check dependencies for status changes
+ if (data.group_by === GroupBy.STATUS && data.to_group) {
+ const canContinue = await TasksControllerV2.checkForCompletedDependencies(data.task.id, data.to_group);
+ if (!canContinue) {
+ return socket.emit(SocketEvents.TASK_SORT_ORDER_CHANGE.toString(), {
+ completed_deps: canContinue
+ });
+ }
}
- notifyStatusChange(socket, config);
+ // Use the simple bulk update function
+ const q = `SELECT update_task_sort_orders_bulk($1);`;
+ await db.query(q, [JSON.stringify(data.task_updates)]);
+ await emitSortOrderChange(data, socket);
+
+ // Handle notifications and logging
+ if (data.group_by === GroupBy.STATUS && data.to_group) {
+ notifyStatusChange(socket, {
+ task_id: data.task.id,
+ to_group: data.to_group,
+ from_group: data.from_group,
+ from_index: data.from_index,
+ to_index: data.to_index,
+ project_id: data.project_id,
+ group_by: data.group_by,
+ to_last_index: data.to_last_index
+ });
+ }
+ } else {
+ // Fallback to old complex method
+ const q = `SELECT handle_task_list_sort_order_change($1);`;
+
+ const config: Config = {
+ from_index: data.from_index,
+ to_index: data.to_index,
+ task_id: data.task.id,
+ from_group: data.from_group,
+ to_group: data.to_group,
+ project_id: data.project_id,
+ group_by: data.group_by,
+ to_last_index: Boolean(data.to_last_index)
+ };
+
+ if ((config.group_by === GroupBy.STATUS) && config.to_group) {
+ const canContinue = await TasksControllerV2.checkForCompletedDependencies(config.task_id, config?.to_group);
+ if (!canContinue) {
+ return socket.emit(SocketEvents.TASK_SORT_ORDER_CHANGE.toString(), {
+ completed_deps: canContinue
+ });
+ }
+
+ notifyStatusChange(socket, config);
+ }
+
+ if (config.group_by === GroupBy.PHASE) {
+ updateUnmappedStatus(config);
+ }
+
+ await db.query(q, [JSON.stringify(config)]);
+ await emitSortOrderChange(data, socket);
}
- if (config.group_by === GroupBy.PHASE) {
- updateUnmappedStatus(config);
- }
-
- await db.query(q, [JSON.stringify(config)]);
- await emitSortOrderChange(data, socket);
-
- if (config.group_by === GroupBy.STATUS) {
+ // Common post-processing logic for both approaches
+ if (data.group_by === GroupBy.STATUS) {
const userId = getLoggedInUserIdFromSocket(socket);
const isAlreadyAssigned = await TasksControllerV2.checkUserAssignedToTask(data.task.id, userId as string, data.team_id);
@@ -104,7 +146,7 @@ export async function on_task_sort_order_change(_io: Server, socket: Socket, dat
}
}
- if (config.group_by === GroupBy.PHASE) {
+ if (data.group_by === GroupBy.PHASE) {
void logPhaseChange({
task_id: data.task.id,
socket,
@@ -113,7 +155,7 @@ export async function on_task_sort_order_change(_io: Server, socket: Socket, dat
});
}
- if (config.group_by === GroupBy.STATUS) {
+ if (data.group_by === GroupBy.STATUS) {
void logStatusChange({
task_id: data.task.id,
socket,
@@ -122,7 +164,7 @@ export async function on_task_sort_order_change(_io: Server, socket: Socket, dat
});
}
- if (config.group_by === GroupBy.PRIORITY) {
+ if (data.group_by === GroupBy.PRIORITY) {
void logPriorityChange({
task_id: data.task.id,
socket,
@@ -131,11 +173,11 @@ export async function on_task_sort_order_change(_io: Server, socket: Socket, dat
});
}
- void notifyProjectUpdates(socket, config.task_id);
+ void notifyProjectUpdates(socket, data.task.id);
return;
} catch (error) {
log_error(error);
}
socket.emit(SocketEvents.TASK_SORT_ORDER_CHANGE.toString(), []);
-}
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/socket.io/commands/on-task-status-change.ts b/worklenz-backend/src/socket.io/commands/on-task-status-change.ts
index cce0531c..e59e6b59 100644
--- a/worklenz-backend/src/socket.io/commands/on-task-status-change.ts
+++ b/worklenz-backend/src/socket.io/commands/on-task-status-change.ts
@@ -4,10 +4,11 @@ import db from "../../config/db";
import {NotificationsService} from "../../services/notifications/notifications.service";
import {TASK_STATUS_COLOR_ALPHA} from "../../shared/constants";
import {SocketEvents} from "../events";
-import {getLoggedInUserIdFromSocket, log_error, notifyProjectUpdates} from "../util";
+import {getLoggedInUserIdFromSocket, log, log_error, notifyProjectUpdates} from "../util";
import TasksControllerV2 from "../../controllers/tasks-controller-v2";
-import {getTaskDetails, logStatusChange} from "../../services/activity-logs/activity-logs.service";
+import {getTaskDetails, logProgressChange, logStatusChange} from "../../services/activity-logs/activity-logs.service";
import { assignMemberIfNot } from "./on-quick-assign-or-remove";
+import logger from "../../utils/logger";
export async function on_task_status_change(_io: Server, socket: Socket, data?: string) {
try {
@@ -49,6 +50,63 @@ export async function on_task_status_change(_io: Server, socket: Socket, data?:
});
}
+ // Check if the new status is in a "done" category
+ if (changeResponse.status_category?.is_done) {
+ // Get current progress value
+ const progressResult = await db.query(`
+ SELECT progress_value, manual_progress
+ FROM tasks
+ WHERE id = $1
+ `, [body.task_id]);
+
+ const currentProgress = progressResult.rows[0]?.progress_value;
+ const isManualProgress = progressResult.rows[0]?.manual_progress;
+
+ // Only update if not already 100%
+ if (currentProgress !== 100) {
+ // Update progress to 100%
+ await db.query(`
+ UPDATE tasks
+ SET progress_value = 100, manual_progress = TRUE
+ WHERE id = $1
+ `, [body.task_id]);
+
+ log(`Task ${body.task_id} moved to done status - progress automatically set to 100%`, null);
+
+ // Log the progress change to activity logs
+ await logProgressChange({
+ task_id: body.task_id,
+ old_value: currentProgress !== null ? currentProgress.toString() : "0",
+ new_value: "100",
+ socket
+ });
+
+ // If this is a subtask, update parent task progress
+ if (body.parent_task) {
+ setTimeout(() => {
+ socket.emit(SocketEvents.GET_TASK_PROGRESS.toString(), body.parent_task);
+ }, 100);
+ }
+ }
+ } else {
+ // Task is moving from "done" to "todo" or "doing" - reset manual_progress to FALSE
+ // so progress can be recalculated based on subtasks
+ await db.query(`
+ UPDATE tasks
+ SET manual_progress = FALSE
+ WHERE id = $1
+ `, [body.task_id]);
+
+ log(`Task ${body.task_id} moved from done status - manual_progress reset to FALSE`, null);
+
+ // If this is a subtask, update parent task progress
+ if (body.parent_task) {
+ setTimeout(() => {
+ socket.emit(SocketEvents.GET_TASK_PROGRESS.toString(), body.parent_task);
+ }, 100);
+ }
+ }
+
const info = await TasksControllerV2.getTaskCompleteRatio(body.parent_task || body.task_id);
socket.emit(SocketEvents.TASK_STATUS_CHANGE.toString(), {
diff --git a/worklenz-backend/src/socket.io/commands/on-time-estimation-change.ts b/worklenz-backend/src/socket.io/commands/on-time-estimation-change.ts
index d6c5e606..32517845 100644
--- a/worklenz-backend/src/socket.io/commands/on-time-estimation-change.ts
+++ b/worklenz-backend/src/socket.io/commands/on-time-estimation-change.ts
@@ -6,10 +6,76 @@ import { SocketEvents } from "../events";
import { log_error, notifyProjectUpdates } from "../util";
import { getTaskDetails, logTotalMinutes } from "../../services/activity-logs/activity-logs.service";
-export async function on_time_estimation_change(_io: Server, socket: Socket, data?: string) {
+/**
+ * Recursively updates all ancestor tasks' progress when a subtask changes
+ * @param io Socket.io instance
+ * @param socket Socket instance for emitting events
+ * @param projectId Project ID for room broadcasting
+ * @param taskId The task ID to update (starts with the parent task)
+ */
+async function updateTaskAncestors(io: any, socket: Socket, projectId: string, taskId: string | null) {
+ if (!taskId) return;
+
+ try {
+ // Get the current task's progress ratio
+ const progressRatio = await db.query(
+ "SELECT get_task_complete_ratio($1) as ratio",
+ [taskId]
+ );
+
+ const ratio = progressRatio?.rows[0]?.ratio?.ratio || 0;
+ console.log(`Updated task ${taskId} progress after time estimation change: ${ratio}`);
+
+ // Check if this task needs a "done" status prompt
+ let shouldPromptForDone = false;
+
+ if (ratio >= 100) {
+ // Get the task's current status
+ const taskStatusResult = await db.query(`
+ SELECT ts.id, stsc.is_done
+ FROM tasks t
+ JOIN task_statuses ts ON t.status_id = ts.id
+ JOIN sys_task_status_categories stsc ON ts.category_id = stsc.id
+ WHERE t.id = $1
+ `, [taskId]);
+
+ // If the task isn't already in a "done" category, we should prompt the user
+ if (taskStatusResult.rows.length > 0 && !taskStatusResult.rows[0].is_done) {
+ shouldPromptForDone = true;
+ }
+ }
+
+ // Emit the updated progress
+ socket.emit(
+ SocketEvents.TASK_PROGRESS_UPDATED.toString(),
+ {
+ task_id: taskId,
+ progress_value: ratio,
+ should_prompt_for_done: shouldPromptForDone
+ }
+ );
+
+ // Find this task's parent to continue the recursive update
+ const parentResult = await db.query(
+ "SELECT parent_task_id FROM tasks WHERE id = $1",
+ [taskId]
+ );
+
+ const parentTaskId = parentResult.rows[0]?.parent_task_id;
+
+ // If there's a parent, recursively update it
+ if (parentTaskId) {
+ await updateTaskAncestors(io, socket, projectId, parentTaskId);
+ }
+ } catch (error) {
+ log_error(`Error updating ancestor task ${taskId}: ${error}`);
+ }
+}
+
+export async function on_time_estimation_change(io: Server, socket: Socket, data?: string) {
try {
// (SELECT SUM(time_spent) FROM task_work_log WHERE task_id = t.id) AS total_minutes_spent,
- const q = `UPDATE tasks SET total_minutes = $2 WHERE id = $1 RETURNING total_minutes;`;
+ const q = `UPDATE tasks SET total_minutes = $2 WHERE id = $1 RETURNING total_minutes, project_id, parent_task_id;`;
const body = JSON.parse(data as string);
const hours = body.total_hours || 0;
@@ -19,7 +85,10 @@ export async function on_time_estimation_change(_io: Server, socket: Socket, dat
const task_data = await getTaskDetails(body.task_id, "total_minutes");
const result0 = await db.query(q, [body.task_id, totalMinutes]);
- const [data0] = result0.rows;
+ const [taskData] = result0.rows;
+
+ const projectId = taskData.project_id;
+ const parentTaskId = taskData.parent_task_id;
const result = await db.query("SELECT SUM(time_spent) AS total_minutes_spent FROM task_work_log WHERE task_id = $1;", [body.task_id]);
const [dd] = result.rows;
@@ -31,6 +100,22 @@ export async function on_time_estimation_change(_io: Server, socket: Socket, dat
total_minutes_spent: dd.total_minutes_spent || 0
};
socket.emit(SocketEvents.TASK_TIME_ESTIMATION_CHANGE.toString(), TasksController.updateTaskViewModel(d));
+
+ // If this is a subtask in time-based mode, update parent task progress
+ if (parentTaskId) {
+ const projectSettingsResult = await db.query(
+ "SELECT use_time_progress FROM projects WHERE id = $1",
+ [projectId]
+ );
+
+ const useTimeProgress = projectSettingsResult.rows[0]?.use_time_progress;
+
+ if (useTimeProgress) {
+ // Recalculate parent task progress when subtask time estimation changes
+ await updateTaskAncestors(io, socket, projectId, parentTaskId);
+ }
+ }
+
notifyProjectUpdates(socket, d.id);
logTotalMinutes({
diff --git a/worklenz-backend/src/socket.io/commands/on-update-task-progress.ts b/worklenz-backend/src/socket.io/commands/on-update-task-progress.ts
new file mode 100644
index 00000000..239b7ff8
--- /dev/null
+++ b/worklenz-backend/src/socket.io/commands/on-update-task-progress.ts
@@ -0,0 +1,177 @@
+import { Socket } from "socket.io";
+import db from "../../config/db";
+import { SocketEvents } from "../events";
+import { log, log_error, notifyProjectUpdates } from "../util";
+import { logProgressChange } from "../../services/activity-logs/activity-logs.service";
+import TasksControllerV2 from "../../controllers/tasks-controller-v2";
+
+interface UpdateTaskProgressData {
+ task_id: string;
+ progress_value: number;
+ parent_task_id: string | null;
+}
+
+/**
+ * Recursively updates all ancestor tasks' progress when a subtask changes
+ * @param io Socket.io instance
+ * @param socket Socket instance for emitting events
+ * @param projectId Project ID for room broadcasting
+ * @param taskId The task ID to update (starts with the parent task)
+ */
+async function updateTaskAncestors(io: any, socket: Socket, projectId: string, taskId: string | null) {
+ if (!taskId) return;
+
+ try {
+ // Use the new controller method to update the task progress
+ await TasksControllerV2.updateTaskProgress(taskId);
+
+ // Get the current task's progress ratio
+ const progressRatio = await db.query(
+ "SELECT get_task_complete_ratio($1) as ratio",
+ [taskId]
+ );
+
+ const ratio = progressRatio?.rows[0]?.ratio?.ratio || 0;
+ console.log(`Updated task ${taskId} progress: ${ratio}`);
+
+ // Check if this task needs a "done" status prompt
+ let shouldPromptForDone = false;
+
+ if (ratio >= 100) {
+ // Get the task's current status
+ const taskStatusResult = await db.query(`
+ SELECT ts.id, stsc.is_done
+ FROM tasks t
+ JOIN task_statuses ts ON t.status_id = ts.id
+ JOIN sys_task_status_categories stsc ON ts.category_id = stsc.id
+ WHERE t.id = $1
+ `, [taskId]);
+
+ // If the task isn't already in a "done" category, we should prompt the user
+ if (taskStatusResult.rows.length > 0 && !taskStatusResult.rows[0].is_done) {
+ shouldPromptForDone = true;
+ }
+ }
+
+ // Emit the updated progress
+ socket.emit(
+ SocketEvents.TASK_PROGRESS_UPDATED.toString(),
+ {
+ task_id: taskId,
+ progress_value: ratio,
+ should_prompt_for_done: shouldPromptForDone
+ }
+ );
+
+ // Find this task's parent to continue the recursive update
+ const parentResult = await db.query(
+ "SELECT parent_task_id FROM tasks WHERE id = $1",
+ [taskId]
+ );
+
+ const parentTaskId = parentResult.rows[0]?.parent_task_id;
+
+ // If there's a parent, recursively update it
+ if (parentTaskId) {
+ await updateTaskAncestors(io, socket, projectId, parentTaskId);
+ }
+ } catch (error) {
+ log_error(`Error updating ancestor task ${taskId}: ${error}`);
+ }
+}
+
+export async function on_update_task_progress(io: any, socket: Socket, data: string) {
+ try {
+ const parsedData = JSON.parse(data) as UpdateTaskProgressData;
+ const { task_id, progress_value, parent_task_id } = parsedData;
+
+ if (!task_id || progress_value === undefined) {
+ return;
+ }
+
+ // Check if this is a parent task (has subtasks)
+ const subTasksResult = await db.query(
+ "SELECT COUNT(*) as subtask_count FROM tasks WHERE parent_task_id = $1",
+ [task_id]
+ );
+
+ const subtaskCount = parseInt(subTasksResult.rows[0]?.subtask_count || "0");
+
+ // If this is a parent task, we shouldn't set manual progress
+ if (subtaskCount > 0) {
+ log_error(`Cannot set manual progress on parent task ${task_id} with ${subtaskCount} subtasks`);
+ return;
+ }
+
+ // Get the current progress value to log the change
+ const currentProgressResult = await db.query(
+ "SELECT progress_value, project_id, status_id FROM tasks WHERE id = $1",
+ [task_id]
+ );
+
+ const currentProgress = currentProgressResult.rows[0]?.progress_value;
+ const projectId = currentProgressResult.rows[0]?.project_id;
+ const statusId = currentProgressResult.rows[0]?.status_id;
+
+ // Update the task progress in the database
+ await db.query(
+ `UPDATE tasks
+ SET progress_value = $1, manual_progress = true, updated_at = NOW()
+ WHERE id = $2`,
+ [progress_value, task_id]
+ );
+
+ // Log the progress change using the activity logs service
+ await logProgressChange({
+ task_id,
+ old_value: currentProgress !== null ? currentProgress.toString() : "0",
+ new_value: progress_value.toString(),
+ socket
+ });
+
+ if (projectId) {
+ // Check if progress is 100% and the task isn't already in a "done" status category
+ let shouldPromptForDone = false;
+
+ if (progress_value >= 100) {
+ // Check if the task's current status is in a "done" category
+ const statusCategoryResult = await db.query(`
+ SELECT stsc.is_done
+ FROM task_statuses ts
+ JOIN sys_task_status_categories stsc ON ts.category_id = stsc.id
+ WHERE ts.id = $1
+ `, [statusId]);
+
+ // If the task isn't already in a "done" category, we should prompt the user
+ if (statusCategoryResult.rows.length > 0 && !statusCategoryResult.rows[0].is_done) {
+ shouldPromptForDone = true;
+ }
+ }
+
+ // Emit the update to all clients in the project room
+ socket.emit(
+ SocketEvents.TASK_PROGRESS_UPDATED.toString(),
+ {
+ task_id,
+ progress_value,
+ should_prompt_for_done: shouldPromptForDone
+ }
+ );
+
+ log(`Emitted progress update for task ${task_id} to project room ${projectId}`, null);
+
+ // If this task has a parent, use our controller to update all ancestors
+ if (parent_task_id) {
+ // Use the controller method to update the parent task's progress
+ await TasksControllerV2.updateTaskProgress(parent_task_id);
+ // Also use the existing method for socket notifications
+ await updateTaskAncestors(io, socket, projectId, parent_task_id);
+ }
+
+ // Notify that project updates are available
+ notifyProjectUpdates(socket, task_id);
+ }
+ } catch (error) {
+ log_error(error);
+ }
+}
diff --git a/worklenz-backend/src/socket.io/commands/on-update-task-weight.ts b/worklenz-backend/src/socket.io/commands/on-update-task-weight.ts
new file mode 100644
index 00000000..7d0f65bf
--- /dev/null
+++ b/worklenz-backend/src/socket.io/commands/on-update-task-weight.ts
@@ -0,0 +1,107 @@
+import { Socket } from "socket.io";
+import db from "../../config/db";
+import { SocketEvents } from "../events";
+import { log, log_error, notifyProjectUpdates } from "../util";
+import { logWeightChange } from "../../services/activity-logs/activity-logs.service";
+import TasksControllerV2 from "../../controllers/tasks-controller-v2";
+
+interface UpdateTaskWeightData {
+ task_id: string;
+ weight: number;
+ parent_task_id: string | null;
+}
+
+export async function on_update_task_weight(io: any, socket: Socket, data: string) {
+ try {
+
+ const parsedData = JSON.parse(data) as UpdateTaskWeightData;
+ const { task_id, weight, parent_task_id } = parsedData;
+
+ if (!task_id || weight === undefined) {
+ return;
+ }
+
+ // Get the current weight value to log the change
+ const currentWeightResult = await db.query(
+ "SELECT weight, project_id FROM tasks WHERE id = $1",
+ [task_id]
+ );
+
+ const currentWeight = currentWeightResult.rows[0]?.weight;
+ const projectId = currentWeightResult.rows[0]?.project_id;
+
+ // Update the task weight using our controller method
+ await TasksControllerV2.updateTaskWeight(task_id, weight);
+
+ // Log the weight change using the activity logs service
+ await logWeightChange({
+ task_id,
+ old_value: currentWeight !== null ? currentWeight.toString() : "100",
+ new_value: weight.toString(),
+ socket
+ });
+
+ if (projectId) {
+ // Emit the update to all clients in the project room
+ socket.emit(
+ SocketEvents.TASK_PROGRESS_UPDATED.toString(),
+ {
+ task_id,
+ weight
+ }
+ );
+
+ // If this is a subtask, update the parent task's progress
+ if (parent_task_id) {
+ // Use the controller to update the parent task progress
+ await TasksControllerV2.updateTaskProgress(parent_task_id);
+
+ // Get the updated progress to emit to clients
+ const progressRatio = await db.query(
+ "SELECT get_task_complete_ratio($1) as ratio",
+ [parent_task_id]
+ );
+
+ // Emit the parent task's updated progress
+ socket.emit(
+ SocketEvents.TASK_PROGRESS_UPDATED.toString(),
+ {
+ task_id: parent_task_id,
+ progress_value: progressRatio?.rows[0]?.ratio?.ratio || 0
+ }
+ );
+
+ // We also need to update any grandparent tasks
+ const grandparentResult = await db.query(
+ "SELECT parent_task_id FROM tasks WHERE id = $1",
+ [parent_task_id]
+ );
+
+ const grandparentId = grandparentResult.rows[0]?.parent_task_id;
+
+ if (grandparentId) {
+ await TasksControllerV2.updateTaskProgress(grandparentId);
+
+ // Emit the grandparent's updated progress
+ const grandparentProgressRatio = await db.query(
+ "SELECT get_task_complete_ratio($1) as ratio",
+ [grandparentId]
+ );
+
+ socket.emit(
+ SocketEvents.TASK_PROGRESS_UPDATED.toString(),
+ {
+ task_id: grandparentId,
+ progress_value: grandparentProgressRatio?.rows[0]?.ratio?.ratio || 0
+ }
+ );
+ }
+ }
+
+ // Notify that project updates are available
+ notifyProjectUpdates(socket, task_id);
+ }
+ } catch (error) {
+ log_error(error);
+ }
+}
\ No newline at end of file
diff --git a/worklenz-backend/src/socket.io/events.ts b/worklenz-backend/src/socket.io/events.ts
index 398ff030..c0a58008 100644
--- a/worklenz-backend/src/socket.io/events.ts
+++ b/worklenz-backend/src/socket.io/events.ts
@@ -57,4 +57,17 @@ export enum SocketEvents {
TASK_ASSIGNEES_CHANGE,
TASK_CUSTOM_COLUMN_UPDATE,
CUSTOM_COLUMN_PINNED_CHANGE,
+ TEAM_MEMBER_ROLE_CHANGE,
+
+ // Task progress events
+ UPDATE_TASK_PROGRESS,
+ UPDATE_TASK_WEIGHT,
+ TASK_PROGRESS_UPDATED,
+
+ // Task subtasks count events
+ GET_TASK_SUBTASKS_COUNT,
+ TASK_SUBTASKS_COUNT,
+
+ // Task completion events
+ GET_DONE_STATUSES,
}
diff --git a/worklenz-backend/src/socket.io/index.ts b/worklenz-backend/src/socket.io/index.ts
index 29c4b147..04927214 100644
--- a/worklenz-backend/src/socket.io/index.ts
+++ b/worklenz-backend/src/socket.io/index.ts
@@ -52,6 +52,10 @@ import { on_task_recurring_change } from "./commands/on-task-recurring-change";
import { on_task_assignees_change } from "./commands/on-task-assignees-change";
import { on_task_custom_column_update } from "./commands/on_custom_column_update";
import { on_custom_column_pinned_change } from "./commands/on_custom_column_pinned_change";
+import { on_update_task_progress } from "./commands/on-update-task-progress";
+import { on_update_task_weight } from "./commands/on-update-task-weight";
+import { on_get_task_subtasks_count } from "./commands/on-get-task-subtasks-count";
+import { on_get_done_statuses } from "./commands/on-get-done-statuses";
export function register(io: any, socket: Socket) {
log(socket.id, "client registered");
@@ -69,7 +73,6 @@ export function register(io: any, socket: Socket) {
socket.on(SocketEvents.TASK_TIME_ESTIMATION_CHANGE.toString(), data => on_time_estimation_change(io, socket, data));
socket.on(SocketEvents.TASK_DESCRIPTION_CHANGE.toString(), data => on_task_description_change(io, socket, data));
socket.on(SocketEvents.GET_TASK_PROGRESS.toString(), data => on_get_task_progress(io, socket, data));
- socket.on(SocketEvents.GET_TASK_PROGRESS.toString(), data => on_get_task_progress(io, socket, data));
socket.on(SocketEvents.TASK_TIMER_START.toString(), data => on_task_timer_start(io, socket, data));
socket.on(SocketEvents.TASK_TIMER_STOP.toString(), data => on_task_timer_stop(io, socket, data));
socket.on(SocketEvents.TASK_SORT_ORDER_CHANGE.toString(), data => on_task_sort_order_change(io, socket, data));
@@ -106,6 +109,10 @@ export function register(io: any, socket: Socket) {
socket.on(SocketEvents.TASK_ASSIGNEES_CHANGE.toString(), data => on_task_assignees_change(io, socket, data));
socket.on(SocketEvents.TASK_CUSTOM_COLUMN_UPDATE.toString(), data => on_task_custom_column_update(io, socket, data));
socket.on(SocketEvents.CUSTOM_COLUMN_PINNED_CHANGE.toString(), data => on_custom_column_pinned_change(io, socket, data));
+ socket.on(SocketEvents.UPDATE_TASK_PROGRESS.toString(), data => on_update_task_progress(io, socket, data));
+ socket.on(SocketEvents.UPDATE_TASK_WEIGHT.toString(), data => on_update_task_weight(io, socket, data));
+ socket.on(SocketEvents.GET_TASK_SUBTASKS_COUNT.toString(), (taskId) => on_get_task_subtasks_count(io, socket, taskId));
+ socket.on(SocketEvents.GET_DONE_STATUSES.toString(), (projectId, callback) => on_get_done_statuses(io, socket, projectId, callback));
// socket.io built-in event
socket.on("disconnect", (reason) => on_disconnect(io, socket, reason));
diff --git a/worklenz-backend/worklenz-email-templates/password-changed-notification.html b/worklenz-backend/worklenz-email-templates/password-changed-notification.html
index f734d8a8..2c8e2d3a 100644
--- a/worklenz-backend/worklenz-email-templates/password-changed-notification.html
+++ b/worklenz-backend/worklenz-email-templates/password-changed-notification.html
@@ -2,31 +2,30 @@
-
+ Password Changed | Worklenz
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+ Password Changed Successfully
+
+
+
Hi,
+
This is a confirmation that your Worklenz
+ account password was changed.
-
- Experience a comprehensive visual representation of task progression within your projects.
- The sequential arrangement unfolds seamlessly in a user-friendly timeline format, allowing
- for effortless understanding and efficient project management.
-
-
-
-
-
-
-
-
-
-
-
-
Project Workload Redesign
-
- Gain insights into the optimized allocation and utilization of resources within your project.
-
-
-
-
-
-
-
-
-
-
-
-
Create new tasks from the roadmap itself
-
- Effortlessly generate and modify tasks directly from the roadmap interface with a simple
- click-and-drag functionality.
- Seamlessly adjust the task's date range according to your
- preferences, providing a user-friendly and intuitive experience for efficient task management.
-
-
-
-
-
-
-
-
-
-
-
-
Deactivate Team Members
-
- Effortlessly manage your team by deactivating members without losing their valuable work.
-
-
- Navigate to the "Settings" section and access "Team Members" to conveniently deactivate
- team members while preserving the work they have contributed.
-
-
-
-
-
-
-
-
-
-
-
-
Reporting Enhancements
-
- This release also includes several other miscellaneous bug fixes and performance
- enhancements to further improve your experience.
-