diff --git a/WebSocketClient/.gitignore b/WebSocketClient/.gitignore
new file mode 100644
index 0000000..225ecd8
--- /dev/null
+++ b/WebSocketClient/.gitignore
@@ -0,0 +1,3 @@
+npm-debug.log
+node_modules/
+dist/
\ No newline at end of file
diff --git a/WebSocketClient/UVLPlayground/.gitignore b/WebSocketClient/UVLPlayground/.gitignore
new file mode 100644
index 0000000..a547bf3
--- /dev/null
+++ b/WebSocketClient/UVLPlayground/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/WebSocketClient/UVLPlayground/Dockerfile b/WebSocketClient/UVLPlayground/Dockerfile
new file mode 100644
index 0000000..6456378
--- /dev/null
+++ b/WebSocketClient/UVLPlayground/Dockerfile
@@ -0,0 +1,14 @@
+# Use an official Nginx runtime as the base image
+FROM nginx:latest
+
+# Copy your static files into the Nginx document root directory
+COPY dist /usr/share/nginx/html
+
+# Optional: Copy a custom Nginx configuration file
+# COPY nginx.conf /etc/nginx/nginx.conf
+
+# Expose port 80 for HTTP traffic (Nginx's default port)
+EXPOSE 80
+
+# Start Nginx in the foreground
+CMD ["nginx", "-g", "daemon off;"]
\ No newline at end of file
diff --git a/WebSocketClient/UVLPlayground/index.html b/WebSocketClient/UVLPlayground/index.html
new file mode 100644
index 0000000..03fbbdb
--- /dev/null
+++ b/WebSocketClient/UVLPlayground/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+ Vite + TS
+
+
+ Monaco Language Client UVL Example
+
+
+
+
diff --git a/WebSocketClient/UVLPlayground/package-lock.json b/WebSocketClient/UVLPlayground/package-lock.json
new file mode 100644
index 0000000..e3ebf47
--- /dev/null
+++ b/WebSocketClient/UVLPlayground/package-lock.json
@@ -0,0 +1,894 @@
+{
+ "name": "uvlplayground",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "uvlplayground",
+ "version": "0.0.0",
+ "dependencies": {
+ "@codingame/monaco-vscode-configuration-service-override": "~1.83.2",
+ "@codingame/monaco-vscode-editor-service-override": "~1.83.2",
+ "@codingame/monaco-vscode-files-service-override": "~1.83.2",
+ "@codingame/monaco-vscode-json-default-extension": "~1.83.2",
+ "@codingame/monaco-vscode-keybindings-service-override": "~1.83.2",
+ "@codingame/monaco-vscode-python-default-extension": "~1.83.2",
+ "@codingame/monaco-vscode-textmate-service-override": "~1.83.2",
+ "@codingame/monaco-vscode-theme-defaults-default-extension": "~1.83.2",
+ "@codingame/monaco-vscode-theme-service-override": "~1.83.2",
+ "monaco-editor": "^0.44.0",
+ "monaco-editor-workers": "~0.44.0",
+ "monaco-languageclient": "^6.6.0",
+ "vite": "~4.4.11",
+ "vscode-json-languageservice": "~5.3.7",
+ "vscode-uri": "~3.0.8",
+ "vscode-ws-jsonrpc": "~3.0.0"
+ },
+ "devDependencies": {
+ "@types/vscode": "~1.83.0",
+ "typescript": "^5.0.2",
+ "vite": "^4.5.0",
+ "vscode-languageserver-types": "~3.17.3"
+ }
+ },
+ "node_modules/@codingame/monaco-vscode-configuration-service-override": {
+ "version": "1.83.2",
+ "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-configuration-service-override/-/monaco-vscode-configuration-service-override-1.83.2.tgz",
+ "integrity": "sha512-I13oNZjAs3Ypmo8wQzKRwvTjFhBOYGBR107/MpZI9JJgi16t1DwfL8IaDnc2yOOwNFkVrJ44Wr2TwFKS6RhUHw==",
+ "dependencies": {
+ "monaco-editor": "0.44.0",
+ "vscode": "npm:@codingame/monaco-vscode-api@1.83.2"
+ }
+ },
+ "node_modules/@codingame/monaco-vscode-editor-service-override": {
+ "version": "1.83.2",
+ "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-editor-service-override/-/monaco-vscode-editor-service-override-1.83.2.tgz",
+ "integrity": "sha512-Ou6StiX26baj98GGKDd5FIICe0pEl6RbopBlrPZ7H20F5T+d5WckEmzopBpGfrnLj/VaOHr8BT6tC3WzaNJWbw==",
+ "dependencies": {
+ "monaco-editor": "0.44.0",
+ "vscode": "npm:@codingame/monaco-vscode-api@1.83.2"
+ }
+ },
+ "node_modules/@codingame/monaco-vscode-files-service-override": {
+ "version": "1.83.2",
+ "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-files-service-override/-/monaco-vscode-files-service-override-1.83.2.tgz",
+ "integrity": "sha512-Y5WCe2Ar1s9971dT3kLQ8ThWJMJFJfMuZ1zGVQ//KCWs1SRuoykuk4NxYYovDNNwqn4Z9myHWPqSO6n07r4nGQ==",
+ "dependencies": {
+ "monaco-editor": "0.44.0",
+ "vscode": "npm:@codingame/monaco-vscode-api@1.83.2"
+ }
+ },
+ "node_modules/@codingame/monaco-vscode-json-default-extension": {
+ "version": "1.83.2",
+ "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-json-default-extension/-/monaco-vscode-json-default-extension-1.83.2.tgz",
+ "integrity": "sha512-8YIoMSd8iD6+0BfN+zi261R83gk2zo05jGrW9LwLJQuFYZwZl1D55rct73ZEv57EXky77PdFg59Q1OFfklE4FA==",
+ "dependencies": {
+ "vscode": "npm:@codingame/monaco-vscode-api@1.83.2"
+ }
+ },
+ "node_modules/@codingame/monaco-vscode-keybindings-service-override": {
+ "version": "1.83.2",
+ "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-keybindings-service-override/-/monaco-vscode-keybindings-service-override-1.83.2.tgz",
+ "integrity": "sha512-zEsTTH/H70DZzyZTu2WeLhakZ8N1W/LlPhgKxksrPluAVMeUAOaU2cuia7PXwxJ7mUtVf13W5BL4HZVwYxngrw==",
+ "dependencies": {
+ "monaco-editor": "0.44.0",
+ "vscode": "npm:@codingame/monaco-vscode-api@1.83.2"
+ }
+ },
+ "node_modules/@codingame/monaco-vscode-languages-service-override": {
+ "version": "1.83.2",
+ "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-languages-service-override/-/monaco-vscode-languages-service-override-1.83.2.tgz",
+ "integrity": "sha512-re9A6EF4cHzXWGkoZcuUERr+O3JiGMEQ2UsH470gKKzsWfbcJ7Ob8u/G6F06PRZoFuTUTqeTTzL7xdPN8tnjKA==",
+ "dependencies": {
+ "monaco-editor": "0.44.0",
+ "vscode": "npm:@codingame/monaco-vscode-api@1.83.2"
+ }
+ },
+ "node_modules/@codingame/monaco-vscode-model-service-override": {
+ "version": "1.83.2",
+ "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-model-service-override/-/monaco-vscode-model-service-override-1.83.2.tgz",
+ "integrity": "sha512-hWAbiOcDegRv4ft2HZHMAMisw5U4Vy6iILY3JwNN+y2tNhuRZz4aqHhHVgVz7bIz/iJtS4wmyN7aKmyXtUnokw==",
+ "dependencies": {
+ "monaco-editor": "0.44.0",
+ "vscode": "npm:@codingame/monaco-vscode-api@1.83.2"
+ }
+ },
+ "node_modules/@codingame/monaco-vscode-python-default-extension": {
+ "version": "1.83.2",
+ "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-python-default-extension/-/monaco-vscode-python-default-extension-1.83.2.tgz",
+ "integrity": "sha512-t2SSAmVynIf/Bhyy88LPET5Rfx+oCKj2ihGhB6I+39LsF+Kb61Vu3PonpID+IHyQJi8buqAb7KnPYmazX+fXfg==",
+ "dependencies": {
+ "vscode": "npm:@codingame/monaco-vscode-api@1.83.2"
+ }
+ },
+ "node_modules/@codingame/monaco-vscode-textmate-service-override": {
+ "version": "1.83.2",
+ "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-textmate-service-override/-/monaco-vscode-textmate-service-override-1.83.2.tgz",
+ "integrity": "sha512-R7ScgN80uSmNBOHmZop+ae+dbboH3SBCPHOYOctyflD7E8UKrENwEv+4OPJqjUm+HjgrRrDDfgwNzSbvPAhjvw==",
+ "dependencies": {
+ "monaco-editor": "0.44.0",
+ "vscode": "npm:@codingame/monaco-vscode-api@1.83.2",
+ "vscode-oniguruma": "1.7.0",
+ "vscode-textmate": "9.0.0"
+ }
+ },
+ "node_modules/@codingame/monaco-vscode-theme-defaults-default-extension": {
+ "version": "1.83.2",
+ "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-theme-defaults-default-extension/-/monaco-vscode-theme-defaults-default-extension-1.83.2.tgz",
+ "integrity": "sha512-PsFRBLN+ce6bP5PVkTBCTUoHMCALwBWwjDeYfsRWS6RQuIFTL9rTEzS2D1i/gRDNadWN6Emb6tce6D4Oqj+/qQ==",
+ "dependencies": {
+ "vscode": "npm:@codingame/monaco-vscode-api@1.83.2"
+ }
+ },
+ "node_modules/@codingame/monaco-vscode-theme-service-override": {
+ "version": "1.83.2",
+ "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-theme-service-override/-/monaco-vscode-theme-service-override-1.83.2.tgz",
+ "integrity": "sha512-aJWZBrD/c12YGia43iV7JmXFc16MJ3oYS3iYBj8RByV3pWfkhgIGDCGZbenRLdf2R045X1lQ8StAVrZe88oZzw==",
+ "dependencies": {
+ "monaco-editor": "0.44.0",
+ "vscode": "npm:@codingame/monaco-vscode-api@1.83.2"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
+ "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
+ "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
+ "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
+ "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
+ "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
+ "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
+ "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
+ "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
+ "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
+ "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
+ "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
+ "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
+ "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
+ "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
+ "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
+ "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
+ "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
+ "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
+ "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
+ "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
+ "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@types/vscode": {
+ "version": "1.83.0",
+ "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.83.0.tgz",
+ "integrity": "sha512-3mUtHqLAVz9hegut9au4xehuBrzRE3UJiQMpoEHkNl6XHliihO7eATx2BMHs0odsmmrwjJrlixx/Pte6M3ygDQ==",
+ "dev": true
+ },
+ "node_modules/@vscode/l10n": {
+ "version": "0.0.16",
+ "resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.16.tgz",
+ "integrity": "sha512-JT5CvrIYYCrmB+dCana8sUqJEcGB1ZDXNLMQ2+42bW995WmNoenijWMUdZfwmuQUTQcEVVIa2OecZzTYWUW9Cg=="
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.18.20",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
+ "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.18.20",
+ "@esbuild/android-arm64": "0.18.20",
+ "@esbuild/android-x64": "0.18.20",
+ "@esbuild/darwin-arm64": "0.18.20",
+ "@esbuild/darwin-x64": "0.18.20",
+ "@esbuild/freebsd-arm64": "0.18.20",
+ "@esbuild/freebsd-x64": "0.18.20",
+ "@esbuild/linux-arm": "0.18.20",
+ "@esbuild/linux-arm64": "0.18.20",
+ "@esbuild/linux-ia32": "0.18.20",
+ "@esbuild/linux-loong64": "0.18.20",
+ "@esbuild/linux-mips64el": "0.18.20",
+ "@esbuild/linux-ppc64": "0.18.20",
+ "@esbuild/linux-riscv64": "0.18.20",
+ "@esbuild/linux-s390x": "0.18.20",
+ "@esbuild/linux-x64": "0.18.20",
+ "@esbuild/netbsd-x64": "0.18.20",
+ "@esbuild/openbsd-x64": "0.18.20",
+ "@esbuild/sunos-x64": "0.18.20",
+ "@esbuild/win32-arm64": "0.18.20",
+ "@esbuild/win32-ia32": "0.18.20",
+ "@esbuild/win32-x64": "0.18.20"
+ }
+ },
+ "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,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/jsonc-parser": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w=="
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/monaco-editor": {
+ "version": "0.44.0",
+ "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz",
+ "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q=="
+ },
+ "node_modules/monaco-editor-workers": {
+ "version": "0.44.0",
+ "resolved": "https://registry.npmjs.org/monaco-editor-workers/-/monaco-editor-workers-0.44.0.tgz",
+ "integrity": "sha512-rvdO292CMnxs9Y3Hl6nAjVx8d0SjcDgmXmZNVoaOCNJrdnTEEzcWcHJzEQsajTAAq4H2oeBmDZRpDE0US5DhXA==",
+ "dependencies": {
+ "monaco-editor": "~0.44.0"
+ },
+ "peerDependencies": {
+ "monaco-editor": "~0.44.0"
+ }
+ },
+ "node_modules/monaco-languageclient": {
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/monaco-languageclient/-/monaco-languageclient-6.6.0.tgz",
+ "integrity": "sha512-Ued2Tpj2z4NiUy8l8KVM4TAk+sd2I9e78OWdXzwNbZz6nqMSK3w5uZkY3qj3LrlERZjJAITjBdUdplDb25t+fw==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@codingame/monaco-vscode-editor-service-override": "~1.83.2",
+ "@codingame/monaco-vscode-languages-service-override": "~1.83.2",
+ "@codingame/monaco-vscode-model-service-override": "~1.83.2",
+ "monaco-editor": "~0.44.0",
+ "vscode": "npm:@codingame/monaco-vscode-api@>=1.83.2 <1.84.0",
+ "vscode-languageclient": "~8.1.0"
+ },
+ "engines": {
+ "node": ">=16.11.0",
+ "npm": ">=9.0.0"
+ },
+ "peerDependencies": {
+ "monaco-editor": "~0.44.0",
+ "vscode": "npm:@codingame/monaco-vscode-api@>=1.83.2 <1.84.0"
+ },
+ "peerDependenciesMeta": {
+ "monaco-editor": {
+ "optional": false
+ },
+ "vscode": {
+ "optional": false
+ }
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+ "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "node_modules/postcss": {
+ "version": "8.4.31",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+ "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"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "3.29.4",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
+ "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
+ "dev": true,
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=14.18.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
+ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/vite": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz",
+ "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==",
+ "dev": true,
+ "dependencies": {
+ "esbuild": "^0.18.10",
+ "postcss": "^8.4.27",
+ "rollup": "^3.27.1"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ },
+ "peerDependencies": {
+ "@types/node": ">= 14",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vscode": {
+ "name": "@codingame/monaco-vscode-api",
+ "version": "1.83.2",
+ "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.83.2.tgz",
+ "integrity": "sha512-wTdkrnMZV85jyZQm9PZW98JMTwhzuETALAtTiMVX9Lvw/tdrbRQC5lBZjjEytHGxhSC141rd5JcwPrDkuimZGA==",
+ "dependencies": {
+ "monaco-editor": "0.44.0"
+ },
+ "bin": {
+ "monaco-treemending": "monaco-treemending.js"
+ }
+ },
+ "node_modules/vscode-json-languageservice": {
+ "version": "5.3.7",
+ "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-5.3.7.tgz",
+ "integrity": "sha512-jdDggN2SLMQw4C/tLr11v6/OK4cMVGy7tbyZRHQvukQ6lcflY3UV+ZMkmwHKCqXz2TmxkjQb536eJW6JMEVeew==",
+ "dependencies": {
+ "@vscode/l10n": "^0.0.16",
+ "jsonc-parser": "^3.2.0",
+ "vscode-languageserver-textdocument": "^1.0.11",
+ "vscode-languageserver-types": "^3.17.5",
+ "vscode-uri": "^3.0.8"
+ }
+ },
+ "node_modules/vscode-json-languageservice/node_modules/vscode-languageserver-types": {
+ "version": "3.17.5",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
+ "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="
+ },
+ "node_modules/vscode-jsonrpc": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0.tgz",
+ "integrity": "sha512-6TDy/abTQk+zDGYazgbIPc+4JoXdwC8NHU9Pbn4UJP1fehUyZmM4RHp5IthX7A6L5KS30PRui+j+tbbMMMafdw==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/vscode-languageclient": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-8.1.0.tgz",
+ "integrity": "sha512-GL4QdbYUF/XxQlAsvYWZRV3V34kOkpRlvV60/72ghHfsYFnS/v2MANZ9P6sHmxFcZKOse8O+L9G7Czg0NUWing==",
+ "dependencies": {
+ "minimatch": "^5.1.0",
+ "semver": "^7.3.7",
+ "vscode-languageserver-protocol": "3.17.3"
+ },
+ "engines": {
+ "vscode": "^1.67.0"
+ }
+ },
+ "node_modules/vscode-languageserver-protocol": {
+ "version": "3.17.3",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3.tgz",
+ "integrity": "sha512-924/h0AqsMtA5yK22GgMtCYiMdCOtWTSGgUOkgEDX+wk2b0x4sAfLiO4NxBxqbiVtz7K7/1/RgVrVI0NClZwqA==",
+ "dependencies": {
+ "vscode-jsonrpc": "8.1.0",
+ "vscode-languageserver-types": "3.17.3"
+ }
+ },
+ "node_modules/vscode-languageserver-textdocument": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.11.tgz",
+ "integrity": "sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA=="
+ },
+ "node_modules/vscode-languageserver-types": {
+ "version": "3.17.3",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz",
+ "integrity": "sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA=="
+ },
+ "node_modules/vscode-oniguruma": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
+ "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
+ },
+ "node_modules/vscode-textmate": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz",
+ "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg=="
+ },
+ "node_modules/vscode-uri": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz",
+ "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw=="
+ },
+ "node_modules/vscode-ws-jsonrpc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/vscode-ws-jsonrpc/-/vscode-ws-jsonrpc-3.0.0.tgz",
+ "integrity": "sha512-22IbVb2K691np9pOubyahNBj1BicsbtlbiaHOJu5/rvyWDqmqPMAqpAfojwGjdBztp8EtO8TAO7lmyY6hnmYAA==",
+ "dependencies": {
+ "vscode-jsonrpc": "~8.1.0"
+ },
+ "engines": {
+ "node": ">=16.11.0",
+ "npm": ">=8.0.0"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ }
+ }
+}
diff --git a/WebSocketClient/UVLPlayground/package.json b/WebSocketClient/UVLPlayground/package.json
new file mode 100644
index 0000000..5e5c95b
--- /dev/null
+++ b/WebSocketClient/UVLPlayground/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "uvlplayground",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "preview": "vite preview"
+ },
+ "devDependencies": {
+ "typescript": "^5.0.2",
+ "vite": "^4.5.0",
+ "vscode-languageserver-types": "~3.17.3",
+ "@types/vscode": "~1.83.0"
+ },
+ "dependencies": {
+ "monaco-editor": "^0.44.0",
+ "monaco-languageclient": "^6.6.0",
+ "@codingame/monaco-vscode-configuration-service-override": "~1.83.2",
+ "@codingame/monaco-vscode-editor-service-override": "~1.83.2",
+ "@codingame/monaco-vscode-files-service-override": "~1.83.2",
+ "@codingame/monaco-vscode-json-default-extension": "~1.83.2",
+ "@codingame/monaco-vscode-keybindings-service-override": "~1.83.2",
+ "@codingame/monaco-vscode-python-default-extension": "~1.83.2",
+ "@codingame/monaco-vscode-textmate-service-override": "~1.83.2",
+ "@codingame/monaco-vscode-theme-defaults-default-extension": "~1.83.2",
+ "@codingame/monaco-vscode-theme-service-override": "~1.83.2",
+ "vscode-json-languageservice": "~5.3.7",
+ "vscode-uri": "~3.0.8",
+ "vscode-ws-jsonrpc": "~3.0.0",
+ "monaco-editor-workers": "~0.44.0",
+ "vite": "~4.4.11"
+ }
+}
diff --git a/WebSocketClient/UVLPlayground/public/vite.svg b/WebSocketClient/UVLPlayground/public/vite.svg
new file mode 100644
index 0000000..e7b8dfb
--- /dev/null
+++ b/WebSocketClient/UVLPlayground/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/WebSocketClient/UVLPlayground/src/counter.ts b/WebSocketClient/UVLPlayground/src/counter.ts
new file mode 100644
index 0000000..09e5afd
--- /dev/null
+++ b/WebSocketClient/UVLPlayground/src/counter.ts
@@ -0,0 +1,9 @@
+export function setupCounter(element: HTMLButtonElement) {
+ let counter = 0
+ const setCounter = (count: number) => {
+ counter = count
+ element.innerHTML = `count is ${counter}`
+ }
+ element.addEventListener('click', () => setCounter(counter + 1))
+ setCounter(0)
+}
diff --git a/WebSocketClient/UVLPlayground/src/main.ts b/WebSocketClient/UVLPlayground/src/main.ts
new file mode 100644
index 0000000..d0af40b
--- /dev/null
+++ b/WebSocketClient/UVLPlayground/src/main.ts
@@ -0,0 +1,162 @@
+/* --------------------------------------------------------------------------------------------
+ * Copyright (c) 2018-2022 TypeFox GmbH (http://www.typefox.io). All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ * ------------------------------------------------------------------------------------------ */
+
+import * as monaco from 'monaco-editor';
+import * as vscode from 'vscode';
+import { whenReady } from '@codingame/monaco-vscode-theme-defaults-default-extension';
+import '@codingame/monaco-vscode-python-default-extension';
+import { LogLevel } from 'vscode/services';
+import { createConfiguredEditor, createModelReference } from 'vscode/monaco';
+import { ExtensionHostKind, registerExtension } from 'vscode/extensions';
+import getConfigurationServiceOverride, { updateUserConfiguration } from '@codingame/monaco-vscode-configuration-service-override';
+import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override';
+import getThemeServiceOverride from '@codingame/monaco-vscode-theme-service-override';
+import getTextmateServiceOverride from '@codingame/monaco-vscode-textmate-service-override';
+import { initServices, MonacoLanguageClient } from 'monaco-languageclient';
+import { CloseAction, ErrorAction, MessageTransports } from 'vscode-languageclient';
+import { WebSocketMessageReader, WebSocketMessageWriter, toSocket } from 'vscode-ws-jsonrpc';
+import { RegisteredFileSystemProvider, registerFileSystemOverlay, RegisteredMemoryFile } from 'vscode/service-override/files';
+import { Uri } from 'vscode';
+//import { createUrl } from '../../common.js';
+
+import { buildWorkerDefinition } from 'monaco-editor-workers';
+buildWorkerDefinition('../../../node_modules/monaco-editor-workers/dist/workers/', new URL('', window.location.href).href, false);
+
+const languageId = 'python';
+let languageClient: MonacoLanguageClient;
+
+const createUrl = (hostname: string, port: number, path: string, searchParams: Record = {}, secure: boolean = location.protocol === 'https:'): string => {
+ const protocol = secure ? 'wss' : 'ws';
+ const url = new URL(`${protocol}://${hostname}:${port}${path}`);
+
+ for (let [key, value] of Object.entries(searchParams)) {
+ if (value instanceof Array) {
+ value = value.join(',');
+ }
+ if (value) {
+ url.searchParams.set(key, value);
+ }
+ }
+
+ return url.toString();
+};
+
+const createWebSocket = (url: string): WebSocket => {
+ const webSocket = new WebSocket(url);
+ webSocket.onopen = async () => {
+ const socket = toSocket(webSocket);
+ const reader = new WebSocketMessageReader(socket);
+ const writer = new WebSocketMessageWriter(socket);
+ languageClient = createLanguageClient({
+ reader,
+ writer
+ });
+ await languageClient.start();
+ reader.onClose(() => languageClient.stop());
+ };
+ return webSocket;
+};
+
+const createLanguageClient = (transports: MessageTransports): MonacoLanguageClient => {
+ return new MonacoLanguageClient({
+ name: 'Pyright Language Client',
+ clientOptions: {
+ // use a language id as a document selector
+ documentSelector: [languageId],
+ // disable the default error handler
+ errorHandler: {
+ error: () => ({ action: ErrorAction.Continue }),
+ closed: () => ({ action: CloseAction.DoNotRestart })
+ },
+ // pyright requires a workspace folder to be present, otherwise it will not work
+ workspaceFolder: {
+ index: 0,
+ name: 'workspace',
+ uri: monaco.Uri.parse('/workspace')
+ },
+ synchronize: {
+ fileEvents: [vscode.workspace.createFileSystemWatcher('**')]
+ }
+ },
+ // create a language client connection from the JSON RPC connection on demand
+ connectionProvider: {
+ get: () => {
+ return Promise.resolve(transports);
+ }
+ }
+ });
+};
+
+export const startPythonClient = async () => {
+ // init vscode-api
+ await initServices({
+ userServices: {
+ ...getThemeServiceOverride(),
+ ...getTextmateServiceOverride(),
+ ...getConfigurationServiceOverride(Uri.file('/workspace')),
+ ...getKeybindingsServiceOverride()
+ },
+ debugLogging: true,
+ logLevel: LogLevel.Debug
+ });
+
+ console.log('Before ready themes');
+ await whenReady();
+ console.log('After ready themes');
+
+ // extension configuration derived from:
+ // https://github.com/microsoft/pyright/blob/main/packages/vscode-pyright/package.json
+ // only a minimum is required to get pyright working
+ const extension = {
+ name: 'python-client',
+ publisher: 'monaco-languageclient-project',
+ version: '1.0.0',
+ engines: {
+ vscode: '^1.78.0'
+ },
+ contributes: {
+ languages: [{
+ id: languageId,
+ aliases: [
+ 'Python'
+ ],
+ extensions: [
+ '.py',
+ '.pyi'
+ ]
+ }]
+ }
+ };
+ registerExtension(extension, ExtensionHostKind.LocalProcess);
+
+ updateUserConfiguration(`{
+ "editor.fontSize": 14,
+ "workbench.colorTheme": "Default Dark Modern",
+ theme: "vs-dark"
+ }`);
+
+ const fileSystemProvider = new RegisteredFileSystemProvider(false);
+ fileSystemProvider.registerFile(new RegisteredMemoryFile(vscode.Uri.file('/workspace/fm.uvl'), 'features\n\tfeature1\n\nconstraints\n\t!feature1'));
+ registerFileSystemOverlay(1, fileSystemProvider);
+
+ // create the web socket and configure to start the language client on open, can add extra parameters to the url if needed.
+ createWebSocket(createUrl('590c9306-8ced-48f6-85f2-bb8caa1bfd52.ul.bw-cloud-instance.org', 30000, '/pyright', {
+ // Used to parse an auth token or additional parameters such as import IDs to the language server
+ authorization: 'UserAuth'
+ // By commenting above line out and commenting below line in, connection to language server will be denied.
+ // authorization: 'FailedUserAuth'
+ }, false));
+
+
+ // use the file create before
+ const modelRef = await createModelReference(monaco.Uri.file('/workspace/fm.uvl'));
+ modelRef.object.setLanguageId(languageId);
+
+ // create monaco editor
+ createConfiguredEditor(document.getElementById('container')!, {
+ model: modelRef.object.textEditorModel,
+ automaticLayout: true
+ });
+};
diff --git a/WebSocketClient/UVLPlayground/src/style.css b/WebSocketClient/UVLPlayground/src/style.css
new file mode 100644
index 0000000..b528b6c
--- /dev/null
+++ b/WebSocketClient/UVLPlayground/src/style.css
@@ -0,0 +1,97 @@
+:root {
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+}
+
+.logo {
+ height: 6em;
+ padding: 1.5em;
+ will-change: filter;
+ transition: filter 300ms;
+}
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.vanilla:hover {
+ filter: drop-shadow(0 0 2em #3178c6aa);
+}
+
+.card {
+ padding: 2em;
+}
+
+.read-the-docs {
+ color: #888;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
+}
diff --git a/WebSocketClient/UVLPlayground/src/typescript.svg b/WebSocketClient/UVLPlayground/src/typescript.svg
new file mode 100644
index 0000000..d91c910
--- /dev/null
+++ b/WebSocketClient/UVLPlayground/src/typescript.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/WebSocketClient/UVLPlayground/src/vite-env.d.ts b/WebSocketClient/UVLPlayground/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/WebSocketClient/UVLPlayground/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/WebSocketClient/UVLPlayground/tsconfig.json b/WebSocketClient/UVLPlayground/tsconfig.json
new file mode 100644
index 0000000..568021c
--- /dev/null
+++ b/WebSocketClient/UVLPlayground/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "module": "ESNext",
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "skipLibCheck": true,
+ "noImplicitAny": false,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "noEmit": true,
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src"]
+}
diff --git a/WebSocketClient/deployment.sh b/WebSocketClient/deployment.sh
new file mode 100644
index 0000000..411e7b4
--- /dev/null
+++ b/WebSocketClient/deployment.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+docker kill uvl-playground-website
+docker rm uvl-playground-website
+
+docker build -t uvl-playground-website .
+docker run --name uvl-playground-website -d -p 80:80 -t uvl-playground-website
\ No newline at end of file