diff --git a/README.md b/README.md
index 7d39919..a23eb64 100644
--- a/README.md
+++ b/README.md
@@ -1,204 +1,90 @@
# Spreadsheet Collaborative Editing
-This repository showcases real-time collaborative editing using the Syncfusion® Spreadsheet Editor, allowing multiple users to edit the same workbook simultaneously. The project demonstrates how to implement collaborative features across multiple frontend frameworks (Angular, React, Vue, and TypeScript) with an ASP.NET Core backend.
+This repository demonstrates real-time collaborative editing in the Syncfusion® Spreadsheet. Multiple users can edit the same workbook simultaneously, and supported changes are synchronized across all users connected to the same collaboration room.
## Features
-- Real-time collaborative editing of spreadsheets
-- Support for multiple frontend frameworks:
- - Angular
- - React
- - Vue
- - TypeScript (Vanilla)
-- ASP.NET Core backend with SignalR for real-time communication
-- Redis integration for collaboration state management
-- Spreadsheet operations synchronization across multiple clients
-- Selection highlighting for other users' cursor positions
+- Real-time multi-user Spreadsheet editing
+- Synchronization of supported Spreadsheet actions
+- Participant presence and selection indicators
+- SignalR-based real-time communication
+- Redis-backed collaboration state management
+- Client samples for Angular, JavaScript, React, TypeScript, and Vue
## Prerequisites
-### Backend
-- .NET 10.0 SDK
-- Redis server (for collaboration state management)
-- Syncfusion license key
+- Node.js and npm
+- ASP.NET Core Collaboration Server
+- Redis Server or a hosted Redis service
+- A valid Syncfusion license key
+
+## Repository structure
+
+```text
+Spreadsheet-Collaborative-Editing/
+|-- client/
+| |-- angular/
+| |-- javascript/
+| |-- react/
+| |-- typescript/
+| `-- vue/
+|-- server/
+| `-- aspnet-core/
+|-- README.md
+`-- license
+```
+
+## Client samples
+
+- [Angular](./client/angular)
+- [JavaScript](./client/javascript)
+- [React](./client/react)
+- [TypeScript](./client/typescript)
+- [Vue](./client/vue)
-### Frontend
-- Node.js (v18 or later)
-- npm or yarn
+Refer to the README file inside each client folder for platform-specific installation, configuration, and run instructions.
-## Project Structure
+## Collaboration Server
+The Collaboration Server uses SignalR for real-time communication and Redis to maintain collaboration sessions and synchronize workbook actions.
+
+Configure the Redis connection string in the server settings:
+
+```json
+{
+ "ConnectionStrings": {
+ "Redis": "YOUR_REDIS_CONNECTION_STRING"
+ }
+}
```
-├── client/
-│ ├── angular/ # Angular implementation
-│ ├── react/ # React implementation
-│ ├── typescript/ # TypeScript/Vanilla implementation
-│ └── vue/ # Vue implementation
-├── server/
-│ └── aspnet-core/ # ASP.NET Core backend with SignalR
-└── README.md
+
+Refer to the README file inside the server folder for setup and run instructions.
+
+## Configure the server URL
+
+In each client sample, replace the Collaboration Server URL placeholder with the URL of the running server:
+
+```text
+YOUR_COLLABORATION_SERVER_URL
```
-## Setup
-
-### Backend Setup
-
-1. Navigate to the server directory:
- ```bash
- cd server/aspnet-core
- ```
-
-2. Configure your Syncfusion license:
- - Add your license key to `SyncfusionLicense.txt` file
- - Or set the `SYNCFUSION_LICENSE_KEY` environment variable
-
-3. Configure Redis connection:
- - Update the Redis connection string in `appsettings.json`:
- ```json
- {
- "ConnectionStrings": {
- "Redis": "your_redis_connection_string"
- }
- }
- ```
-
-4. Run the server:
- ```bash
- dotnet run
- ```
-
- The server will start on `https://localhost:5001` by default.
-
-### Frontend Setup
-
-Choose one of the client implementations:
-
-#### Angular
-
-1. Navigate to the Angular client:
- ```bash
- cd client/angular
- ```
-
-2. Install dependencies:
- ```bash
- npm install
- ```
-
-3. Update the service URL in `src/components/spreadsheet-editor/spreadsheet-editor.component.ts`:
- ```typescript
- const serviceUrl: string = 'https://localhost:5001/';
- ```
-
-4. Run the application:
- ```bash
- npm start
- ```
-
- The application will be available at `http://localhost:4200`.
-
-#### React
-
-1. Navigate to the React client:
- ```bash
- cd client/react
- ```
-
-2. Install dependencies:
- ```bash
- npm install
- ```
-
-3. Update the service URL in `src/SpreadsheetEditorAdapter.ts`:
- ```typescript
- const serviceUrl: string = 'https://localhost:5001/';
- ```
-
-4. Run the application:
- ```bash
- npm run dev
- ```
-
- The application will be available at `http://localhost:5173`.
-
-#### Vue
-
-1. Navigate to the Vue client:
- ```bash
- cd client/vue
- ```
-
-2. Install dependencies:
- ```bash
- npm install
- ```
-
-3. Update the service URL in `src/SpreadsheetEditorAdapter.ts`:
- ```typescript
- const serviceUrl: string = 'https://localhost:5001/';
- ```
-
-4. Run the application:
- ```bash
- npm run dev
- ```
-
- The application will be available at `http://localhost:5173`.
-
-#### TypeScript (Vanilla)
-
-1. Navigate to the TypeScript client:
- ```bash
- cd client/typescript
- ```
-
-2. Install dependencies:
- ```bash
- npm install
- ```
-
-3. Update the service URL in `src/spreadsheet-editor-adapter.ts`:
- ```typescript
- const serviceUrl: string = 'https://localhost:5001/';
- ```
-
-4. Run the application:
- ```bash
- npm run dev
- ```
-
- The application will be available at `http://localhost:5173`.
+Users who connect to the same server and open a URL containing the same `id` query parameter join the same collaboration room.
-## Usage
-
-1. Start the backend server
-2. Start one of the frontend clients
-3. Open the application in multiple browser windows or devices
-4. Each user will be assigned a unique room ID automatically
-5. To collaborate in the same room, share the URL with the room ID parameter
-6. All users in the same room will see real-time updates as others edit the spreadsheet
-
-## API Endpoints
-
-The backend provides the following API endpoints:
-
-- `POST /api/CollaborativeEditing/ImportFile` - Import a file for collaborative editing
-
-## Contributing
-
-Contributions are welcome! Please follow these steps:
-
-1. Fork the repository
-2. Create a feature branch
-3. Commit your changes
-4. Push to the branch
-5. Create a pull request
+## Test collaborative editing
-## License
+1. Start Redis and the Collaboration Server.
+2. Start any client sample.
+3. Open the application in a browser.
+4. Copy the complete URL containing the `id` query parameter.
+5. Open the copied URL in another browser tab or window.
+6. Edit the workbook and verify that supported changes are synchronized between both clients.
+
+## Documentation
-This project uses Syncfusion Essential JS 2 components, which are licensed under either the Syncfusion Community License Program or the Syncfusion commercial license.
+- [Collaborative editing overview](https://help.syncfusion.com/document-processing/excel/spreadsheet/react/collaborative-editing/overview)
+- [Collaboration Client](https://help.syncfusion.com/document-processing/collaborator/collaboration-client)
+- [Collaboration Server](https://help.syncfusion.com/document-processing/collaborator/collaboration-server)
-Please refer to the [license](license) file for more information.
+## License
-To use this product, you must agree to and abide by Syncfusion's license containing all terms and conditions, which can be found at:
-https://www.syncfusion.com/content/downloads/syncfusion_license.pdf
+This project is licensed under the terms specified in the repository's license file.
diff --git a/client/angular/src/components/spreadsheet-editor/spreadsheet-editor.component.ts b/client/angular/src/components/spreadsheet-editor/spreadsheet-editor.component.ts
index b074c2b..4ab96aa 100644
--- a/client/angular/src/components/spreadsheet-editor/spreadsheet-editor.component.ts
+++ b/client/angular/src/components/spreadsheet-editor/spreadsheet-editor.component.ts
@@ -8,8 +8,8 @@ import { CollaborationClient } from '@syncfusion/ej2-collaborator';
import { SpreadsheetEditorAdapter } from './spreadsheet-editor-adapter';
const serviceUrl: string =
- 'https://appservice-267100-e9c8cxaab6a2dfeu.centralindia-01.azurewebsites.net/';
-const currentUser: string = 'John';
+ ''YOUR_COLLABORATION_SERVER_URL'';
+const currentUser: string = 'John Adams';
function getRoomName(): string {
const currentUrl: URL = new URL(window.location.href);
diff --git a/client/javascript/.gitignore b/client/javascript/.gitignore
new file mode 100644
index 0000000..cc9689e
--- /dev/null
+++ b/client/javascript/.gitignore
@@ -0,0 +1,6 @@
+node_modules
+dist
+.vscode/*
+!.vscode/extensions.json
+.DS_Store
+*.local
diff --git a/client/javascript/README.md b/client/javascript/README.md
new file mode 100644
index 0000000..0d35784
--- /dev/null
+++ b/client/javascript/README.md
@@ -0,0 +1,79 @@
+# JavaScript Spreadsheet Collaborative Editing
+
+This example demonstrates real-time collaborative editing in the Syncfusion Essential JS 2 JavaScript Spreadsheet. Multiple users can edit the same workbook, and supported actions are synchronized through the Collaboration Server.
+
+## Prerequisites
+
+- Node.js
+- Redis Server
+- ASP.NET Core Redis Collaboration Server, or access to the configured hosted Collaboration Server
+
+## Install dependencies
+
+```bash
+npm install
+```
+
+## Configure the Collaboration Server
+
+The Collaboration Server URL is defined in `src/index.js`. Update `serviceUrl` when a different server endpoint is used.
+
+## Run the application
+
+```bash
+npm run dev
+```
+
+Open the URL displayed by Vite, normally:
+
+```text
+http://localhost:5173/
+```
+
+When the page opens without an `id` query parameter, the client generates a room ID and updates the URL. Open the complete URL in another browser tab or window to join the same collaboration room.
+
+Example:
+
+```text
+http://localhost:5173/?id=sample-room
+```
+
+## Project structure
+
+```text
+src/
+|-- index.js
+|-- spreadsheet-editor-adapter.js
+`-- style.css
+```
+
+## How it works
+
+1. `CollaborativeEditingHandler` is injected into the Spreadsheet.
+2. The Spreadsheet starts with collaborative editing enabled.
+3. The client obtains or generates a room ID from the URL.
+4. The adapter imports the latest workbook and room version from the server.
+5. `CollaborationClient` connects through SignalR and joins the room.
+6. Local Spreadsheet actions are sent from `actionComplete`.
+7. Remote actions are applied through `SpreadsheetEditorAdapter.applyRemoteAction`.
+
+## Build
+
+```bash
+npm run build
+```
+
+## Important packages
+
+- `@syncfusion/ej2-spreadsheet`
+- `@syncfusion/ej2-collaborator`
+- `@microsoft/signalr`
+- `@syncfusion/ej2-tailwind3-theme`
+
+## Troubleshooting
+
+If clients do not synchronize, verify that the Collaboration Server is reachable, Redis is running, all clients use the same room ID, and the browser console has no SignalR or CORS errors.
+
+## License
+
+Refer to the license file in the parent repository.
diff --git a/client/javascript/index.html b/client/javascript/index.html
new file mode 100644
index 0000000..0e768e8
--- /dev/null
+++ b/client/javascript/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ JavaScript Spreadsheet Collaborative Editing
+
+
+
+
+
+
diff --git a/client/javascript/package-lock.json b/client/javascript/package-lock.json
new file mode 100644
index 0000000..65f9841
--- /dev/null
+++ b/client/javascript/package-lock.json
@@ -0,0 +1,1663 @@
+{
+ "name": "javascript-spreadsheet-collaborative-editing",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "javascript-spreadsheet-collaborative-editing",
+ "version": "1.0.0",
+ "dependencies": {
+ "@microsoft/signalr": "^9.0.0",
+ "@syncfusion/ej2-collaborator": "35.1.37",
+ "@syncfusion/ej2-spreadsheet": "35.1.37",
+ "@syncfusion/ej2-tailwind3-theme": "35.1.37"
+ },
+ "devDependencies": {
+ "vite": "^7.1.9"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz",
+ "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz",
+ "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz",
+ "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz",
+ "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz",
+ "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz",
+ "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz",
+ "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz",
+ "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz",
+ "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz",
+ "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz",
+ "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz",
+ "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz",
+ "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz",
+ "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz",
+ "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz",
+ "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz",
+ "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz",
+ "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz",
+ "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz",
+ "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz",
+ "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz",
+ "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz",
+ "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz",
+ "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz",
+ "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz",
+ "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@microsoft/signalr": {
+ "version": "9.0.19",
+ "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-9.0.19.tgz",
+ "integrity": "sha512-hKDxt4nRXvkhhy+Etlhbg0UDQdhk8PsZKlQTnHyCn+bb+Q6gM8RCZLI43WsLH1IQCa7l/G8tX09em1F1LH/C1w==",
+ "license": "MIT",
+ "dependencies": {
+ "abort-controller": "^3.0.0",
+ "eventsource": "^2.0.2",
+ "fetch-cookie": "^2.0.3",
+ "node-fetch": "^2.6.7",
+ "ws": "^7.5.10"
+ }
+ },
+ "node_modules/@napi-rs/lzma-linux-x64-gnu": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz",
+ "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^22.20 || ^24.12 || >=25"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.64.0.tgz",
+ "integrity": "sha512-FLLpX941CD/7aBvX3GqLGBM9OvY5PGXTryPJkG5r5/OuBpZpV5k45Uo3RxAvqd35tsyc3hH1bhtz921IKzoIzg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.64.0.tgz",
+ "integrity": "sha512-iI32XM/jnDYJsvx5ai/za/7gWO9XoSeFFtU06/ZCaRgyilfJOjaopD3nOpk2WrTCGOyeDt4hleUiGOAnd5tHNg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.64.0.tgz",
+ "integrity": "sha512-dRBZlbt2sEtF8Mn4MODThze9fIPdDoOhVSlXMAKy5dQbOYK9pOOoPY4Fat3OTtr0+8zbJo5TTZwlsfxY/kDNJg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.64.0.tgz",
+ "integrity": "sha512-Y3whrJOMucfkhgNkvcM93M6j8C53iEAMmPMYD99C6G1kUy4ELigLWk9ar2/4aCBSRgsql0zdlOemLgW2m5GZgQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.64.0.tgz",
+ "integrity": "sha512-S6S1GEzPjFF6IONYJX3AKt/799+8RgBgCcwRnUo+Ep1IvBxUbw5M51iU0TDdK2NWWVnSvCQ8yi6Em0fGASMOng==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.64.0.tgz",
+ "integrity": "sha512-Ed1DPoFENkXj4IGzSB12SesV40iP6LxCCrbTIkSGIQBpOOxpBM+0kj62lmaeIHfMWTDoddqTOtqc7s8LYfn+Pw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.64.0.tgz",
+ "integrity": "sha512-J/6xhutJPtFyIkmHdf4olOdHHKH5kOJNumojdWn+Elv5ICEYTVOa362Vw27TxsK0BLzb1le3EDlO3UbvFK1lnQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.64.0.tgz",
+ "integrity": "sha512-G4L/Nnx59d2LvDoV/P4S5lZ7oVLT6hodOHMacqjiq2LL2gts86KbkEBTYL53+fBt0odhf7XPIbIATGoYiJctxg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.64.0.tgz",
+ "integrity": "sha512-zF16pvJDEUksGYRbfnXne7pdklAyj2XDmJeYKgP93oq0cUyX9Y8O7lUo1R+IY1GagP/YBvCEDCe7eEcAKpw//g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.64.0.tgz",
+ "integrity": "sha512-nIggWn8n+w12+R5lsV+PYYoUY8vuObxPAQqJI7WES+9v0qspYuAHoZMfYM0yLxlipasT5BY9ht5W8t5c/rSCkg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.64.0.tgz",
+ "integrity": "sha512-WLOTiHPzszP0dxIMsHpFeDSOSB5I49Mj8K4+yKE3H1X/D0JRG5XZ5jrctJLMjnUc/LUzaKiwq6EHWNJ8pup8PA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.64.0.tgz",
+ "integrity": "sha512-35RK9aRhh7g7Pmeu5gQ01aCvrhXzj9LoBE6xtUcEH1ns+nyTaSzxSpADmBQINu4QiTDGvmQYwo1j5hlg1rRXFw==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.64.0.tgz",
+ "integrity": "sha512-RqTfnpoTjuWfPAmqK5p2edt2AMCDJWm6oTn7sKfmyx+6tRga0ip05SJ977o6udTcIiDeF/CJMUfkaN4gtWt6Aw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.64.0.tgz",
+ "integrity": "sha512-RQjZPigjxFvFZDijG6rjlSXxhRaTf9zLYVpGK+lVcga64oMqP1GbgVqCb46eHTTceSIgp89Ja0y5aPe3GFBYHg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.64.0.tgz",
+ "integrity": "sha512-tjL58mgQcTRnDRpeky+Sth1MKQeYi2Ct6r3Luq9E5aTSjnM/i/JbozqZkKqp9thM5+oDSZxo+05f9kdQedfTGA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.64.0.tgz",
+ "integrity": "sha512-ictoRyVaoZ8C67myHef+8hhCa6IplXJJ/xUCkVCxziV4zxMZh+jvhkhGsPBLqj1S72fnqD0QH5zL4lcaa4X7DQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.64.0.tgz",
+ "integrity": "sha512-8aVvZ2hfr9RLFzBQkQNmYeHLDja8fLeQAmLt757zdKN/B+8L809KlLJKctQjS22wZotptV8G6o7fVPuAs8S1tQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.64.0.tgz",
+ "integrity": "sha512-2dEF8GAcDKwshUfydD+GhosppNyBzhVUHkdFF3CXd3FpOkzj/RZzF5aoEtzklujklT5qFVRU2GK/cFeLaTNKVg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.64.0.tgz",
+ "integrity": "sha512-3XHTvoo2hKkh0MiOfS7SkhHjMaaWF7P4F3drocZZaho/Z8w7h/jpnuBHm91BOQLfvrKHs1yR+zir4E8RI3XzTQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.64.0.tgz",
+ "integrity": "sha512-HKtkzodL4a3KFWDXDoO61cRynAWTR3LnAE0oGtfG9lcNFpNuVYUFOByxDgNqEvic9rvaQbAj+SFwTEWDptRaIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.64.0.tgz",
+ "integrity": "sha512-JBsxqiY16uyyCujtoC3s7zL+SrYyNElptD7K4V+KUoJ2V8/XG3hPWpheK+SuPwNh1cikJvIZmIdsrYXvD6PLJw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.64.0.tgz",
+ "integrity": "sha512-S5Qrijh37qhnUYQ0ay8WN3LuWeKjow7wTUyCOPMZtnXiBXYXdsZETI6ZLfYnQAKovltckPLBFdNeD61P2rJc7g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.64.0.tgz",
+ "integrity": "sha512-zbZ6iMmLFEsCtTdc2/y1F/cDFVNNCPF7Ae8PCT/wdPE//hGwYp6r+MyCLMFX+kOeIe09Pz6ASfnnfpSTN1FJQQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.64.0.tgz",
+ "integrity": "sha512-L6Hw69oNpuYaOr1zCG30v0/DqKYCSRwodPGwIcVZ/6f8SOzq9rxtL/xNVI5MO4wjli+Ko0ErK9uHJL3mNPt8wQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.64.0.tgz",
+ "integrity": "sha512-nl+CTWIgOGszQmUz/kanfgrfFZ4qiwxKIfT/ryl3N3Ewk5tqizmYtNXiqb7Bu/fDtNgu1kyxdFiAUJNur3iysg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@syncfusion/ej2-base": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-base/-/ej2-base-35.1.37.tgz",
+ "integrity": "sha512-pg4WMFGbZJ9XoGr7ecBQ4+afWeVh1s0nckwqa1fFe1PK48Szg/gV5rEFXygFsHfratparBVAJogAd8WrWv3pYg==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-icons": "~35.1.37"
+ },
+ "bin": {
+ "syncfusion-license": "bin/syncfusion-license.js"
+ }
+ },
+ "node_modules/@syncfusion/ej2-buttons": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-buttons/-/ej2-buttons-35.1.37.tgz",
+ "integrity": "sha512-tLYpbTqfPPNBqVZ8SmwM9yw+gAkBRhD0Rcl+1YcrG/8z43tVqWJdemtOlOItV/GGEQXXhDbX7PKgJs9m3CDkrg==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-calculate": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-calculate/-/ej2-calculate-35.1.37.tgz",
+ "integrity": "sha512-q6Ogf+3vUcDZFOs7cdhFtXwrBmz555dSKnXNPe1QRdOhnZpOYIDYWcy0WlJ9E6zVk8SdvS3hMNKTmVP8DE1lxA==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-calendars": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-calendars/-/ej2-calendars-35.1.37.tgz",
+ "integrity": "sha512-KLYnPjinjjpHU4I4hZwJKWuMm8AYPWnnT7R/kVYQ0fMz4Vt1XrNCcOyByTvSINTDvb4sZeF6a5VTRNL6/i7Xgw==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-buttons": "~35.1.37",
+ "@syncfusion/ej2-inputs": "~35.1.37",
+ "@syncfusion/ej2-lists": "~35.1.37",
+ "@syncfusion/ej2-popups": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-charts": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-charts/-/ej2-charts-35.1.37.tgz",
+ "integrity": "sha512-q9ShJ4K7ozYRPqSpENay95eoe4ZBftHogveYTRsJTAKXCrh7tbjxJ9doeKBN+pcdqIBqcK0ecXDw4vPyxRvEtA==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-calendars": "~35.1.37",
+ "@syncfusion/ej2-data": "~35.1.37",
+ "@syncfusion/ej2-excel-export": "~35.1.37",
+ "@syncfusion/ej2-navigations": "~35.1.37",
+ "@syncfusion/ej2-pdf-export": "~35.1.37",
+ "@syncfusion/ej2-svg-base": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-collaborator": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-collaborator/-/ej2-collaborator-35.1.37.tgz",
+ "integrity": "sha512-Ff72o4M1yIw8VtjaiKyicHv7e5jr0jcL3Mak0yrvOCZoLyp4ucu5Zi5f+WHAy9qj4Tgu2WCuhzqRML8tx8G5gA==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-compression": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-compression/-/ej2-compression-35.1.37.tgz",
+ "integrity": "sha512-Lz+5N1iahYLtmyznJ9O+xTq34Mfc7PXFJna28h7PGJ7YNkZxJDLi1KijypJHj+LZfi8NAQsn7MRMnTFfbHxBmQ==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-file-utils": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-data": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-data/-/ej2-data-35.1.37.tgz",
+ "integrity": "sha512-rjHvWvwOYWCvWhptPe9ldenOKZXPXFer0v2UrbJhSfJ1oC9NxCm+HX1MrfY46SStOz93s3X8XorF2LgQlXRyRA==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-dropdowns": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-dropdowns/-/ej2-dropdowns-35.1.37.tgz",
+ "integrity": "sha512-StvzQPhuFZIQd53PAIWg7gsBiEKNMJuRueDgCNKTUoJo45fuHphShhb4RIwjnM1D6BJqQ1a/7oxeWQYxdaH/CQ==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-data": "~35.1.37",
+ "@syncfusion/ej2-inputs": "~35.1.37",
+ "@syncfusion/ej2-lists": "~35.1.37",
+ "@syncfusion/ej2-navigations": "~35.1.37",
+ "@syncfusion/ej2-notifications": "~35.1.37",
+ "@syncfusion/ej2-popups": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-excel-export": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-excel-export/-/ej2-excel-export-35.1.37.tgz",
+ "integrity": "sha512-oTjGCkiTpsx06EVbvwrwaTjORucMizuCb/AnfbjGoHVPGfZj74cchHQY+8rmY2uSRmz9nLQIGhc4Ip1JNcWDZg==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-compression": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-file-utils": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-file-utils/-/ej2-file-utils-35.1.37.tgz",
+ "integrity": "sha512-+Psm/DeB0b8DJeo63OU997bSSSL8Lj6s7tnY0CFUb1nXHmJ6pxxGLapf6MbBJYFSD+as1IWk2kFHkmWI1hu5Xg==",
+ "license": "SEE LICENSE IN license"
+ },
+ "node_modules/@syncfusion/ej2-grids": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-grids/-/ej2-grids-35.1.37.tgz",
+ "integrity": "sha512-4t3o3VsUoYCes+gIVsYTyb2jbADfMMbGmGbJdeg9D4/Vl7sfvMdM7cWAxOX87oGwxhua29hQw7+8DLZ2Wm1Agg==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-buttons": "~35.1.37",
+ "@syncfusion/ej2-calendars": "~35.1.37",
+ "@syncfusion/ej2-compression": "~35.1.37",
+ "@syncfusion/ej2-data": "~35.1.37",
+ "@syncfusion/ej2-dropdowns": "~35.1.37",
+ "@syncfusion/ej2-excel-export": "~35.1.37",
+ "@syncfusion/ej2-file-utils": "~35.1.37",
+ "@syncfusion/ej2-inputs": "~35.1.37",
+ "@syncfusion/ej2-lists": "~35.1.37",
+ "@syncfusion/ej2-navigations": "~35.1.37",
+ "@syncfusion/ej2-notifications": "~35.1.37",
+ "@syncfusion/ej2-pdf-export": "~35.1.37",
+ "@syncfusion/ej2-popups": "~35.1.37",
+ "@syncfusion/ej2-querybuilder": "~35.1.37",
+ "@syncfusion/ej2-splitbuttons": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-icons": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-icons/-/ej2-icons-35.1.37.tgz",
+ "integrity": "sha512-D7LC3O2OI2Ugc/DLShHvhoEPBEZCT9hj49PjV30CxfJ8ZyVR+EWl/GC3b1q1xMKLiB7ZhDrXBoZgq5mJaeVZuw==",
+ "license": "SEE LICENSE IN license"
+ },
+ "node_modules/@syncfusion/ej2-inputs": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-inputs/-/ej2-inputs-35.1.37.tgz",
+ "integrity": "sha512-P4NQI/MQrfAqnpMNuRsxB0GMIXXZ5EIPPIt/oZnq1gAzGbDj7HM4yz4rg6xtiae8t2nMr0QI4cggL2dDKzpfHQ==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-buttons": "~35.1.37",
+ "@syncfusion/ej2-popups": "~35.1.37",
+ "@syncfusion/ej2-splitbuttons": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-interactive-chat": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-interactive-chat/-/ej2-interactive-chat-35.1.37.tgz",
+ "integrity": "sha512-oq+h77v2DlbQBblBAfT25DKoLUMtBKiFxrlkgpDq2QqTLIhcD0XlrOXO5FKlUsLTMpmV71pZjpyNWyWc4rH+/g==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-dropdowns": "~35.1.37",
+ "@syncfusion/ej2-inputs": "~35.1.37",
+ "@syncfusion/ej2-layouts": "~35.1.37",
+ "@syncfusion/ej2-markdown-converter": "~35.1.37",
+ "@syncfusion/ej2-navigations": "~35.1.37",
+ "@syncfusion/ej2-notifications": "~35.1.37",
+ "@syncfusion/ej2-popups": "~35.1.37",
+ "@syncfusion/ej2-splitbuttons": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-layouts": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-layouts/-/ej2-layouts-35.1.37.tgz",
+ "integrity": "sha512-5yj54DPYAKLjuIA+pO3IaZryGWbqAfXRZZuyOb35cjOFHoDDeAoQ9x0ocigxUYFv/IOx/6JW3M79Fb3hx7XA8g==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-lists": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-lists/-/ej2-lists-35.1.37.tgz",
+ "integrity": "sha512-GA5cnNXA+Kpme2nDAxld7x88T1YnoMDvHidTk2CJj/Dp3mwvB2/FScaGxYjidES1Hev0XWvJtgnGPdhI95gE2Q==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-buttons": "~35.1.37",
+ "@syncfusion/ej2-data": "~35.1.37",
+ "@syncfusion/ej2-popups": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-markdown-converter": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-markdown-converter/-/ej2-markdown-converter-35.1.37.tgz",
+ "integrity": "sha512-fBtN3+1ACdXIYbzAX35gDcOTtR5VCdjW2QSWaLpO3jhh+NntOrhfM82ntxI+TOdyZYOvtNxt/pQjIp2K/UOGBA==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-navigations": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-navigations/-/ej2-navigations-35.1.37.tgz",
+ "integrity": "sha512-jqpVXZimfqfIPzCf9I7KPB47hVdiouYDnmEHIpayekQlSdMq2qZQJy59sqb8genYL4OR/KnEFJlcIp1mdhJ8Kw==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-buttons": "~35.1.37",
+ "@syncfusion/ej2-data": "~35.1.37",
+ "@syncfusion/ej2-inputs": "~35.1.37",
+ "@syncfusion/ej2-lists": "~35.1.37",
+ "@syncfusion/ej2-notifications": "~35.1.37",
+ "@syncfusion/ej2-popups": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-notifications": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-notifications/-/ej2-notifications-35.1.37.tgz",
+ "integrity": "sha512-UyjQ2Ykx8N1YrikYxrMaK9F7x/u4Ea4ZdCO8rL07binfF+lDEFlPpMoLbiQYatwb8gN++d5UbcyQXs/sYLIYfg==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-buttons": "~35.1.37",
+ "@syncfusion/ej2-popups": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-pdf-export": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-pdf-export/-/ej2-pdf-export-35.1.37.tgz",
+ "integrity": "sha512-9+2GJBe0vjs0CuIBgQQd7GcQ2CaxCh//OqNlnbGvPO4dfagEj0TUoKpbhIK9Qs5+l1KHvpSgPhQ80LuZBfyHhw==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-compression": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-popups": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-popups/-/ej2-popups-35.1.37.tgz",
+ "integrity": "sha512-HC3x/sR07YDDc/eS/iZrN0SyJkuAXDS1uRABeN6UdPdkp2o7IOkSOCAyAURMY/dHqpCDblhsnE0LXZ6HwlcQaQ==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-buttons": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-querybuilder": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-querybuilder/-/ej2-querybuilder-35.1.37.tgz",
+ "integrity": "sha512-h2xUbOt+I88ICtWRhcMrmizfX4fXU9ZfSc2cR/Umn5vSoMJE52AEAQ9iamRiMTJUFAwOyINpdfabr1pO7xngKg==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-buttons": "~35.1.37",
+ "@syncfusion/ej2-calendars": "~35.1.37",
+ "@syncfusion/ej2-dropdowns": "~35.1.37",
+ "@syncfusion/ej2-inputs": "~35.1.37",
+ "@syncfusion/ej2-splitbuttons": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-splitbuttons": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-splitbuttons/-/ej2-splitbuttons-35.1.37.tgz",
+ "integrity": "sha512-whjKUf7p9grTtDxssx4s2u9gYDysiRHBn658dj6oRMKoYAECdaw5H/WEIcqKoxA6B1hJyUHZ8GE1SbWdV7eSVw==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-popups": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-spreadsheet": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-spreadsheet/-/ej2-spreadsheet-35.1.37.tgz",
+ "integrity": "sha512-TEM28i5E17uFG37HpYLaRhpjiyq/k4KxQG6MJMTn3JroZtM2+BUvki6l847xhCdPt1Jrvg8slc0uKI28Cox3XA==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37",
+ "@syncfusion/ej2-calculate": "~35.1.37",
+ "@syncfusion/ej2-charts": "~35.1.37",
+ "@syncfusion/ej2-dropdowns": "~35.1.37",
+ "@syncfusion/ej2-grids": "~35.1.37",
+ "@syncfusion/ej2-interactive-chat": "~35.1.37",
+ "@syncfusion/ej2-navigations": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-svg-base": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-svg-base/-/ej2-svg-base-35.1.37.tgz",
+ "integrity": "sha512-jgTjelQSmDHETQfXaecRL92tw/i63ijnACZEwp97gDl+bbY8Nc/PjTvaHNjECjuOL2Nt83q4z77OnGjE2zmNJQ==",
+ "license": "SEE LICENSE IN license",
+ "dependencies": {
+ "@syncfusion/ej2-base": "~35.1.37"
+ }
+ },
+ "node_modules/@syncfusion/ej2-tailwind3-theme": {
+ "version": "35.1.37",
+ "resolved": "https://registry.npmjs.org/@syncfusion/ej2-tailwind3-theme/-/ej2-tailwind3-theme-35.1.37.tgz",
+ "integrity": "sha512-1Qujjxkeo4pH58CcBHytkqwTuZZRlFeoEfdzyfkvZGjtcg9dH2sOMYVwz6GVs4dRrtm/KJkqeBXMToCMR6bT2g==",
+ "license": "SEE LICENSE IN license"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
+ "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/abort-controller": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+ "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+ "license": "MIT",
+ "dependencies": {
+ "event-target-shim": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=6.5"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.28.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz",
+ "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.28.2",
+ "@esbuild/android-arm": "0.28.2",
+ "@esbuild/android-arm64": "0.28.2",
+ "@esbuild/android-x64": "0.28.2",
+ "@esbuild/darwin-arm64": "0.28.2",
+ "@esbuild/darwin-x64": "0.28.2",
+ "@esbuild/freebsd-arm64": "0.28.2",
+ "@esbuild/freebsd-x64": "0.28.2",
+ "@esbuild/linux-arm": "0.28.2",
+ "@esbuild/linux-arm64": "0.28.2",
+ "@esbuild/linux-ia32": "0.28.2",
+ "@esbuild/linux-loong64": "0.28.2",
+ "@esbuild/linux-mips64el": "0.28.2",
+ "@esbuild/linux-ppc64": "0.28.2",
+ "@esbuild/linux-riscv64": "0.28.2",
+ "@esbuild/linux-s390x": "0.28.2",
+ "@esbuild/linux-x64": "0.28.2",
+ "@esbuild/netbsd-arm64": "0.28.2",
+ "@esbuild/netbsd-x64": "0.28.2",
+ "@esbuild/openbsd-arm64": "0.28.2",
+ "@esbuild/openbsd-x64": "0.28.2",
+ "@esbuild/openharmony-arm64": "0.28.2",
+ "@esbuild/sunos-x64": "0.28.2",
+ "@esbuild/win32-arm64": "0.28.2",
+ "@esbuild/win32-ia32": "0.28.2",
+ "@esbuild/win32-x64": "0.28.2"
+ }
+ },
+ "node_modules/event-target-shim": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eventsource": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz",
+ "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fetch-cookie": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-2.2.0.tgz",
+ "integrity": "sha512-h9AgfjURuCgA2+2ISl8GbavpUdR+WGAM2McW/ovn4tVccegp8ZqCKWSBR8uRdM8dDNlx5WdKRWxBYUwteLDCNQ==",
+ "license": "Unlicense",
+ "dependencies": {
+ "set-cookie-parser": "^2.4.8",
+ "tough-cookie": "^4.0.0"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.20",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz",
+ "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
+ "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.29.tgz",
+ "integrity": "sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.19",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/psl": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
+ "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==",
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/lupomontero"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/querystringify": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
+ "license": "MIT"
+ },
+ "node_modules/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "license": "MIT"
+ },
+ "node_modules/rollup": {
+ "version": "4.64.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.64.0.tgz",
+ "integrity": "sha512-gjA/kFeDfffII8COoPsvLPvE16hWDTEc1+0QKQNKUkuV8iJjqsC4xXs8/FzuL0v9EV39kuxTbAgcFoTRyy2TGQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.9"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@napi-rs/lzma-linux-x64-gnu": "1.5.1",
+ "@rollup/rollup-android-arm-eabi": "4.64.0",
+ "@rollup/rollup-android-arm64": "4.64.0",
+ "@rollup/rollup-darwin-arm64": "4.64.0",
+ "@rollup/rollup-darwin-x64": "4.64.0",
+ "@rollup/rollup-freebsd-arm64": "4.64.0",
+ "@rollup/rollup-freebsd-x64": "4.64.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.64.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.64.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.64.0",
+ "@rollup/rollup-linux-arm64-musl": "4.64.0",
+ "@rollup/rollup-linux-loong64-gnu": "4.64.0",
+ "@rollup/rollup-linux-loong64-musl": "4.64.0",
+ "@rollup/rollup-linux-ppc64-gnu": "4.64.0",
+ "@rollup/rollup-linux-ppc64-musl": "4.64.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.64.0",
+ "@rollup/rollup-linux-riscv64-musl": "4.64.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.64.0",
+ "@rollup/rollup-linux-x64-gnu": "4.64.0",
+ "@rollup/rollup-linux-x64-musl": "4.64.0",
+ "@rollup/rollup-openbsd-x64": "4.64.0",
+ "@rollup/rollup-openharmony-arm64": "4.64.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.64.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.64.0",
+ "@rollup/rollup-win32-x64-gnu": "4.64.0",
+ "@rollup/rollup-win32-x64-msvc": "4.64.0",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
+ "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
+ "license": "MIT"
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz",
+ "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
+ "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
+ "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.2.0",
+ "url-parse": "^1.5.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT"
+ },
+ "node_modules/universalify": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/url-parse": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+ "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
+ "node_modules/vite": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.7.tgz",
+ "integrity": "sha512-AHEzTORMbi7/7aXp7w7KZ5+DCUdSeLsJz0grY8xHpc9DHdYb0vQu6DqJfm2tOw3gDExNgPgnJTXxM6syYFHaCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.27.0 || ^0.28.0",
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3",
+ "postcss": "^8.5.6",
+ "rollup": "^4.43.0",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "lightningcss": "^1.21.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/ws": {
+ "version": "7.5.13",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.13.tgz",
+ "integrity": "sha512-rsKI6xDBFVf4r/x8XyChGK04QR/XHroxs/jUcoWvtEZM8TPU/X/uIY9B1CsSzYws9ZJb/6bbBu7dPhFW00CAoA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ }
+ }
+}
diff --git a/client/javascript/package.json b/client/javascript/package.json
new file mode 100644
index 0000000..3b56e90
--- /dev/null
+++ b/client/javascript/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "javascript-spreadsheet-collaborative-editing",
+ "private": true,
+ "version": "1.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@microsoft/signalr": "^9.0.0",
+ "@syncfusion/ej2-collaborator": "35.1.37",
+ "@syncfusion/ej2-spreadsheet": "35.1.37",
+ "@syncfusion/ej2-tailwind3-theme": "35.1.37"
+ },
+ "devDependencies": {
+ "vite": "^7.1.9"
+ }
+}
diff --git a/client/javascript/src/index.js b/client/javascript/src/index.js
new file mode 100644
index 0000000..fab4ac7
--- /dev/null
+++ b/client/javascript/src/index.js
@@ -0,0 +1,92 @@
+import {
+ CollaborativeEditingHandler,
+ Spreadsheet
+} from '@syncfusion/ej2-spreadsheet';
+import { CollaborationClient } from '@syncfusion/ej2-collaborator';
+import { SpreadsheetEditorAdapter } from './spreadsheet-editor-adapter';
+import './style.css';
+
+const serviceUrl =
+ ''YOUR_COLLABORATION_SERVER_URL'';
+const currentUser = 'John Adams';
+
+Spreadsheet.Inject(CollaborativeEditingHandler);
+
+function getRoomName() {
+ const currentUrl = new URL(window.location.href);
+ let roomName = (
+ currentUrl.searchParams.get('id') || ''
+ ).trim();
+
+ if (!roomName) {
+ roomName = Math.random().toString(32).slice(2);
+ currentUrl.searchParams.set('id', roomName);
+ window.history.replaceState(
+ window.history.state,
+ '',
+ currentUrl.pathname + currentUrl.search + currentUrl.hash
+ );
+ }
+
+ return roomName;
+}
+
+let adapter = null;
+let collaborationClient = null;
+let initialized = false;
+
+const spreadsheet = new Spreadsheet({
+ height: '550px',
+ enableCollaborativeEditing: true,
+ created: async () => {
+ if (initialized) {
+ return;
+ }
+
+ initialized = true;
+ const roomName = getRoomName();
+ const spreadsheetAdapter = new SpreadsheetEditorAdapter(
+ spreadsheet,
+ serviceUrl,
+ currentUser
+ );
+
+ try {
+ await spreadsheetAdapter.loadFromServer(
+ 'Sample',
+ roomName
+ );
+
+ const client = new CollaborationClient(
+ spreadsheetAdapter,
+ {
+ serviceUrl,
+ connectionType: 'signalr',
+ currentUser
+ }
+ );
+
+ adapter = spreadsheetAdapter;
+ collaborationClient = client;
+ await client.joinRoomAsync(roomName);
+
+ console.log(
+ '[Collaborative Editing] Joined room',
+ roomName
+ );
+ } catch (error) {
+ initialized = false;
+ console.error(
+ '[Collaborative Editing] Failed to join the room.',
+ error
+ );
+ }
+ },
+ actionComplete: (args) => {
+ adapter?.sendActionToServer(args);
+ }
+});
+
+spreadsheet.appendTo('#spreadsheet');
+
+void collaborationClient;
diff --git a/client/javascript/src/spreadsheet-editor-adapter.js b/client/javascript/src/spreadsheet-editor-adapter.js
new file mode 100644
index 0000000..e142f54
--- /dev/null
+++ b/client/javascript/src/spreadsheet-editor-adapter.js
@@ -0,0 +1,66 @@
+export class SpreadsheetEditorAdapter {
+ constructor(spreadsheet, serviceUrl, currentUser) {
+ this.spreadsheet = spreadsheet;
+ this.serviceUrl = serviceUrl.endsWith('/')
+ ? serviceUrl
+ : serviceUrl + '/';
+ this.currentUser = currentUser;
+ this.currentRoomName = '';
+ }
+
+ async loadFromServer(fileName, roomName) {
+ const response = await fetch(
+ this.serviceUrl + 'api/CollaborativeEditing/ImportFile',
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ fileName,
+ roomName
+ })
+ }
+ );
+
+ if (!response.ok) {
+ throw new Error('Failed to load the workbook.');
+ }
+
+ const data = JSON.parse(await response.text());
+
+ this.currentRoomName = roomName;
+ this.spreadsheet.collaborativeEditingModule.updateRoomInfo(
+ roomName,
+ data.version,
+ this.serviceUrl + 'api/CollaborativeEditing/'
+ );
+ this.spreadsheet.collaborativeEditingModule.setLocalUser(
+ this.currentUser
+ );
+ this.spreadsheet.openFromJson({
+ file: data.sfdt
+ });
+ }
+
+ sendActionToServer(action) {
+ if (!action) {
+ return;
+ }
+
+ this.spreadsheet.collaborativeEditingModule.sendActionToServer(
+ action
+ );
+ }
+
+ applyRemoteAction(action, data) {
+ if (!data) {
+ return;
+ }
+
+ this.spreadsheet.collaborativeEditingModule.applyRemoteAction(
+ action,
+ data.payload
+ );
+ }
+}
diff --git a/client/javascript/src/style.css b/client/javascript/src/style.css
new file mode 100644
index 0000000..8a9a433
--- /dev/null
+++ b/client/javascript/src/style.css
@@ -0,0 +1,11 @@
+@import '@syncfusion/ej2-tailwind3-theme/styles/tailwind3.css';
+
+html,
+body {
+ height: 100%;
+ margin: 0;
+}
+
+#spreadsheet {
+ width: 100%;
+}
diff --git a/client/react/README.md b/client/react/README.md
index cc6a6e0..ec1c7ba 100644
--- a/client/react/README.md
+++ b/client/react/README.md
@@ -36,7 +36,7 @@ Open `src/App.tsx` and update the following URL when required:
```ts
const serviceUrl: string =
- 'https://appservice-267100-e9c8cxaab6a2dfeu.centralindia-01.azurewebsites.net/';
+ ''YOUR_COLLABORATION_SERVER_URL'';
```
The URL must point to the running ASP.NET Core Collaboration Server.
@@ -70,7 +70,7 @@ Copy the complete URL and open it in another browser window or tab. Clients usin
The sample uses the following participant name:
```ts
-const currentUser: string = 'John';
+const currentUser: string = 'John Adams';
```
## How the sample works
diff --git a/client/react/src/App.tsx b/client/react/src/App.tsx
index e32f1e6..d2ecabf 100644
--- a/client/react/src/App.tsx
+++ b/client/react/src/App.tsx
@@ -9,9 +9,9 @@ import { SpreadsheetEditorAdapter } from './SpreadsheetEditorAdapter';
import './App.css';
const serviceUrl: string =
- 'https://appservice-267100-e9c8cxaab6a2dfeu.centralindia-01.azurewebsites.net/';
+ ''YOUR_COLLABORATION_SERVER_URL'';
-const currentUser: string = 'John';
+const currentUser: string = 'John Adams';
function getRoomName(): string {
const currentUrl: URL = new URL(window.location.href);
diff --git a/client/typescript/src/index.ts b/client/typescript/src/index.ts
index 84b604d..2335257 100644
--- a/client/typescript/src/index.ts
+++ b/client/typescript/src/index.ts
@@ -7,8 +7,8 @@ import { SpreadsheetEditorAdapter } from './spreadsheet-editor-adapter';
import './style.css';
const serviceUrl: string =
- 'https://appservice-267100-e9c8cxaab6a2dfeu.centralindia-01.azurewebsites.net/';
-const currentUser: string = 'John';
+ ''YOUR_COLLABORATION_SERVER_URL'';
+const currentUser: string = 'John Adams';
Spreadsheet.Inject(CollaborativeEditingHandler);
diff --git a/client/vue/src/App.vue b/client/vue/src/App.vue
index 6c04bbf..bb6b0fc 100644
--- a/client/vue/src/App.vue
+++ b/client/vue/src/App.vue
@@ -11,8 +11,8 @@ import { CollaborationClient } from '@syncfusion/ej2-collaborator';
import { SpreadsheetEditorAdapter } from './SpreadsheetEditorAdapter';
const serviceUrl: string =
- 'https://appservice-267100-e9c8cxaab6a2dfeu.centralindia-01.azurewebsites.net/';
-const currentUser: string = 'John';
+ ''YOUR_COLLABORATION_SERVER_URL'';
+const currentUser: string = 'John Adams';
provide('spreadsheet', [CollaborativeEditingHandler]);
diff --git a/server/aspnet-core/README.md b/server/aspnet-core/README.md
new file mode 100644
index 0000000..4db6e8c
--- /dev/null
+++ b/server/aspnet-core/README.md
@@ -0,0 +1,225 @@
+# ASP.NET Core Spreadsheet Collaboration Server
+
+This project provides the ASP.NET Core Collaboration Server for real-time collaborative editing in the Syncfusion® Spreadsheet. It uses SignalR for real-time communication and Redis to maintain collaboration operations and room state.
+
+## Prerequisites
+
+Before running the server, ensure that the following are available:
+
+- .NET 10.0 SDK
+- Redis Server or a hosted Redis service
+- The `wwwroot/Files/Sample.xlsx` workbook
+
+## Configure the Redis connection
+
+Open `appsettings.json` and replace the Redis connection-string placeholder:
+
+```json
+{
+ "ConnectionStrings": {
+ "Redis": "Your_Connection_string"
+ }
+}
+```
+
+For a local Redis instance, the value can be similar to:
+
+```json
+{
+ "ConnectionStrings": {
+ "Redis": "localhost:6379"
+ }
+}
+```
+
+## Register the Syncfusion license key
+
+The server reads the Syncfusion license key from either a local license file or an environment variable.
+
+### Option 1: License file
+
+Create a `SyncfusionLicense.txt` file in the project root and add the license key as its content.
+
+```text
+YOUR_SYNCFUSION_LICENSE_KEY
+```
+
+### Option 2: Environment variable
+
+Set the `SYNCFUSION_LICENSE_KEY` environment variable before running the server.
+
+Windows Command Prompt:
+
+```cmd
+set SYNCFUSION_LICENSE_KEY=YOUR_SYNCFUSION_LICENSE_KEY
+```
+
+Windows PowerShell:
+
+```powershell
+$env:SYNCFUSION_LICENSE_KEY="YOUR_SYNCFUSION_LICENSE_KEY"
+```
+
+Linux or macOS:
+
+```bash
+export SYNCFUSION_LICENSE_KEY=YOUR_SYNCFUSION_LICENSE_KEY
+```
+
+## Source workbook
+
+The collaboration sample loads the source workbook from:
+
+```text
+wwwroot/Files/Sample.xlsx
+```
+
+Ensure that `Sample.xlsx` exists at this location before starting the server.
+
+## Run the server
+
+Navigate to the ASP.NET Core server folder:
+
+```bash
+cd server/aspnet-core
+```
+
+Restore the required packages:
+
+```bash
+dotnet restore
+```
+
+Run the server:
+
+```bash
+dotnet run
+```
+
+The development profile uses the following URLs:
+
+```text
+https://localhost:7002
+http://localhost:5209
+```
+
+Use one of these URLs as the Collaboration Server URL in the client applications.
+
+For example:
+
+```ts
+const serviceUrl: string = 'https://localhost:7002/';
+```
+
+## Collaboration endpoints
+
+The server exposes the following Spreadsheet collaboration endpoints under:
+
+```text
+api/CollaborativeEditing
+```
+
+- `POST /ImportFile` loads the source workbook, applies pending room operations, and returns the synchronized workbook and version.
+- `POST /UpdateAction` stores and broadcasts a Spreadsheet action.
+- `POST /UpdateSelection` updates and broadcasts a participant's selection.
+- `GET /GetRoomSelections/{roomName}` returns the active selections for a collaboration room.
+- `POST /RemoveUserSelection` removes a disconnected participant's selection.
+- `POST /GetActionsFromServer` returns actions newer than the client's last synchronized version.
+
+The collaboration transport endpoint is registered through `MapCollaborationServer` and uses SignalR.
+
+## Spreadsheet endpoints
+
+The server also provides the following standard Spreadsheet endpoints:
+
+```text
+POST /api/Spreadsheet/Open
+POST /api/Spreadsheet/Save
+```
+
+These endpoints support opening and saving Spreadsheet files.
+
+## CORS
+
+The server uses the `AllowAllOrigins` CORS policy so that the client samples can access the collaboration and Spreadsheet endpoints during development.
+
+## Test collaborative editing
+
+1. Start Redis.
+2. Run the ASP.NET Core server using `dotnet run`.
+3. Configure a client sample with the displayed server URL.
+4. Start the client application.
+5. Open the complete client URL, including the `id` query parameter, in two browser tabs or windows.
+6. Edit a cell and verify that the supported change is synchronized between both clients.
+
+## Project structure
+
+```text
+server/aspnet-core/
+|-- Adapters/
+| `-- SpreadsheetCollaborativeAdaptor.cs
+|-- Controllers/
+| |-- CollaborativeEditingController.cs
+| |-- SpreadsheetController.cs
+| `-- TestController.cs
+|-- Properties/
+| `-- launchSettings.json
+|-- wwwroot/
+| `-- Files/
+| `-- Sample.xlsx
+|-- appsettings.Development.json
+|-- appsettings.json
+|-- ej2-spreadsheet-server.csproj
+|-- ej2-spreadsheet-server.sln
+|-- NuGet.Config
+|-- Program.cs
+|-- SyncfusionLicense.txt
+|-- web.config
+`-- README.md
+```
+
+## Troubleshooting
+
+### Redis connection failure
+
+Verify that Redis is running and that the `Redis` value in `appsettings.json` contains a valid connection string.
+
+### Workbook does not load
+
+Verify that the following file exists:
+
+```text
+wwwroot/Files/Sample.xlsx
+```
+
+Also confirm that the browser Network panel does not show an error for:
+
+```text
+api/CollaborativeEditing/ImportFile
+```
+
+### Client cannot connect to the collaboration room
+
+Verify that:
+
+- The ASP.NET Core server is running.
+- The client uses the correct server URL.
+- The client and server use SignalR.
+- The browser accepts the local HTTPS development certificate.
+- The browser console does not contain SignalR or network errors.
+
+### Syncfusion license warning
+
+Ensure that a valid license key is available through `SyncfusionLicense.txt` or the `SYNCFUSION_LICENSE_KEY` environment variable.
+
+### Package restore failure
+
+Confirm that the package sources configured in `NuGet.Config` are accessible, and then run:
+
+```bash
+dotnet restore
+```
+
+## License
+
+This project is licensed under the terms specified in the repository's license file. Syncfusion® packages are subject to the applicable Syncfusion license terms.