YC-Chen commited on
Commit
71f66a5
·
1 Parent(s): 5257c03

breaking change: new structure

Browse files
.dockerignore CHANGED
@@ -7,11 +7,6 @@ tests
7
  *.test.js
8
  .eslintrc.js
9
 
10
- # Router
11
- router/node_modules
12
- router/.env
13
- router/*.log
14
-
15
  # Environment files
16
  .env
17
  .env.local
 
7
  *.test.js
8
  .eslintrc.js
9
 
 
 
 
 
 
10
  # Environment files
11
  .env
12
  .env.local
.env.sample CHANGED
@@ -2,6 +2,6 @@
2
  # Copy this file to .env and modify the values
3
 
4
  # Target Backend Server Configuration
5
- TARGET_HOST=your-backend-server.com
6
- TARGET_PORT=8000
7
- TARGET_WS_PATH=/ws/orchestrator
 
2
  # Copy this file to .env and modify the values
3
 
4
  # Target Backend Server Configuration
5
+ BACKEND_HOST=your-backend-server.com
6
+ BACKEND_PORT=8000
7
+ BACKEND_WS_PATH=/ws/orchestrator
DOCKER_USAGE.md DELETED
@@ -1,158 +0,0 @@
1
- # Docker Usage Guide
2
-
3
- This project includes a Frontend Server and WebSocket Proxy Server that can be deployed together using Docker.
4
-
5
- ## Architecture
6
-
7
- ```
8
- Docker Container
9
- ├── Frontend Server (Port 3000)
10
- │ └── Serves static web interface
11
- └── WebSocket Proxy Server (Port 8000)
12
- └── Forwards WebSocket connections to backend
13
- ```
14
-
15
- ## Environment Configuration
16
-
17
- Before starting Docker, configure the target backend server. There are two options:
18
-
19
- ### Option 1: Using Environment File
20
-
21
- Create `router/.env`:
22
-
23
- ```bash
24
- cp router/.env.sample router/.env
25
- ```
26
-
27
- Edit `router/.env`:
28
-
29
- ```env
30
- PROXY_PORT=8000
31
- TARGET_HOST=your-backend-server.com
32
- TARGET_PORT=8000
33
- TARGET_WS_PATH=/ws/orchestrator
34
- ```
35
-
36
- ### Option 2: Using Command-line Environment Variables
37
-
38
- Pass environment variables when running Docker (see below).
39
-
40
- ## Build Docker Image
41
-
42
- ```bash
43
- docker build -t chattaste-voice-bot .
44
- ```
45
-
46
- ## Run Docker Container
47
-
48
- ### Using .env File
49
-
50
- ```bash
51
- docker run -d \
52
- -p 3000:3000 \
53
- -p 8000:8000 \
54
- --name chattaste-bot \
55
- chattaste-voice-bot
56
- ```
57
-
58
- ### Using Command-line Environment Variables
59
-
60
- ```bash
61
- docker run -d \
62
- -p 3000:3000 \
63
- -p 8000:8000 \
64
- -e TARGET_HOST=your-backend-server.com \
65
- -e TARGET_PORT=8000 \
66
- -e TARGET_WS_PATH=/ws/orchestrator \
67
- --name chattaste-bot \
68
- chattaste-voice-bot
69
- ```
70
-
71
- ## View Service Status
72
-
73
- ```bash
74
- # View container logs
75
- docker logs chattaste-bot
76
-
77
- # View live logs
78
- docker logs -f chattaste-bot
79
-
80
- # Check container status
81
- docker ps
82
- ```
83
-
84
- ## Stop and Remove Container
85
-
86
- ```bash
87
- # Stop container
88
- docker stop chattaste-bot
89
-
90
- # Remove container
91
- docker rm chattaste-bot
92
- ```
93
-
94
- ## Test Connection
95
-
96
- 1. Open browser: `http://localhost:3000`
97
- 2. Frontend connects to `ws://localhost:8000/ws/orchestrator`
98
- 3. Proxy server forwards to configured target server
99
-
100
- ## Troubleshooting
101
-
102
- ### Verify Proxy Server is Running
103
-
104
- ```bash
105
- docker logs chattaste-bot | grep "Proxy server"
106
- ```
107
-
108
- Expected output:
109
- ```
110
- ✓ Proxy server is listening on port 8000
111
- ```
112
-
113
- ### Cannot Connect to Target Server
114
-
115
- Check environment variables:
116
-
117
- ```bash
118
- docker exec chattaste-bot env | grep TARGET
119
- ```
120
-
121
- ### Restart Services
122
-
123
- ```bash
124
- docker restart chattaste-bot
125
- ```
126
-
127
- ## Docker Compose (Recommended)
128
-
129
- For easier management, use Docker Compose with `docker-compose.yml`:
130
-
131
- ```yaml
132
- version: '3.8'
133
-
134
- services:
135
- chattaste-bot:
136
- build: .
137
- ports:
138
- - "3000:3000"
139
- - "8000:8000"
140
- environment:
141
- - TARGET_HOST=your-backend-server.com
142
- - TARGET_PORT=8000
143
- - TARGET_WS_PATH=/ws/orchestrator
144
- restart: unless-stopped
145
- ```
146
-
147
- Usage:
148
-
149
- ```bash
150
- # Start services
151
- docker-compose up -d
152
-
153
- # View logs
154
- docker-compose logs -f
155
-
156
- # Stop services
157
- docker-compose down
158
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Dockerfile CHANGED
@@ -10,24 +10,15 @@ WORKDIR /app
10
  COPY frontend/package*.json ./frontend/
11
  RUN cd frontend && npm install --include=dev
12
 
13
- # Copy and install router dependencies
14
- COPY router/package*.json ./router/
15
- RUN cd router && npm install
16
-
17
  # Copy application files
18
  COPY frontend/. ./frontend/
19
- COPY router/. ./router/
20
 
21
  # Copy startup script
22
- COPY start.sh /app/start.sh
23
- RUN chmod +x /app/start.sh
24
 
25
  # Expose ports
26
- EXPOSE 3000 8000
27
-
28
- # Enable logging output
29
- ENV NODE_ENV=production
30
- ENV LOG_LEVEL=info
31
 
32
  # Start both frontend and router
33
- CMD ["/app/start.sh"]
 
10
  COPY frontend/package*.json ./frontend/
11
  RUN cd frontend && npm install --include=dev
12
 
 
 
 
 
13
  # Copy application files
14
  COPY frontend/. ./frontend/
 
15
 
16
  # Copy startup script
17
+ COPY run_frontend.sh /app/run_frontend.sh
18
+ RUN chmod +x /app/run_frontend.sh
19
 
20
  # Expose ports
21
+ EXPOSE 3000
 
 
 
 
22
 
23
  # Start both frontend and router
24
+ CMD ["/app/run_frontend.sh"]
README.md CHANGED
@@ -10,56 +10,3 @@ app_port: 3000
10
 
11
  # ChatTASTE Voice Bot
12
 
13
- WebSocket-based voice bot frontend with integrated proxy server.
14
-
15
- ## Architecture
16
-
17
- - **Frontend Server** (Port 3000): Static web interface
18
- - **WebSocket Proxy Server** (Port 8000): Forwards WebSocket connections to backend TASTE service
19
-
20
- ## Quick Start
21
-
22
- ### Using Docker Compose (Recommended)
23
-
24
- 1. Configure environment variables:
25
- ```bash
26
- cp .env.sample .env
27
- # Edit .env to set your target backend server
28
- ```
29
-
30
- 2. Start services:
31
- ```bash
32
- docker-compose up -d
33
- ```
34
-
35
- 3. Access the web interface:
36
- ```
37
- http://localhost:3000
38
- ```
39
-
40
- ### Using Docker
41
-
42
- For detailed instructions, see [DOCKER_USAGE.md](./DOCKER_USAGE.md)
43
-
44
- ## Project Structure
45
-
46
- ```
47
- .
48
- ├── frontend/ # Frontend static web files
49
- ├── router/ # WebSocket Proxy Server
50
- ├── Dockerfile # Docker image definition
51
- ├── docker-compose.yml # Docker Compose configuration
52
- └── start.sh # Service startup script
53
- ```
54
-
55
- ## Development
56
-
57
- ### Frontend Development
58
- See `frontend/README.md`
59
-
60
- ### Proxy Server Development
61
- See `router/README.md`
62
-
63
- ---
64
-
65
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
10
 
11
  # ChatTASTE Voice Bot
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docker-compose.yml DELETED
@@ -1,16 +0,0 @@
1
- version: '3.8'
2
-
3
- services:
4
- chattaste-bot:
5
- build: .
6
- container_name: chattaste-bot
7
- ports:
8
- - "3000:3000"
9
- - "8000:8000"
10
- environment:
11
- # WebSocket Proxy 設定
12
- - PROXY_PORT=8000
13
- - TARGET_HOST=${TARGET_HOST:-localhost}
14
- - TARGET_PORT=${TARGET_PORT:-8001}
15
- - TARGET_WS_PATH=${TARGET_WS_PATH:-/ws/orchestrator}
16
- restart: unless-stopped
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/js/config.js CHANGED
@@ -3,10 +3,6 @@
3
  */
4
 
5
  export const CONFIG = {
6
- // Server
7
- host: 'localhost',
8
- port: 8000,
9
-
10
  // Audio
11
  micSampleRate: 16000,
12
  agentSampleRate: 24000,
 
3
  */
4
 
5
  export const CONFIG = {
 
 
 
 
6
  // Audio
7
  micSampleRate: 16000,
8
  agentSampleRate: 24000,
frontend/js/main.js CHANGED
@@ -10,7 +10,7 @@ import CONFIG from './config.js';
10
  class TasteVoiceBotApp {
11
  constructor() {
12
  // Orchestrator client and audio manager
13
- this.orchestratorClient = new OrchestratorClient('localhost', 8000);
14
  this.audioManager = new AudioManager();
15
 
16
  // State
 
10
  class TasteVoiceBotApp {
11
  constructor() {
12
  // Orchestrator client and audio manager
13
+ this.orchestratorClient = new OrchestratorClient();
14
  this.audioManager = new AudioManager();
15
 
16
  // State
frontend/js/orchestrator-client.js CHANGED
@@ -25,9 +25,7 @@ import CONFIG from './config.js';
25
  const { AudioChunk, AgentResponse, TokenChunk, Role } = tastebot.simple;
26
 
27
  export class OrchestratorClient {
28
- constructor(host = 'localhost', port = 8000) {
29
- this.host = host;
30
- this.port = port;
31
  this.ws = null;
32
  this.isConnected = false;
33
 
@@ -65,11 +63,14 @@ export class OrchestratorClient {
65
 
66
  /**
67
  * Connect to Orchestrator WebSocket endpoint
 
68
  */
69
  async connect() {
70
  return new Promise((resolve, reject) => {
71
  try {
72
- const url = `ws://${this.host}:${this.port}/ws/orchestrator`;
 
 
73
  console.log('Connecting to orchestrator:', url);
74
 
75
  this.ws = new WebSocket(url);
 
25
  const { AudioChunk, AgentResponse, TokenChunk, Role } = tastebot.simple;
26
 
27
  export class OrchestratorClient {
28
+ constructor() {
 
 
29
  this.ws = null;
30
  this.isConnected = false;
31
 
 
63
 
64
  /**
65
  * Connect to Orchestrator WebSocket endpoint
66
+ * Uses same-origin WebSocket connection (proxied to backend by Express server)
67
  */
68
  async connect() {
69
  return new Promise((resolve, reject) => {
70
  try {
71
+ // Use same-origin connection - protocol and host from window.location
72
+ const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
73
+ const url = `${protocol}//${window.location.host}/ws/orchestrator`;
74
  console.log('Connecting to orchestrator:', url);
75
 
76
  this.ws = new WebSocket(url);
frontend/package-lock.json CHANGED
@@ -9,6 +9,8 @@
9
  "version": "1.0.0",
10
  "license": "MIT",
11
  "dependencies": {
 
 
12
  "protobufjs": "^7.5.4",
13
  "protobufjs-cli": "^1.1.3"
14
  },
@@ -2580,6 +2582,15 @@
2580
  "@types/node": "*"
2581
  }
2582
  },
 
 
 
 
 
 
 
 
 
2583
  "node_modules/@types/istanbul-lib-coverage": {
2584
  "version": "2.0.6",
2585
  "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
@@ -2925,6 +2936,19 @@
2925
  "dev": true,
2926
  "license": "BSD-3-Clause"
2927
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
2928
  "node_modules/acorn": {
2929
  "version": "8.15.0",
2930
  "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
@@ -3129,6 +3153,12 @@
3129
  "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
3130
  "license": "Python-2.0"
3131
  },
 
 
 
 
 
 
3132
  "node_modules/async": {
3133
  "version": "3.2.6",
3134
  "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
@@ -3354,6 +3384,57 @@
3354
  "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
3355
  "license": "MIT"
3356
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3357
  "node_modules/brace-expansion": {
3358
  "version": "1.1.12",
3359
  "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
@@ -3369,7 +3450,6 @@
3369
  "version": "3.0.3",
3370
  "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
3371
  "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
3372
- "dev": true,
3373
  "license": "MIT",
3374
  "dependencies": {
3375
  "fill-range": "^7.1.1"
@@ -3429,11 +3509,19 @@
3429
  "dev": true,
3430
  "license": "MIT"
3431
  },
 
 
 
 
 
 
 
 
 
3432
  "node_modules/call-bind-apply-helpers": {
3433
  "version": "1.0.2",
3434
  "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
3435
  "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
3436
- "dev": true,
3437
  "license": "MIT",
3438
  "dependencies": {
3439
  "es-errors": "^1.3.0",
@@ -3447,7 +3535,6 @@
3447
  "version": "1.0.4",
3448
  "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
3449
  "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
3450
- "dev": true,
3451
  "license": "MIT",
3452
  "dependencies": {
3453
  "call-bind-apply-helpers": "^1.0.2",
@@ -3679,6 +3766,47 @@
3679
  "dev": true,
3680
  "license": "MIT"
3681
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3682
  "node_modules/convert-source-map": {
3683
  "version": "2.0.0",
3684
  "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -3686,6 +3814,21 @@
3686
  "dev": true,
3687
  "license": "MIT"
3688
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3689
  "node_modules/core-js-compat": {
3690
  "version": "3.45.1",
3691
  "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz",
@@ -3855,6 +3998,25 @@
3855
  "node": ">=0.4.0"
3856
  }
3857
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3858
  "node_modules/detect-newline": {
3859
  "version": "3.1.0",
3860
  "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
@@ -3906,7 +4068,6 @@
3906
  "version": "1.0.1",
3907
  "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
3908
  "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
3909
- "dev": true,
3910
  "license": "MIT",
3911
  "dependencies": {
3912
  "call-bind-apply-helpers": "^1.0.1",
@@ -3917,6 +4078,12 @@
3917
  "node": ">= 0.4"
3918
  }
3919
  },
 
 
 
 
 
 
3920
  "node_modules/electron-to-chromium": {
3921
  "version": "1.5.224",
3922
  "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.224.tgz",
@@ -3944,6 +4111,15 @@
3944
  "dev": true,
3945
  "license": "MIT"
3946
  },
 
 
 
 
 
 
 
 
 
3947
  "node_modules/enhanced-resolve": {
3948
  "version": "5.18.3",
3949
  "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
@@ -3998,7 +4174,6 @@
3998
  "version": "1.0.1",
3999
  "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
4000
  "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
4001
- "dev": true,
4002
  "license": "MIT",
4003
  "engines": {
4004
  "node": ">= 0.4"
@@ -4008,7 +4183,6 @@
4008
  "version": "1.3.0",
4009
  "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
4010
  "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
4011
- "dev": true,
4012
  "license": "MIT",
4013
  "engines": {
4014
  "node": ">= 0.4"
@@ -4025,7 +4199,6 @@
4025
  "version": "1.1.1",
4026
  "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
4027
  "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
4028
- "dev": true,
4029
  "license": "MIT",
4030
  "dependencies": {
4031
  "es-errors": "^1.3.0"
@@ -4060,6 +4233,12 @@
4060
  "node": ">=6"
4061
  }
4062
  },
 
 
 
 
 
 
4063
  "node_modules/escape-string-regexp": {
4064
  "version": "4.0.0",
4065
  "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
@@ -4255,11 +4434,19 @@
4255
  "node": ">=0.10.0"
4256
  }
4257
  },
 
 
 
 
 
 
 
 
 
4258
  "node_modules/eventemitter3": {
4259
  "version": "4.0.7",
4260
  "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
4261
  "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
4262
- "dev": true,
4263
  "license": "MIT"
4264
  },
4265
  "node_modules/events": {
@@ -4322,6 +4509,87 @@
4322
  "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
4323
  }
4324
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4325
  "node_modules/fast-deep-equal": {
4326
  "version": "3.1.3",
4327
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -4406,7 +4674,6 @@
4406
  "version": "7.1.1",
4407
  "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
4408
  "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
4409
- "dev": true,
4410
  "license": "MIT",
4411
  "dependencies": {
4412
  "to-regex-range": "^5.0.1"
@@ -4415,6 +4682,39 @@
4415
  "node": ">=8"
4416
  }
4417
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4418
  "node_modules/find-cache-dir": {
4419
  "version": "4.0.0",
4420
  "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz",
@@ -4485,7 +4785,6 @@
4485
  "version": "1.15.11",
4486
  "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
4487
  "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
4488
- "dev": true,
4489
  "funding": [
4490
  {
4491
  "type": "individual",
@@ -4519,6 +4818,24 @@
4519
  "node": ">= 6"
4520
  }
4521
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4522
  "node_modules/fs.realpath": {
4523
  "version": "1.0.0",
4524
  "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -4544,7 +4861,6 @@
4544
  "version": "1.1.2",
4545
  "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
4546
  "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
4547
- "dev": true,
4548
  "license": "MIT",
4549
  "funding": {
4550
  "url": "https://github.com/sponsors/ljharb"
@@ -4574,7 +4890,6 @@
4574
  "version": "1.3.0",
4575
  "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
4576
  "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
4577
- "dev": true,
4578
  "license": "MIT",
4579
  "dependencies": {
4580
  "call-bind-apply-helpers": "^1.0.2",
@@ -4609,7 +4924,6 @@
4609
  "version": "1.0.1",
4610
  "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
4611
  "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
4612
- "dev": true,
4613
  "license": "MIT",
4614
  "dependencies": {
4615
  "dunder-proto": "^1.0.1",
@@ -4694,7 +5008,6 @@
4694
  "version": "1.2.0",
4695
  "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
4696
  "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
4697
- "dev": true,
4698
  "license": "MIT",
4699
  "engines": {
4700
  "node": ">= 0.4"
@@ -4729,7 +5042,6 @@
4729
  "version": "1.1.0",
4730
  "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
4731
  "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
4732
- "dev": true,
4733
  "license": "MIT",
4734
  "engines": {
4735
  "node": ">= 0.4"
@@ -4758,7 +5070,6 @@
4758
  "version": "2.0.2",
4759
  "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
4760
  "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
4761
- "dev": true,
4762
  "license": "MIT",
4763
  "dependencies": {
4764
  "function-bind": "^1.1.2"
@@ -4797,11 +5108,30 @@
4797
  "dev": true,
4798
  "license": "MIT"
4799
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4800
  "node_modules/http-proxy": {
4801
  "version": "1.18.1",
4802
  "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
4803
  "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
4804
- "dev": true,
4805
  "license": "MIT",
4806
  "dependencies": {
4807
  "eventemitter3": "^4.0.0",
@@ -4827,6 +5157,30 @@
4827
  "node": ">= 6"
4828
  }
4829
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4830
  "node_modules/http-server": {
4831
  "version": "14.1.1",
4832
  "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
@@ -5045,6 +5399,15 @@
5045
  "node": ">=10.13.0"
5046
  }
5047
  },
 
 
 
 
 
 
 
 
 
5048
  "node_modules/is-arrayish": {
5049
  "version": "0.2.1",
5050
  "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
@@ -5072,7 +5435,6 @@
5072
  "version": "2.1.1",
5073
  "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
5074
  "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
5075
- "dev": true,
5076
  "license": "MIT",
5077
  "engines": {
5078
  "node": ">=0.10.0"
@@ -5102,7 +5464,6 @@
5102
  "version": "4.0.3",
5103
  "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
5104
  "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
5105
- "dev": true,
5106
  "license": "MIT",
5107
  "dependencies": {
5108
  "is-extglob": "^2.1.1"
@@ -5115,7 +5476,6 @@
5115
  "version": "7.0.0",
5116
  "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
5117
  "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
5118
- "dev": true,
5119
  "license": "MIT",
5120
  "engines": {
5121
  "node": ">=0.12.0"
@@ -5131,6 +5491,18 @@
5131
  "node": ">=8"
5132
  }
5133
  },
 
 
 
 
 
 
 
 
 
 
 
 
5134
  "node_modules/is-plain-object": {
5135
  "version": "2.0.4",
5136
  "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@@ -6291,7 +6663,6 @@
6291
  "version": "1.1.0",
6292
  "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
6293
  "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
6294
- "dev": true,
6295
  "license": "MIT",
6296
  "engines": {
6297
  "node": ">= 0.4"
@@ -6303,6 +6674,24 @@
6303
  "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
6304
  "license": "MIT"
6305
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6306
  "node_modules/merge-stream": {
6307
  "version": "2.0.0",
6308
  "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -6310,11 +6699,19 @@
6310
  "dev": true,
6311
  "license": "MIT"
6312
  },
 
 
 
 
 
 
 
 
 
6313
  "node_modules/micromatch": {
6314
  "version": "4.0.8",
6315
  "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
6316
  "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
6317
- "dev": true,
6318
  "license": "MIT",
6319
  "dependencies": {
6320
  "braces": "^3.0.3",
@@ -6328,7 +6725,6 @@
6328
  "version": "1.6.0",
6329
  "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
6330
  "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
6331
- "dev": true,
6332
  "license": "MIT",
6333
  "bin": {
6334
  "mime": "cli.js"
@@ -6341,7 +6737,6 @@
6341
  "version": "1.52.0",
6342
  "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
6343
  "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
6344
- "dev": true,
6345
  "license": "MIT",
6346
  "engines": {
6347
  "node": ">= 0.6"
@@ -6351,7 +6746,6 @@
6351
  "version": "2.1.35",
6352
  "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
6353
  "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
6354
- "dev": true,
6355
  "license": "MIT",
6356
  "dependencies": {
6357
  "mime-db": "1.52.0"
@@ -6408,7 +6802,6 @@
6408
  "version": "2.1.3",
6409
  "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
6410
  "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
6411
- "dev": true,
6412
  "license": "MIT"
6413
  },
6414
  "node_modules/natural-compare": {
@@ -6418,6 +6811,15 @@
6418
  "dev": true,
6419
  "license": "MIT"
6420
  },
 
 
 
 
 
 
 
 
 
6421
  "node_modules/neo-async": {
6422
  "version": "2.6.2",
6423
  "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
@@ -6473,7 +6875,6 @@
6473
  "version": "1.13.4",
6474
  "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
6475
  "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
6476
- "dev": true,
6477
  "license": "MIT",
6478
  "engines": {
6479
  "node": ">= 0.4"
@@ -6482,6 +6883,18 @@
6482
  "url": "https://github.com/sponsors/ljharb"
6483
  }
6484
  },
 
 
 
 
 
 
 
 
 
 
 
 
6485
  "node_modules/once": {
6486
  "version": "1.4.0",
6487
  "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -6622,6 +7035,15 @@
6622
  "url": "https://github.com/inikulin/parse5?sponsor=1"
6623
  }
6624
  },
 
 
 
 
 
 
 
 
 
6625
  "node_modules/path-exists": {
6626
  "version": "4.0.0",
6627
  "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -6659,6 +7081,12 @@
6659
  "dev": true,
6660
  "license": "MIT"
6661
  },
 
 
 
 
 
 
6662
  "node_modules/picocolors": {
6663
  "version": "1.1.1",
6664
  "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -6670,7 +7098,6 @@
6670
  "version": "2.3.1",
6671
  "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
6672
  "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
6673
- "dev": true,
6674
  "license": "MIT",
6675
  "engines": {
6676
  "node": ">=8.6"
@@ -7045,6 +7472,19 @@
7045
  "node": ">= 0.8.0"
7046
  }
7047
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
7048
  "node_modules/psl": {
7049
  "version": "1.15.0",
7050
  "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
@@ -7098,7 +7538,6 @@
7098
  "version": "6.14.0",
7099
  "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
7100
  "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
7101
- "dev": true,
7102
  "license": "BSD-3-Clause",
7103
  "dependencies": {
7104
  "side-channel": "^1.1.0"
@@ -7148,6 +7587,42 @@
7148
  "safe-buffer": "^5.1.0"
7149
  }
7150
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7151
  "node_modules/react-is": {
7152
  "version": "18.3.1",
7153
  "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
@@ -7250,7 +7725,6 @@
7250
  "version": "1.0.0",
7251
  "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
7252
  "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
7253
- "dev": true,
7254
  "license": "MIT"
7255
  },
7256
  "node_modules/requizzle": {
@@ -7389,7 +7863,6 @@
7389
  "version": "2.1.2",
7390
  "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
7391
  "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
7392
- "dev": true,
7393
  "license": "MIT"
7394
  },
7395
  "node_modules/saxes": {
@@ -7479,6 +7952,45 @@
7479
  "semver": "bin/semver.js"
7480
  }
7481
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7482
  "node_modules/serialize-javascript": {
7483
  "version": "6.0.2",
7484
  "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
@@ -7489,6 +8001,27 @@
7489
  "randombytes": "^2.1.0"
7490
  }
7491
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7492
  "node_modules/shallow-clone": {
7493
  "version": "3.0.1",
7494
  "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
@@ -7529,7 +8062,6 @@
7529
  "version": "1.1.0",
7530
  "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
7531
  "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
7532
- "dev": true,
7533
  "license": "MIT",
7534
  "dependencies": {
7535
  "es-errors": "^1.3.0",
@@ -7549,7 +8081,6 @@
7549
  "version": "1.0.0",
7550
  "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
7551
  "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
7552
- "dev": true,
7553
  "license": "MIT",
7554
  "dependencies": {
7555
  "es-errors": "^1.3.0",
@@ -7566,7 +8097,6 @@
7566
  "version": "1.0.1",
7567
  "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
7568
  "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
7569
- "dev": true,
7570
  "license": "MIT",
7571
  "dependencies": {
7572
  "call-bound": "^1.0.2",
@@ -7585,7 +8115,6 @@
7585
  "version": "1.0.2",
7586
  "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
7587
  "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
7588
- "dev": true,
7589
  "license": "MIT",
7590
  "dependencies": {
7591
  "call-bound": "^1.0.2",
@@ -7676,6 +8205,15 @@
7676
  "node": ">=8"
7677
  }
7678
  },
 
 
 
 
 
 
 
 
 
7679
  "node_modules/string-length": {
7680
  "version": "4.0.2",
7681
  "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
@@ -7934,7 +8472,6 @@
7934
  "version": "5.0.1",
7935
  "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
7936
  "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
7937
- "dev": true,
7938
  "license": "MIT",
7939
  "dependencies": {
7940
  "is-number": "^7.0.0"
@@ -7943,6 +8480,15 @@
7943
  "node": ">=8.0"
7944
  }
7945
  },
 
 
 
 
 
 
 
 
 
7946
  "node_modules/tough-cookie": {
7947
  "version": "4.1.4",
7948
  "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
@@ -8008,6 +8554,19 @@
8008
  "url": "https://github.com/sponsors/sindresorhus"
8009
  }
8010
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
8011
  "node_modules/uc.micro": {
8012
  "version": "2.1.0",
8013
  "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
@@ -8104,6 +8663,15 @@
8104
  "node": ">= 4.0.0"
8105
  }
8106
  },
 
 
 
 
 
 
 
 
 
8107
  "node_modules/update-browserslist-db": {
8108
  "version": "1.1.3",
8109
  "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
@@ -8163,6 +8731,15 @@
8163
  "requires-port": "^1.0.0"
8164
  }
8165
  },
 
 
 
 
 
 
 
 
 
8166
  "node_modules/v8-to-istanbul": {
8167
  "version": "9.3.0",
8168
  "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
@@ -8178,6 +8755,15 @@
8178
  "node": ">=10.12.0"
8179
  }
8180
  },
 
 
 
 
 
 
 
 
 
8181
  "node_modules/w3c-xmlserializer": {
8182
  "version": "4.0.0",
8183
  "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
 
9
  "version": "1.0.0",
10
  "license": "MIT",
11
  "dependencies": {
12
+ "express": "^4.18.2",
13
+ "http-proxy-middleware": "^2.0.6",
14
  "protobufjs": "^7.5.4",
15
  "protobufjs-cli": "^1.1.3"
16
  },
 
2582
  "@types/node": "*"
2583
  }
2584
  },
2585
+ "node_modules/@types/http-proxy": {
2586
+ "version": "1.17.17",
2587
+ "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz",
2588
+ "integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==",
2589
+ "license": "MIT",
2590
+ "dependencies": {
2591
+ "@types/node": "*"
2592
+ }
2593
+ },
2594
  "node_modules/@types/istanbul-lib-coverage": {
2595
  "version": "2.0.6",
2596
  "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
 
2936
  "dev": true,
2937
  "license": "BSD-3-Clause"
2938
  },
2939
+ "node_modules/accepts": {
2940
+ "version": "1.3.8",
2941
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
2942
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
2943
+ "license": "MIT",
2944
+ "dependencies": {
2945
+ "mime-types": "~2.1.34",
2946
+ "negotiator": "0.6.3"
2947
+ },
2948
+ "engines": {
2949
+ "node": ">= 0.6"
2950
+ }
2951
+ },
2952
  "node_modules/acorn": {
2953
  "version": "8.15.0",
2954
  "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
 
3153
  "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
3154
  "license": "Python-2.0"
3155
  },
3156
+ "node_modules/array-flatten": {
3157
+ "version": "1.1.1",
3158
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
3159
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
3160
+ "license": "MIT"
3161
+ },
3162
  "node_modules/async": {
3163
  "version": "3.2.6",
3164
  "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
 
3384
  "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
3385
  "license": "MIT"
3386
  },
3387
+ "node_modules/body-parser": {
3388
+ "version": "1.20.4",
3389
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz",
3390
+ "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==",
3391
+ "license": "MIT",
3392
+ "dependencies": {
3393
+ "bytes": "~3.1.2",
3394
+ "content-type": "~1.0.5",
3395
+ "debug": "2.6.9",
3396
+ "depd": "2.0.0",
3397
+ "destroy": "~1.2.0",
3398
+ "http-errors": "~2.0.1",
3399
+ "iconv-lite": "~0.4.24",
3400
+ "on-finished": "~2.4.1",
3401
+ "qs": "~6.14.0",
3402
+ "raw-body": "~2.5.3",
3403
+ "type-is": "~1.6.18",
3404
+ "unpipe": "~1.0.0"
3405
+ },
3406
+ "engines": {
3407
+ "node": ">= 0.8",
3408
+ "npm": "1.2.8000 || >= 1.4.16"
3409
+ }
3410
+ },
3411
+ "node_modules/body-parser/node_modules/debug": {
3412
+ "version": "2.6.9",
3413
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
3414
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
3415
+ "license": "MIT",
3416
+ "dependencies": {
3417
+ "ms": "2.0.0"
3418
+ }
3419
+ },
3420
+ "node_modules/body-parser/node_modules/iconv-lite": {
3421
+ "version": "0.4.24",
3422
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
3423
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
3424
+ "license": "MIT",
3425
+ "dependencies": {
3426
+ "safer-buffer": ">= 2.1.2 < 3"
3427
+ },
3428
+ "engines": {
3429
+ "node": ">=0.10.0"
3430
+ }
3431
+ },
3432
+ "node_modules/body-parser/node_modules/ms": {
3433
+ "version": "2.0.0",
3434
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
3435
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
3436
+ "license": "MIT"
3437
+ },
3438
  "node_modules/brace-expansion": {
3439
  "version": "1.1.12",
3440
  "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
 
3450
  "version": "3.0.3",
3451
  "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
3452
  "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
 
3453
  "license": "MIT",
3454
  "dependencies": {
3455
  "fill-range": "^7.1.1"
 
3509
  "dev": true,
3510
  "license": "MIT"
3511
  },
3512
+ "node_modules/bytes": {
3513
+ "version": "3.1.2",
3514
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
3515
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
3516
+ "license": "MIT",
3517
+ "engines": {
3518
+ "node": ">= 0.8"
3519
+ }
3520
+ },
3521
  "node_modules/call-bind-apply-helpers": {
3522
  "version": "1.0.2",
3523
  "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
3524
  "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
 
3525
  "license": "MIT",
3526
  "dependencies": {
3527
  "es-errors": "^1.3.0",
 
3535
  "version": "1.0.4",
3536
  "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
3537
  "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
 
3538
  "license": "MIT",
3539
  "dependencies": {
3540
  "call-bind-apply-helpers": "^1.0.2",
 
3766
  "dev": true,
3767
  "license": "MIT"
3768
  },
3769
+ "node_modules/content-disposition": {
3770
+ "version": "0.5.4",
3771
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
3772
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
3773
+ "license": "MIT",
3774
+ "dependencies": {
3775
+ "safe-buffer": "5.2.1"
3776
+ },
3777
+ "engines": {
3778
+ "node": ">= 0.6"
3779
+ }
3780
+ },
3781
+ "node_modules/content-disposition/node_modules/safe-buffer": {
3782
+ "version": "5.2.1",
3783
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
3784
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
3785
+ "funding": [
3786
+ {
3787
+ "type": "github",
3788
+ "url": "https://github.com/sponsors/feross"
3789
+ },
3790
+ {
3791
+ "type": "patreon",
3792
+ "url": "https://www.patreon.com/feross"
3793
+ },
3794
+ {
3795
+ "type": "consulting",
3796
+ "url": "https://feross.org/support"
3797
+ }
3798
+ ],
3799
+ "license": "MIT"
3800
+ },
3801
+ "node_modules/content-type": {
3802
+ "version": "1.0.5",
3803
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
3804
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
3805
+ "license": "MIT",
3806
+ "engines": {
3807
+ "node": ">= 0.6"
3808
+ }
3809
+ },
3810
  "node_modules/convert-source-map": {
3811
  "version": "2.0.0",
3812
  "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
 
3814
  "dev": true,
3815
  "license": "MIT"
3816
  },
3817
+ "node_modules/cookie": {
3818
+ "version": "0.7.2",
3819
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
3820
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
3821
+ "license": "MIT",
3822
+ "engines": {
3823
+ "node": ">= 0.6"
3824
+ }
3825
+ },
3826
+ "node_modules/cookie-signature": {
3827
+ "version": "1.0.7",
3828
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz",
3829
+ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==",
3830
+ "license": "MIT"
3831
+ },
3832
  "node_modules/core-js-compat": {
3833
  "version": "3.45.1",
3834
  "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.45.1.tgz",
 
3998
  "node": ">=0.4.0"
3999
  }
4000
  },
4001
+ "node_modules/depd": {
4002
+ "version": "2.0.0",
4003
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
4004
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
4005
+ "license": "MIT",
4006
+ "engines": {
4007
+ "node": ">= 0.8"
4008
+ }
4009
+ },
4010
+ "node_modules/destroy": {
4011
+ "version": "1.2.0",
4012
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
4013
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
4014
+ "license": "MIT",
4015
+ "engines": {
4016
+ "node": ">= 0.8",
4017
+ "npm": "1.2.8000 || >= 1.4.16"
4018
+ }
4019
+ },
4020
  "node_modules/detect-newline": {
4021
  "version": "3.1.0",
4022
  "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
 
4068
  "version": "1.0.1",
4069
  "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
4070
  "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
 
4071
  "license": "MIT",
4072
  "dependencies": {
4073
  "call-bind-apply-helpers": "^1.0.1",
 
4078
  "node": ">= 0.4"
4079
  }
4080
  },
4081
+ "node_modules/ee-first": {
4082
+ "version": "1.1.1",
4083
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
4084
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
4085
+ "license": "MIT"
4086
+ },
4087
  "node_modules/electron-to-chromium": {
4088
  "version": "1.5.224",
4089
  "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.224.tgz",
 
4111
  "dev": true,
4112
  "license": "MIT"
4113
  },
4114
+ "node_modules/encodeurl": {
4115
+ "version": "2.0.0",
4116
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
4117
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
4118
+ "license": "MIT",
4119
+ "engines": {
4120
+ "node": ">= 0.8"
4121
+ }
4122
+ },
4123
  "node_modules/enhanced-resolve": {
4124
  "version": "5.18.3",
4125
  "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz",
 
4174
  "version": "1.0.1",
4175
  "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
4176
  "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
 
4177
  "license": "MIT",
4178
  "engines": {
4179
  "node": ">= 0.4"
 
4183
  "version": "1.3.0",
4184
  "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
4185
  "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
 
4186
  "license": "MIT",
4187
  "engines": {
4188
  "node": ">= 0.4"
 
4199
  "version": "1.1.1",
4200
  "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
4201
  "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
 
4202
  "license": "MIT",
4203
  "dependencies": {
4204
  "es-errors": "^1.3.0"
 
4233
  "node": ">=6"
4234
  }
4235
  },
4236
+ "node_modules/escape-html": {
4237
+ "version": "1.0.3",
4238
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
4239
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
4240
+ "license": "MIT"
4241
+ },
4242
  "node_modules/escape-string-regexp": {
4243
  "version": "4.0.0",
4244
  "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
 
4434
  "node": ">=0.10.0"
4435
  }
4436
  },
4437
+ "node_modules/etag": {
4438
+ "version": "1.8.1",
4439
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
4440
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
4441
+ "license": "MIT",
4442
+ "engines": {
4443
+ "node": ">= 0.6"
4444
+ }
4445
+ },
4446
  "node_modules/eventemitter3": {
4447
  "version": "4.0.7",
4448
  "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
4449
  "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
 
4450
  "license": "MIT"
4451
  },
4452
  "node_modules/events": {
 
4509
  "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
4510
  }
4511
  },
4512
+ "node_modules/express": {
4513
+ "version": "4.22.1",
4514
+ "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz",
4515
+ "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==",
4516
+ "license": "MIT",
4517
+ "dependencies": {
4518
+ "accepts": "~1.3.8",
4519
+ "array-flatten": "1.1.1",
4520
+ "body-parser": "~1.20.3",
4521
+ "content-disposition": "~0.5.4",
4522
+ "content-type": "~1.0.4",
4523
+ "cookie": "~0.7.1",
4524
+ "cookie-signature": "~1.0.6",
4525
+ "debug": "2.6.9",
4526
+ "depd": "2.0.0",
4527
+ "encodeurl": "~2.0.0",
4528
+ "escape-html": "~1.0.3",
4529
+ "etag": "~1.8.1",
4530
+ "finalhandler": "~1.3.1",
4531
+ "fresh": "~0.5.2",
4532
+ "http-errors": "~2.0.0",
4533
+ "merge-descriptors": "1.0.3",
4534
+ "methods": "~1.1.2",
4535
+ "on-finished": "~2.4.1",
4536
+ "parseurl": "~1.3.3",
4537
+ "path-to-regexp": "~0.1.12",
4538
+ "proxy-addr": "~2.0.7",
4539
+ "qs": "~6.14.0",
4540
+ "range-parser": "~1.2.1",
4541
+ "safe-buffer": "5.2.1",
4542
+ "send": "~0.19.0",
4543
+ "serve-static": "~1.16.2",
4544
+ "setprototypeof": "1.2.0",
4545
+ "statuses": "~2.0.1",
4546
+ "type-is": "~1.6.18",
4547
+ "utils-merge": "1.0.1",
4548
+ "vary": "~1.1.2"
4549
+ },
4550
+ "engines": {
4551
+ "node": ">= 0.10.0"
4552
+ },
4553
+ "funding": {
4554
+ "type": "opencollective",
4555
+ "url": "https://opencollective.com/express"
4556
+ }
4557
+ },
4558
+ "node_modules/express/node_modules/debug": {
4559
+ "version": "2.6.9",
4560
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
4561
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
4562
+ "license": "MIT",
4563
+ "dependencies": {
4564
+ "ms": "2.0.0"
4565
+ }
4566
+ },
4567
+ "node_modules/express/node_modules/ms": {
4568
+ "version": "2.0.0",
4569
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
4570
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
4571
+ "license": "MIT"
4572
+ },
4573
+ "node_modules/express/node_modules/safe-buffer": {
4574
+ "version": "5.2.1",
4575
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
4576
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
4577
+ "funding": [
4578
+ {
4579
+ "type": "github",
4580
+ "url": "https://github.com/sponsors/feross"
4581
+ },
4582
+ {
4583
+ "type": "patreon",
4584
+ "url": "https://www.patreon.com/feross"
4585
+ },
4586
+ {
4587
+ "type": "consulting",
4588
+ "url": "https://feross.org/support"
4589
+ }
4590
+ ],
4591
+ "license": "MIT"
4592
+ },
4593
  "node_modules/fast-deep-equal": {
4594
  "version": "3.1.3",
4595
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
 
4674
  "version": "7.1.1",
4675
  "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
4676
  "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
 
4677
  "license": "MIT",
4678
  "dependencies": {
4679
  "to-regex-range": "^5.0.1"
 
4682
  "node": ">=8"
4683
  }
4684
  },
4685
+ "node_modules/finalhandler": {
4686
+ "version": "1.3.2",
4687
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
4688
+ "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==",
4689
+ "license": "MIT",
4690
+ "dependencies": {
4691
+ "debug": "2.6.9",
4692
+ "encodeurl": "~2.0.0",
4693
+ "escape-html": "~1.0.3",
4694
+ "on-finished": "~2.4.1",
4695
+ "parseurl": "~1.3.3",
4696
+ "statuses": "~2.0.2",
4697
+ "unpipe": "~1.0.0"
4698
+ },
4699
+ "engines": {
4700
+ "node": ">= 0.8"
4701
+ }
4702
+ },
4703
+ "node_modules/finalhandler/node_modules/debug": {
4704
+ "version": "2.6.9",
4705
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
4706
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
4707
+ "license": "MIT",
4708
+ "dependencies": {
4709
+ "ms": "2.0.0"
4710
+ }
4711
+ },
4712
+ "node_modules/finalhandler/node_modules/ms": {
4713
+ "version": "2.0.0",
4714
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
4715
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
4716
+ "license": "MIT"
4717
+ },
4718
  "node_modules/find-cache-dir": {
4719
  "version": "4.0.0",
4720
  "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz",
 
4785
  "version": "1.15.11",
4786
  "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
4787
  "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
 
4788
  "funding": [
4789
  {
4790
  "type": "individual",
 
4818
  "node": ">= 6"
4819
  }
4820
  },
4821
+ "node_modules/forwarded": {
4822
+ "version": "0.2.0",
4823
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
4824
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
4825
+ "license": "MIT",
4826
+ "engines": {
4827
+ "node": ">= 0.6"
4828
+ }
4829
+ },
4830
+ "node_modules/fresh": {
4831
+ "version": "0.5.2",
4832
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
4833
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
4834
+ "license": "MIT",
4835
+ "engines": {
4836
+ "node": ">= 0.6"
4837
+ }
4838
+ },
4839
  "node_modules/fs.realpath": {
4840
  "version": "1.0.0",
4841
  "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
 
4861
  "version": "1.1.2",
4862
  "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
4863
  "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
 
4864
  "license": "MIT",
4865
  "funding": {
4866
  "url": "https://github.com/sponsors/ljharb"
 
4890
  "version": "1.3.0",
4891
  "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
4892
  "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
 
4893
  "license": "MIT",
4894
  "dependencies": {
4895
  "call-bind-apply-helpers": "^1.0.2",
 
4924
  "version": "1.0.1",
4925
  "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
4926
  "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
 
4927
  "license": "MIT",
4928
  "dependencies": {
4929
  "dunder-proto": "^1.0.1",
 
5008
  "version": "1.2.0",
5009
  "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
5010
  "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
 
5011
  "license": "MIT",
5012
  "engines": {
5013
  "node": ">= 0.4"
 
5042
  "version": "1.1.0",
5043
  "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
5044
  "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
 
5045
  "license": "MIT",
5046
  "engines": {
5047
  "node": ">= 0.4"
 
5070
  "version": "2.0.2",
5071
  "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
5072
  "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
 
5073
  "license": "MIT",
5074
  "dependencies": {
5075
  "function-bind": "^1.1.2"
 
5108
  "dev": true,
5109
  "license": "MIT"
5110
  },
5111
+ "node_modules/http-errors": {
5112
+ "version": "2.0.1",
5113
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
5114
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
5115
+ "license": "MIT",
5116
+ "dependencies": {
5117
+ "depd": "~2.0.0",
5118
+ "inherits": "~2.0.4",
5119
+ "setprototypeof": "~1.2.0",
5120
+ "statuses": "~2.0.2",
5121
+ "toidentifier": "~1.0.1"
5122
+ },
5123
+ "engines": {
5124
+ "node": ">= 0.8"
5125
+ },
5126
+ "funding": {
5127
+ "type": "opencollective",
5128
+ "url": "https://opencollective.com/express"
5129
+ }
5130
+ },
5131
  "node_modules/http-proxy": {
5132
  "version": "1.18.1",
5133
  "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
5134
  "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
 
5135
  "license": "MIT",
5136
  "dependencies": {
5137
  "eventemitter3": "^4.0.0",
 
5157
  "node": ">= 6"
5158
  }
5159
  },
5160
+ "node_modules/http-proxy-middleware": {
5161
+ "version": "2.0.9",
5162
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz",
5163
+ "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==",
5164
+ "license": "MIT",
5165
+ "dependencies": {
5166
+ "@types/http-proxy": "^1.17.8",
5167
+ "http-proxy": "^1.18.1",
5168
+ "is-glob": "^4.0.1",
5169
+ "is-plain-obj": "^3.0.0",
5170
+ "micromatch": "^4.0.2"
5171
+ },
5172
+ "engines": {
5173
+ "node": ">=12.0.0"
5174
+ },
5175
+ "peerDependencies": {
5176
+ "@types/express": "^4.17.13"
5177
+ },
5178
+ "peerDependenciesMeta": {
5179
+ "@types/express": {
5180
+ "optional": true
5181
+ }
5182
+ }
5183
+ },
5184
  "node_modules/http-server": {
5185
  "version": "14.1.1",
5186
  "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
 
5399
  "node": ">=10.13.0"
5400
  }
5401
  },
5402
+ "node_modules/ipaddr.js": {
5403
+ "version": "1.9.1",
5404
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
5405
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
5406
+ "license": "MIT",
5407
+ "engines": {
5408
+ "node": ">= 0.10"
5409
+ }
5410
+ },
5411
  "node_modules/is-arrayish": {
5412
  "version": "0.2.1",
5413
  "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
 
5435
  "version": "2.1.1",
5436
  "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
5437
  "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
 
5438
  "license": "MIT",
5439
  "engines": {
5440
  "node": ">=0.10.0"
 
5464
  "version": "4.0.3",
5465
  "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
5466
  "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
 
5467
  "license": "MIT",
5468
  "dependencies": {
5469
  "is-extglob": "^2.1.1"
 
5476
  "version": "7.0.0",
5477
  "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
5478
  "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
 
5479
  "license": "MIT",
5480
  "engines": {
5481
  "node": ">=0.12.0"
 
5491
  "node": ">=8"
5492
  }
5493
  },
5494
+ "node_modules/is-plain-obj": {
5495
+ "version": "3.0.0",
5496
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz",
5497
+ "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==",
5498
+ "license": "MIT",
5499
+ "engines": {
5500
+ "node": ">=10"
5501
+ },
5502
+ "funding": {
5503
+ "url": "https://github.com/sponsors/sindresorhus"
5504
+ }
5505
+ },
5506
  "node_modules/is-plain-object": {
5507
  "version": "2.0.4",
5508
  "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
 
6663
  "version": "1.1.0",
6664
  "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
6665
  "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
 
6666
  "license": "MIT",
6667
  "engines": {
6668
  "node": ">= 0.4"
 
6674
  "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
6675
  "license": "MIT"
6676
  },
6677
+ "node_modules/media-typer": {
6678
+ "version": "0.3.0",
6679
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
6680
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
6681
+ "license": "MIT",
6682
+ "engines": {
6683
+ "node": ">= 0.6"
6684
+ }
6685
+ },
6686
+ "node_modules/merge-descriptors": {
6687
+ "version": "1.0.3",
6688
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
6689
+ "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
6690
+ "license": "MIT",
6691
+ "funding": {
6692
+ "url": "https://github.com/sponsors/sindresorhus"
6693
+ }
6694
+ },
6695
  "node_modules/merge-stream": {
6696
  "version": "2.0.0",
6697
  "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
 
6699
  "dev": true,
6700
  "license": "MIT"
6701
  },
6702
+ "node_modules/methods": {
6703
+ "version": "1.1.2",
6704
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
6705
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
6706
+ "license": "MIT",
6707
+ "engines": {
6708
+ "node": ">= 0.6"
6709
+ }
6710
+ },
6711
  "node_modules/micromatch": {
6712
  "version": "4.0.8",
6713
  "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
6714
  "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
 
6715
  "license": "MIT",
6716
  "dependencies": {
6717
  "braces": "^3.0.3",
 
6725
  "version": "1.6.0",
6726
  "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
6727
  "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
 
6728
  "license": "MIT",
6729
  "bin": {
6730
  "mime": "cli.js"
 
6737
  "version": "1.52.0",
6738
  "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
6739
  "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
 
6740
  "license": "MIT",
6741
  "engines": {
6742
  "node": ">= 0.6"
 
6746
  "version": "2.1.35",
6747
  "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
6748
  "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
 
6749
  "license": "MIT",
6750
  "dependencies": {
6751
  "mime-db": "1.52.0"
 
6802
  "version": "2.1.3",
6803
  "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
6804
  "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
 
6805
  "license": "MIT"
6806
  },
6807
  "node_modules/natural-compare": {
 
6811
  "dev": true,
6812
  "license": "MIT"
6813
  },
6814
+ "node_modules/negotiator": {
6815
+ "version": "0.6.3",
6816
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
6817
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
6818
+ "license": "MIT",
6819
+ "engines": {
6820
+ "node": ">= 0.6"
6821
+ }
6822
+ },
6823
  "node_modules/neo-async": {
6824
  "version": "2.6.2",
6825
  "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
 
6875
  "version": "1.13.4",
6876
  "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
6877
  "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
 
6878
  "license": "MIT",
6879
  "engines": {
6880
  "node": ">= 0.4"
 
6883
  "url": "https://github.com/sponsors/ljharb"
6884
  }
6885
  },
6886
+ "node_modules/on-finished": {
6887
+ "version": "2.4.1",
6888
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
6889
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
6890
+ "license": "MIT",
6891
+ "dependencies": {
6892
+ "ee-first": "1.1.1"
6893
+ },
6894
+ "engines": {
6895
+ "node": ">= 0.8"
6896
+ }
6897
+ },
6898
  "node_modules/once": {
6899
  "version": "1.4.0",
6900
  "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
 
7035
  "url": "https://github.com/inikulin/parse5?sponsor=1"
7036
  }
7037
  },
7038
+ "node_modules/parseurl": {
7039
+ "version": "1.3.3",
7040
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
7041
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
7042
+ "license": "MIT",
7043
+ "engines": {
7044
+ "node": ">= 0.8"
7045
+ }
7046
+ },
7047
  "node_modules/path-exists": {
7048
  "version": "4.0.0",
7049
  "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
 
7081
  "dev": true,
7082
  "license": "MIT"
7083
  },
7084
+ "node_modules/path-to-regexp": {
7085
+ "version": "0.1.12",
7086
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
7087
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
7088
+ "license": "MIT"
7089
+ },
7090
  "node_modules/picocolors": {
7091
  "version": "1.1.1",
7092
  "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
 
7098
  "version": "2.3.1",
7099
  "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
7100
  "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
 
7101
  "license": "MIT",
7102
  "engines": {
7103
  "node": ">=8.6"
 
7472
  "node": ">= 0.8.0"
7473
  }
7474
  },
7475
+ "node_modules/proxy-addr": {
7476
+ "version": "2.0.7",
7477
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
7478
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
7479
+ "license": "MIT",
7480
+ "dependencies": {
7481
+ "forwarded": "0.2.0",
7482
+ "ipaddr.js": "1.9.1"
7483
+ },
7484
+ "engines": {
7485
+ "node": ">= 0.10"
7486
+ }
7487
+ },
7488
  "node_modules/psl": {
7489
  "version": "1.15.0",
7490
  "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz",
 
7538
  "version": "6.14.0",
7539
  "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
7540
  "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
 
7541
  "license": "BSD-3-Clause",
7542
  "dependencies": {
7543
  "side-channel": "^1.1.0"
 
7587
  "safe-buffer": "^5.1.0"
7588
  }
7589
  },
7590
+ "node_modules/range-parser": {
7591
+ "version": "1.2.1",
7592
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
7593
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
7594
+ "license": "MIT",
7595
+ "engines": {
7596
+ "node": ">= 0.6"
7597
+ }
7598
+ },
7599
+ "node_modules/raw-body": {
7600
+ "version": "2.5.3",
7601
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz",
7602
+ "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==",
7603
+ "license": "MIT",
7604
+ "dependencies": {
7605
+ "bytes": "~3.1.2",
7606
+ "http-errors": "~2.0.1",
7607
+ "iconv-lite": "~0.4.24",
7608
+ "unpipe": "~1.0.0"
7609
+ },
7610
+ "engines": {
7611
+ "node": ">= 0.8"
7612
+ }
7613
+ },
7614
+ "node_modules/raw-body/node_modules/iconv-lite": {
7615
+ "version": "0.4.24",
7616
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
7617
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
7618
+ "license": "MIT",
7619
+ "dependencies": {
7620
+ "safer-buffer": ">= 2.1.2 < 3"
7621
+ },
7622
+ "engines": {
7623
+ "node": ">=0.10.0"
7624
+ }
7625
+ },
7626
  "node_modules/react-is": {
7627
  "version": "18.3.1",
7628
  "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
 
7725
  "version": "1.0.0",
7726
  "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
7727
  "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
 
7728
  "license": "MIT"
7729
  },
7730
  "node_modules/requizzle": {
 
7863
  "version": "2.1.2",
7864
  "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
7865
  "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
 
7866
  "license": "MIT"
7867
  },
7868
  "node_modules/saxes": {
 
7952
  "semver": "bin/semver.js"
7953
  }
7954
  },
7955
+ "node_modules/send": {
7956
+ "version": "0.19.2",
7957
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz",
7958
+ "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==",
7959
+ "license": "MIT",
7960
+ "dependencies": {
7961
+ "debug": "2.6.9",
7962
+ "depd": "2.0.0",
7963
+ "destroy": "1.2.0",
7964
+ "encodeurl": "~2.0.0",
7965
+ "escape-html": "~1.0.3",
7966
+ "etag": "~1.8.1",
7967
+ "fresh": "~0.5.2",
7968
+ "http-errors": "~2.0.1",
7969
+ "mime": "1.6.0",
7970
+ "ms": "2.1.3",
7971
+ "on-finished": "~2.4.1",
7972
+ "range-parser": "~1.2.1",
7973
+ "statuses": "~2.0.2"
7974
+ },
7975
+ "engines": {
7976
+ "node": ">= 0.8.0"
7977
+ }
7978
+ },
7979
+ "node_modules/send/node_modules/debug": {
7980
+ "version": "2.6.9",
7981
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
7982
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
7983
+ "license": "MIT",
7984
+ "dependencies": {
7985
+ "ms": "2.0.0"
7986
+ }
7987
+ },
7988
+ "node_modules/send/node_modules/debug/node_modules/ms": {
7989
+ "version": "2.0.0",
7990
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
7991
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
7992
+ "license": "MIT"
7993
+ },
7994
  "node_modules/serialize-javascript": {
7995
  "version": "6.0.2",
7996
  "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
 
8001
  "randombytes": "^2.1.0"
8002
  }
8003
  },
8004
+ "node_modules/serve-static": {
8005
+ "version": "1.16.3",
8006
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz",
8007
+ "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==",
8008
+ "license": "MIT",
8009
+ "dependencies": {
8010
+ "encodeurl": "~2.0.0",
8011
+ "escape-html": "~1.0.3",
8012
+ "parseurl": "~1.3.3",
8013
+ "send": "~0.19.1"
8014
+ },
8015
+ "engines": {
8016
+ "node": ">= 0.8.0"
8017
+ }
8018
+ },
8019
+ "node_modules/setprototypeof": {
8020
+ "version": "1.2.0",
8021
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
8022
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
8023
+ "license": "ISC"
8024
+ },
8025
  "node_modules/shallow-clone": {
8026
  "version": "3.0.1",
8027
  "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
 
8062
  "version": "1.1.0",
8063
  "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
8064
  "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
 
8065
  "license": "MIT",
8066
  "dependencies": {
8067
  "es-errors": "^1.3.0",
 
8081
  "version": "1.0.0",
8082
  "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
8083
  "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
 
8084
  "license": "MIT",
8085
  "dependencies": {
8086
  "es-errors": "^1.3.0",
 
8097
  "version": "1.0.1",
8098
  "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
8099
  "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
 
8100
  "license": "MIT",
8101
  "dependencies": {
8102
  "call-bound": "^1.0.2",
 
8115
  "version": "1.0.2",
8116
  "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
8117
  "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
 
8118
  "license": "MIT",
8119
  "dependencies": {
8120
  "call-bound": "^1.0.2",
 
8205
  "node": ">=8"
8206
  }
8207
  },
8208
+ "node_modules/statuses": {
8209
+ "version": "2.0.2",
8210
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
8211
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
8212
+ "license": "MIT",
8213
+ "engines": {
8214
+ "node": ">= 0.8"
8215
+ }
8216
+ },
8217
  "node_modules/string-length": {
8218
  "version": "4.0.2",
8219
  "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
 
8472
  "version": "5.0.1",
8473
  "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
8474
  "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
 
8475
  "license": "MIT",
8476
  "dependencies": {
8477
  "is-number": "^7.0.0"
 
8480
  "node": ">=8.0"
8481
  }
8482
  },
8483
+ "node_modules/toidentifier": {
8484
+ "version": "1.0.1",
8485
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
8486
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
8487
+ "license": "MIT",
8488
+ "engines": {
8489
+ "node": ">=0.6"
8490
+ }
8491
+ },
8492
  "node_modules/tough-cookie": {
8493
  "version": "4.1.4",
8494
  "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
 
8554
  "url": "https://github.com/sponsors/sindresorhus"
8555
  }
8556
  },
8557
+ "node_modules/type-is": {
8558
+ "version": "1.6.18",
8559
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
8560
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
8561
+ "license": "MIT",
8562
+ "dependencies": {
8563
+ "media-typer": "0.3.0",
8564
+ "mime-types": "~2.1.24"
8565
+ },
8566
+ "engines": {
8567
+ "node": ">= 0.6"
8568
+ }
8569
+ },
8570
  "node_modules/uc.micro": {
8571
  "version": "2.1.0",
8572
  "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
 
8663
  "node": ">= 4.0.0"
8664
  }
8665
  },
8666
+ "node_modules/unpipe": {
8667
+ "version": "1.0.0",
8668
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
8669
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
8670
+ "license": "MIT",
8671
+ "engines": {
8672
+ "node": ">= 0.8"
8673
+ }
8674
+ },
8675
  "node_modules/update-browserslist-db": {
8676
  "version": "1.1.3",
8677
  "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
 
8731
  "requires-port": "^1.0.0"
8732
  }
8733
  },
8734
+ "node_modules/utils-merge": {
8735
+ "version": "1.0.1",
8736
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
8737
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
8738
+ "license": "MIT",
8739
+ "engines": {
8740
+ "node": ">= 0.4.0"
8741
+ }
8742
+ },
8743
  "node_modules/v8-to-istanbul": {
8744
  "version": "9.3.0",
8745
  "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
 
8755
  "node": ">=10.12.0"
8756
  }
8757
  },
8758
+ "node_modules/vary": {
8759
+ "version": "1.1.2",
8760
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
8761
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
8762
+ "license": "MIT",
8763
+ "engines": {
8764
+ "node": ">= 0.8"
8765
+ }
8766
+ },
8767
  "node_modules/w3c-xmlserializer": {
8768
  "version": "4.0.0",
8769
  "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
frontend/package.json CHANGED
@@ -6,7 +6,7 @@
6
  "scripts": {
7
  "test": "jest",
8
  "test:watch": "jest --watch",
9
- "serve": "http-server . -p 3000",
10
  "lint": "eslint js/**/*.js",
11
  "build": "webpack --mode production",
12
  "proto:generate": "pbjs -t static-module -w es6 -o proto/data_pb.js ../schema/data.proto && pbts -o proto/data_pb.d.ts proto/data_pb.js"
@@ -20,6 +20,8 @@
20
  "author": "",
21
  "license": "MIT",
22
  "dependencies": {
 
 
23
  "protobufjs": "^7.5.4",
24
  "protobufjs-cli": "^1.1.3"
25
  },
 
6
  "scripts": {
7
  "test": "jest",
8
  "test:watch": "jest --watch",
9
+ "serve": "node server.js",
10
  "lint": "eslint js/**/*.js",
11
  "build": "webpack --mode production",
12
  "proto:generate": "pbjs -t static-module -w es6 -o proto/data_pb.js ../schema/data.proto && pbts -o proto/data_pb.d.ts proto/data_pb.js"
 
20
  "author": "",
21
  "license": "MIT",
22
  "dependencies": {
23
+ "express": "^4.18.2",
24
+ "http-proxy-middleware": "^2.0.6",
25
  "protobufjs": "^7.5.4",
26
  "protobufjs-cli": "^1.1.3"
27
  },
frontend/server.js ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Express server with WebSocket proxy for TASTE Voice Bot frontend
3
+ *
4
+ * Architecture:
5
+ * - Browser connects to this server on port 3000 (HTTP + WebSocket)
6
+ * - Server serves static files from current directory
7
+ * - WebSocket requests to /ws/* are proxied internally to backend
8
+ * - Browser never directly connects to backend port
9
+ */
10
+
11
+ const express = require('express');
12
+ const { createProxyMiddleware } = require('http-proxy-middleware');
13
+ const path = require('path');
14
+
15
+ // Read backend configuration from environment variables
16
+ const BACKEND_HOST = process.env.BACKEND_HOST || 'localhost';
17
+ const BACKEND_PORT = process.env.BACKEND_PORT || '8000';
18
+ const BACKEND_WS_PATH = process.env.BACKEND_WS_PATH || '/ws/orchestrator';
19
+ const FRONTEND_PORT = process.env.FRONTEND_PORT || '3000';
20
+
21
+ // Parse BACKEND_HOST to extract protocol and hostname
22
+ let backendUrl;
23
+ try {
24
+ // If BACKEND_HOST includes protocol (http:// or https://), parse it
25
+ if (BACKEND_HOST.includes('://')) {
26
+ const url = new URL(BACKEND_HOST);
27
+ const protocol = url.protocol === 'https:' ? 'https' : 'http';
28
+ const wsProtocol = url.protocol === 'https:' ? 'wss' : 'ws';
29
+ const host = url.hostname;
30
+ const port = url.port || BACKEND_PORT;
31
+ backendUrl = {
32
+ http: `${protocol}://${host}:${port}`,
33
+ ws: `${wsProtocol}://${host}:${port}`,
34
+ display: `${protocol}://${host}:${port}`
35
+ };
36
+ } else {
37
+ // BACKEND_HOST is just hostname
38
+ backendUrl = {
39
+ http: `http://${BACKEND_HOST}:${BACKEND_PORT}`,
40
+ ws: `ws://${BACKEND_HOST}:${BACKEND_PORT}`,
41
+ display: `http://${BACKEND_HOST}:${BACKEND_PORT}`
42
+ };
43
+ }
44
+ } catch (e) {
45
+ // Fallback to simple hostname
46
+ backendUrl = {
47
+ http: `http://${BACKEND_HOST}:${BACKEND_PORT}`,
48
+ ws: `ws://${BACKEND_HOST}:${BACKEND_PORT}`,
49
+ display: `http://${BACKEND_HOST}:${BACKEND_PORT}`
50
+ };
51
+ }
52
+
53
+ const app = express();
54
+
55
+ // Serve static files from current directory
56
+ app.use(express.static(__dirname));
57
+
58
+ // WebSocket proxy middleware
59
+ const wsProxy = createProxyMiddleware({
60
+ target: backendUrl.http,
61
+ changeOrigin: true,
62
+ ws: true, // Enable WebSocket proxying
63
+ logLevel: 'info',
64
+ onError: (err, req, res) => {
65
+ console.error('Proxy error:', err);
66
+ if (res.writeHead) {
67
+ res.writeHead(502, { 'Content-Type': 'text/plain' });
68
+ res.end('Bad Gateway: Could not connect to backend');
69
+ }
70
+ },
71
+ onProxyReqWs: (proxyReq, req, socket, options, head) => {
72
+ console.log(`[WS Proxy] ${req.url} -> ${backendUrl.ws}${req.url}`);
73
+ }
74
+ });
75
+
76
+ // Apply WebSocket proxy to /ws/* paths
77
+ app.use('/ws', wsProxy);
78
+
79
+ // Start server
80
+ const server = app.listen(FRONTEND_PORT, () => {
81
+ console.log('=================================');
82
+ console.log('TASTE Voice Bot Frontend Server');
83
+ console.log('=================================');
84
+ console.log(`Frontend: http://localhost:${FRONTEND_PORT}`);
85
+ console.log(`Backend: ${backendUrl.display}`);
86
+ console.log(`WS Proxy: /ws/* -> ${backendUrl.ws}/ws/*`);
87
+ console.log('=================================');
88
+ });
89
+
90
+ // Enable WebSocket upgrade handling
91
+ server.on('upgrade', (req, socket, head) => {
92
+ if (req.url.startsWith('/ws')) {
93
+ wsProxy.upgrade(req, socket, head);
94
+ } else {
95
+ socket.destroy();
96
+ }
97
+ });
98
+
99
+ // Graceful shutdown
100
+ process.on('SIGTERM', () => {
101
+ console.log('SIGTERM received, shutting down gracefully...');
102
+ server.close(() => {
103
+ console.log('Server closed');
104
+ process.exit(0);
105
+ });
106
+ });
107
+
108
+ process.on('SIGINT', () => {
109
+ console.log('SIGINT received, shutting down gracefully...');
110
+ server.close(() => {
111
+ console.log('Server closed');
112
+ process.exit(0);
113
+ });
114
+ });
router/.env.sample DELETED
@@ -1,9 +0,0 @@
1
- # Proxy Server Configuration
2
-
3
- # Local proxy server port (where clients connect to)
4
- PROXY_PORT=8000
5
-
6
- # Target server configuration (where to forward requests)
7
- TARGET_HOST=your-backend-server.com
8
- TARGET_PORT=8000
9
- TARGET_WS_PATH=/ws/orchestrator
 
 
 
 
 
 
 
 
 
 
router/.gitignore DELETED
@@ -1,12 +0,0 @@
1
- # Dependencies
2
- node_modules/
3
-
4
- # Environment variables
5
- .env
6
-
7
- # Logs
8
- *.log
9
- npm-debug.log*
10
-
11
- # OS files
12
- .DS_Store
 
 
 
 
 
 
 
 
 
 
 
 
 
router/README.md DELETED
@@ -1,82 +0,0 @@
1
- # WebSocket Proxy Server
2
-
3
- WebSocket proxy server that receives connections from localhost:8000 and forwards them to a target backend server.
4
-
5
- ## Features
6
-
7
- - Listen on `ws://localhost:8000/ws/orchestrator`
8
- - Forward all WebSocket messages to the target server
9
- - Support both binary and text messages
10
- - Handle connection errors and auto-reconnection
11
-
12
- ## Configuration
13
-
14
- Copy `.env.sample` to `.env` and set the following variables:
15
-
16
- ```bash
17
- # Local proxy server port (where clients connect)
18
- PROXY_PORT=8000
19
-
20
- # Target server configuration (where to forward requests)
21
- TARGET_HOST=your-backend-server.com
22
- TARGET_PORT=8000
23
- TARGET_WS_PATH=/ws/orchestrator
24
- ```
25
-
26
- ## Installation
27
-
28
- ```bash
29
- npm install
30
- ```
31
-
32
- ## Usage
33
-
34
- ```bash
35
- # Start the proxy server
36
- npm start
37
-
38
- # Development mode with auto-restart
39
- npm run dev
40
- ```
41
-
42
- ## Example
43
-
44
- 1. Configure environment variables:
45
-
46
- ```bash
47
- cp .env.sample .env
48
- # Edit .env file with your target server settings
49
- ```
50
-
51
- 2. Start the proxy server:
52
-
53
- ```bash
54
- npm start
55
- ```
56
-
57
- 3. Frontend connects to proxy (no changes needed):
58
-
59
- ```javascript
60
- // Frontend still connects to localhost:8000
61
- const ws = new WebSocket('ws://localhost:8000/ws/orchestrator');
62
- ```
63
-
64
- ## Architecture
65
-
66
- ```
67
- [Frontend Client]
68
- |
69
- | ws://localhost:8000/ws/orchestrator
70
- v
71
- [Proxy Server]
72
- |
73
- | ws://${TARGET_HOST}:${TARGET_PORT}/ws/orchestrator
74
- v
75
- [Backend Server]
76
- ```
77
-
78
- ## Notes
79
-
80
- - Ensure `.env` file is properly configured
81
- - Target server must be accessible
82
- - Port 8000 must not be in use by other processes
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
router/package.json DELETED
@@ -1,22 +0,0 @@
1
- {
2
- "name": "chattaste-websocket-proxy",
3
- "version": "1.0.0",
4
- "description": "WebSocket proxy server for ChatTASTE Voice Bot",
5
- "main": "server.js",
6
- "type": "module",
7
- "scripts": {
8
- "start": "node server.js",
9
- "dev": "node --watch server.js"
10
- },
11
- "keywords": [
12
- "websocket",
13
- "proxy",
14
- "chattaste"
15
- ],
16
- "author": "",
17
- "license": "MIT",
18
- "dependencies": {
19
- "ws": "^8.18.0",
20
- "dotenv": "^16.4.7"
21
- }
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
router/server.js DELETED
@@ -1,121 +0,0 @@
1
- import WebSocket, { WebSocketServer } from 'ws';
2
- import { config } from 'dotenv';
3
-
4
- // Load environment variables
5
- config();
6
-
7
- // Configuration from environment variables
8
- const PROXY_PORT = parseInt(process.env.PROXY_PORT || '8000', 10);
9
- const TARGET_HOST = process.env.TARGET_HOST || 'localhost';
10
- const TARGET_PORT = parseInt(process.env.TARGET_PORT || '8001', 10);
11
- const TARGET_WS_PATH = process.env.TARGET_WS_PATH || '/ws/orchestrator';
12
-
13
- // Construct target WebSocket URL
14
- const targetUrl = `ws://${TARGET_HOST}:${TARGET_PORT}${TARGET_WS_PATH}`;
15
-
16
- console.log('=== WebSocket Proxy Server ===');
17
- console.log(`Listening on: ws://localhost:${PROXY_PORT}/ws/orchestrator`);
18
- console.log(`Forwarding to: ${targetUrl}`);
19
- console.log('==============================\n');
20
-
21
- // Create WebSocket server
22
- const wss = new WebSocketServer({
23
- port: PROXY_PORT,
24
- path: '/ws/orchestrator'
25
- });
26
-
27
- wss.on('listening', () => {
28
- console.log(`✓ Proxy server is listening on port ${PROXY_PORT}`);
29
- });
30
-
31
- wss.on('connection', (clientSocket, request) => {
32
- const clientIp = request.socket.remoteAddress;
33
- console.log(`[${new Date().toISOString()}] Client connected from ${clientIp}`);
34
-
35
- // Create connection to target server
36
- const targetSocket = new WebSocket(targetUrl);
37
-
38
- // Handle connection to target server
39
- targetSocket.on('open', () => {
40
- console.log(`[${new Date().toISOString()}] Connected to target server: ${targetUrl}`);
41
- });
42
-
43
- // Forward messages from client to target
44
- clientSocket.on('message', (data, isBinary) => {
45
- if (targetSocket.readyState === WebSocket.OPEN) {
46
- targetSocket.send(data, { binary: isBinary });
47
- }
48
- });
49
-
50
- // Forward messages from target to client
51
- targetSocket.on('message', (data, isBinary) => {
52
- if (clientSocket.readyState === WebSocket.OPEN) {
53
- clientSocket.send(data, { binary: isBinary });
54
- }
55
- });
56
-
57
- // Handle client disconnection
58
- clientSocket.on('close', (code, reason) => {
59
- console.log(`[${new Date().toISOString()}] Client disconnected (code: ${code}, reason: ${reason})`);
60
- if (targetSocket.readyState === WebSocket.OPEN || targetSocket.readyState === WebSocket.CONNECTING) {
61
- targetSocket.close();
62
- }
63
- });
64
-
65
- // Handle target disconnection
66
- targetSocket.on('close', (code, reason) => {
67
- console.log(`[${new Date().toISOString()}] Target server disconnected (code: ${code}, reason: ${reason})`);
68
- if (clientSocket.readyState === WebSocket.OPEN) {
69
- clientSocket.close();
70
- }
71
- });
72
-
73
- // Handle client errors
74
- clientSocket.on('error', (error) => {
75
- console.error(`[${new Date().toISOString()}] Client error:`, error.message);
76
- if (targetSocket.readyState === WebSocket.OPEN) {
77
- targetSocket.close();
78
- }
79
- });
80
-
81
- // Handle target errors
82
- targetSocket.on('error', (error) => {
83
- console.error(`[${new Date().toISOString()}] Target server error:`, error.message);
84
- if (clientSocket.readyState === WebSocket.OPEN) {
85
- clientSocket.close();
86
- }
87
- });
88
- });
89
-
90
- wss.on('error', (error) => {
91
- console.error('WebSocket server error:', error);
92
- });
93
-
94
- // Handle uncaught exceptions
95
- process.on('uncaughtException', (error) => {
96
- console.error(`[${new Date().toISOString()}] Uncaught Exception:`, error);
97
- process.exit(1);
98
- });
99
-
100
- // Handle unhandled promise rejections
101
- process.on('unhandledRejection', (reason, promise) => {
102
- console.error(`[${new Date().toISOString()}] Unhandled Rejection at:`, promise, 'reason:', reason);
103
- process.exit(1);
104
- });
105
-
106
- // Handle graceful shutdown
107
- process.on('SIGINT', () => {
108
- console.log('\n\nShutting down proxy server...');
109
- wss.close(() => {
110
- console.log('Proxy server closed');
111
- process.exit(0);
112
- });
113
- });
114
-
115
- process.on('SIGTERM', () => {
116
- console.log('\n\nShutting down proxy server...');
117
- wss.close(() => {
118
- console.log('Proxy server closed');
119
- process.exit(0);
120
- });
121
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
run_frontend.sh ADDED
@@ -0,0 +1 @@
 
 
1
+ cd frontend && npm install && node server.js
start.sh DELETED
@@ -1,61 +0,0 @@
1
- #!/bin/bash
2
-
3
- set -o pipefail
4
-
5
- # Helper function for logging with timestamp
6
- log() {
7
- echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
8
- }
9
-
10
- log "Starting ChatTASTE Voice Bot services..."
11
- log "NODE_ENV: ${NODE_ENV:-development}"
12
- log "LOG_LEVEL: ${LOG_LEVEL:-debug}"
13
-
14
- # Function to handle shutdown
15
- shutdown() {
16
- log "Shutting down services..."
17
- if [ ! -z "$ROUTER_PID" ] && kill -0 $ROUTER_PID 2>/dev/null; then
18
- log "Killing Router (PID: $ROUTER_PID)..."
19
- kill $ROUTER_PID 2>/dev/null || true
20
- fi
21
- if [ ! -z "$FRONTEND_PID" ] && kill -0 $FRONTEND_PID 2>/dev/null; then
22
- log "Killing Frontend (PID: $FRONTEND_PID)..."
23
- kill $FRONTEND_PID 2>/dev/null || true
24
- fi
25
- log "Services shut down"
26
- exit 0
27
- }
28
-
29
- # Trap SIGTERM and SIGINT signals
30
- trap shutdown SIGTERM SIGINT
31
-
32
- # Start the proxy server in the background
33
- log "Starting WebSocket Proxy Server on port 8000..."
34
- cd /app/router && node server.js &
35
- ROUTER_PID=$!
36
- log "Router started with PID: $ROUTER_PID"
37
- sleep 1
38
-
39
- # Start the frontend server in the background
40
- log "Starting Frontend Server on port 3000..."
41
- cd /app/frontend && npm run serve &
42
- FRONTEND_PID=$!
43
- log "Frontend started with PID: $FRONTEND_PID"
44
- sleep 2
45
-
46
- log "Both services are running. Monitoring processes..."
47
-
48
- # Monitor both processes
49
- while true; do
50
- if ! kill -0 $ROUTER_PID 2>/dev/null; then
51
- log "ERROR: Router process (PID: $ROUTER_PID) has died"
52
- shutdown
53
- fi
54
-
55
- if ! kill -0 $FRONTEND_PID 2>/dev/null; then
56
- log "ERROR: Frontend process (PID: $FRONTEND_PID) has died"
57
- shutdown
58
- fi
59
-
60
- sleep 5
61
- done