From 54a192cc47656b8b43bd8474312eff68886b8ac0 Mon Sep 17 00:00:00 2001
From: baletiballo <75846481+baletiballo@users.noreply.github.com>
Date: Thu, 23 Jan 2025 17:32:01 +0100
Subject: [PATCH] Made the ScrollView run on a Node server, to allow the use of
 three.js

Moved all ScrollView related Files into a new Folder for that.
---
 .gitignore                                    |   2 +
 Assets/Scripts/UI/InGame/WebViewController.cs |   2 +-
 Assets/StreamingAssets/ScrollView_Server.meta |   8 +
 .../ScrollView_Server/package-lock.json       | 951 ++++++++++++++++++
 .../ScrollView_Server/package-lock.json.meta  |   7 +
 .../ScrollView_Server/package.json            |   8 +
 .../ScrollView_Server/package.json.meta       |   7 +
 .../ScrollView_Server/scrollView.html         | 181 ++++
 .../scrollView.html.meta                      |   2 +-
 .../scroll_interaction.meta                   |   2 +-
 .../scroll_interaction/.SetScrollContent.js   |  33 +
 .../scroll_interaction/Drop_facts.js          |   0
 .../scroll_interaction/Drop_facts.js.meta     |   0
 .../scroll_interaction/SetScrollContent.js    |  28 +
 .../SetScrollContent.js.meta                  |   0
 .../scrollView.html                           | 212 ----
 .../scroll_interaction/SetScrollContent.js    |  67 --
 17 files changed, 1228 insertions(+), 282 deletions(-)
 create mode 100644 Assets/StreamingAssets/ScrollView_Server.meta
 create mode 100644 Assets/StreamingAssets/ScrollView_Server/package-lock.json
 create mode 100644 Assets/StreamingAssets/ScrollView_Server/package-lock.json.meta
 create mode 100644 Assets/StreamingAssets/ScrollView_Server/package.json
 create mode 100644 Assets/StreamingAssets/ScrollView_Server/package.json.meta
 create mode 100644 Assets/StreamingAssets/ScrollView_Server/scrollView.html
 rename Assets/StreamingAssets/{StreamToDataPath_withHandler => ScrollView_Server}/scrollView.html.meta (74%)
 rename Assets/StreamingAssets/{StreamToDataPath_withHandler => ScrollView_Server}/scroll_interaction.meta (77%)
 create mode 100644 Assets/StreamingAssets/ScrollView_Server/scroll_interaction/.SetScrollContent.js
 rename Assets/StreamingAssets/{StreamToDataPath_withHandler => ScrollView_Server}/scroll_interaction/Drop_facts.js (100%)
 rename Assets/StreamingAssets/{StreamToDataPath_withHandler => ScrollView_Server}/scroll_interaction/Drop_facts.js.meta (100%)
 create mode 100644 Assets/StreamingAssets/ScrollView_Server/scroll_interaction/SetScrollContent.js
 rename Assets/StreamingAssets/{StreamToDataPath_withHandler => ScrollView_Server}/scroll_interaction/SetScrollContent.js.meta (100%)
 delete mode 100644 Assets/StreamingAssets/StreamToDataPath_withHandler/scrollView.html
 delete mode 100644 Assets/StreamingAssets/StreamToDataPath_withHandler/scroll_interaction/SetScrollContent.js

diff --git a/.gitignore b/.gitignore
index d557caf9..7709cc67 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,3 +81,5 @@ Assets/StreamingAssets/frameit-mmt.jar
 Assets/StreamingAssets/frameit-mmt.jar.meta
 Assets/StreamingAssets/StreamToDataPath_withHandler/tmp.json
 Assets/StreamingAssets/StreamToDataPath_withHandler/tmp.json.meta
+/Assets/StreamingAssets/ScrollView_Server/node_modules
+Assets/StreamingAssets/ScrollView_Server/node_modules.meta
diff --git a/Assets/Scripts/UI/InGame/WebViewController.cs b/Assets/Scripts/UI/InGame/WebViewController.cs
index 8d247c58..103d3606 100644
--- a/Assets/Scripts/UI/InGame/WebViewController.cs
+++ b/Assets/Scripts/UI/InGame/WebViewController.cs
@@ -23,7 +23,7 @@ private void Awake()
     {
         webViewComponent = GetComponent<WebViewComponent>();
         WebViewComponent.serializerSettings.Converters.Add(new FactObjectUIConverter());
-        webViewComponent.targetUrl = Path.Join(CommunicationEvents.Get_DataPath(), "scrollView.html");
+        webViewComponent.targetUrl = Path.Join(CommunicationEvents.Get_DataPath(), "../ScrollView_Server/scrollView.html");
         webViewComponent.OnWebViewComponentReady += OnWebViewComponentReady;
 
         // TODO: handle webViewComponent.onDomDocumentUpdated
diff --git a/Assets/StreamingAssets/ScrollView_Server.meta b/Assets/StreamingAssets/ScrollView_Server.meta
new file mode 100644
index 00000000..d0754c12
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b246cdf29bb2a4a46bfde090f9fb1b4b
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/StreamingAssets/ScrollView_Server/package-lock.json b/Assets/StreamingAssets/ScrollView_Server/package-lock.json
new file mode 100644
index 00000000..a37e8cd1
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/package-lock.json
@@ -0,0 +1,951 @@
+{
+  "name": "ScrollView_Server",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "dependencies": {
+        "three": "^0.172.0"
+      },
+      "devDependencies": {
+        "vite": "^6.0.11"
+      }
+    },
+    "node_modules/@esbuild/aix-ppc64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
+      "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "aix"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz",
+      "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/android-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz",
+      "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/android-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz",
+      "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/darwin-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz",
+      "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz",
+      "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz",
+      "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/freebsd-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz",
+      "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-arm": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz",
+      "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz",
+      "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-ia32": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz",
+      "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz",
+      "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-mips64el": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz",
+      "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-ppc64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz",
+      "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-riscv64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz",
+      "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-s390x": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz",
+      "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz",
+      "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/netbsd-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz",
+      "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/netbsd-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz",
+      "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/openbsd-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz",
+      "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/openbsd-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz",
+      "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/sunos-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz",
+      "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/win32-arm64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz",
+      "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/win32-ia32": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz",
+      "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/win32-x64": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz",
+      "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@rollup/rollup-android-arm-eabi": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.31.0.tgz",
+      "integrity": "sha512-9NrR4033uCbUBRgvLcBrJofa2KY9DzxL2UKZ1/4xA/mnTNyhZCWBuD8X3tPm1n4KxcgaraOYgrFKSgwjASfmlA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-android-arm64": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.31.0.tgz",
+      "integrity": "sha512-iBbODqT86YBFHajxxF8ebj2hwKm1k8PTBQSojSt3d1FFt1gN+xf4CowE47iN0vOSdnd+5ierMHBbu/rHc7nq5g==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-arm64": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.31.0.tgz",
+      "integrity": "sha512-WHIZfXgVBX30SWuTMhlHPXTyN20AXrLH4TEeH/D0Bolvx9PjgZnn4H677PlSGvU6MKNsjCQJYczkpvBbrBnG6g==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-x64": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.31.0.tgz",
+      "integrity": "sha512-hrWL7uQacTEF8gdrQAqcDy9xllQ0w0zuL1wk1HV8wKGSGbKPVjVUv/DEwT2+Asabf8Dh/As+IvfdU+H8hhzrQQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-freebsd-arm64": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.31.0.tgz",
+      "integrity": "sha512-S2oCsZ4hJviG1QjPY1h6sVJLBI6ekBeAEssYKad1soRFv3SocsQCzX6cwnk6fID6UQQACTjeIMB+hyYrFacRew==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-freebsd-x64": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.31.0.tgz",
+      "integrity": "sha512-pCANqpynRS4Jirn4IKZH4tnm2+2CqCNLKD7gAdEjzdLGbH1iO0zouHz4mxqg0uEMpO030ejJ0aA6e1PJo2xrPA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.31.0.tgz",
+      "integrity": "sha512-0O8ViX+QcBd3ZmGlcFTnYXZKGbFu09EhgD27tgTdGnkcYXLat4KIsBBQeKLR2xZDCXdIBAlWLkiXE1+rJpCxFw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.31.0.tgz",
+      "integrity": "sha512-w5IzG0wTVv7B0/SwDnMYmbr2uERQp999q8FMkKG1I+j8hpPX2BYFjWe69xbhbP6J9h2gId/7ogesl9hwblFwwg==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-gnu": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.31.0.tgz",
+      "integrity": "sha512-JyFFshbN5xwy6fulZ8B/8qOqENRmDdEkcIMF0Zz+RsfamEW+Zabl5jAb0IozP/8UKnJ7g2FtZZPEUIAlUSX8cA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-musl": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.31.0.tgz",
+      "integrity": "sha512-kpQXQ0UPFeMPmPYksiBL9WS/BDiQEjRGMfklVIsA0Sng347H8W2iexch+IEwaR7OVSKtr2ZFxggt11zVIlZ25g==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.31.0.tgz",
+      "integrity": "sha512-pMlxLjt60iQTzt9iBb3jZphFIl55a70wexvo8p+vVFK+7ifTRookdoXX3bOsRdmfD+OKnMozKO6XM4zR0sHRrQ==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.31.0.tgz",
+      "integrity": "sha512-D7TXT7I/uKEuWiRkEFbed1UUYZwcJDU4vZQdPTcepK7ecPhzKOYk4Er2YR4uHKme4qDeIh6N3XrLfpuM7vzRWQ==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.31.0.tgz",
+      "integrity": "sha512-wal2Tc8O5lMBtoePLBYRKj2CImUCJ4UNGJlLwspx7QApYny7K1cUYlzQ/4IGQBLmm+y0RS7dwc3TDO/pmcneTw==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-s390x-gnu": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.31.0.tgz",
+      "integrity": "sha512-O1o5EUI0+RRMkK9wiTVpk2tyzXdXefHtRTIjBbmFREmNMy7pFeYXCFGbhKFwISA3UOExlo5GGUuuj3oMKdK6JQ==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-gnu": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.31.0.tgz",
+      "integrity": "sha512-zSoHl356vKnNxwOWnLd60ixHNPRBglxpv2g7q0Cd3Pmr561gf0HiAcUBRL3S1vPqRC17Zo2CX/9cPkqTIiai1g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-musl": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.31.0.tgz",
+      "integrity": "sha512-ypB/HMtcSGhKUQNiFwqgdclWNRrAYDH8iMYH4etw/ZlGwiTVxBz2tDrGRrPlfZu6QjXwtd+C3Zib5pFqID97ZA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-arm64-msvc": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.31.0.tgz",
+      "integrity": "sha512-JuhN2xdI/m8Hr+aVO3vspO7OQfUFO6bKLIRTAy0U15vmWjnZDLrEgCZ2s6+scAYaQVpYSh9tZtRijApw9IXyMw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-ia32-msvc": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.31.0.tgz",
+      "integrity": "sha512-U1xZZXYkvdf5MIWmftU8wrM5PPXzyaY1nGCI4KI4BFfoZxHamsIe+BtnPLIvvPykvQWlVbqUXdLa4aJUuilwLQ==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-x64-msvc": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.31.0.tgz",
+      "integrity": "sha512-ul8rnCsUumNln5YWwz0ted2ZHFhzhRRnkpBZ+YRuHoRAlUji9KChpOUOndY7uykrPEPXVbHLlsdo6v5yXo/TXw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@types/estree": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+      "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/esbuild": {
+      "version": "0.24.2",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
+      "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "optionalDependencies": {
+        "@esbuild/aix-ppc64": "0.24.2",
+        "@esbuild/android-arm": "0.24.2",
+        "@esbuild/android-arm64": "0.24.2",
+        "@esbuild/android-x64": "0.24.2",
+        "@esbuild/darwin-arm64": "0.24.2",
+        "@esbuild/darwin-x64": "0.24.2",
+        "@esbuild/freebsd-arm64": "0.24.2",
+        "@esbuild/freebsd-x64": "0.24.2",
+        "@esbuild/linux-arm": "0.24.2",
+        "@esbuild/linux-arm64": "0.24.2",
+        "@esbuild/linux-ia32": "0.24.2",
+        "@esbuild/linux-loong64": "0.24.2",
+        "@esbuild/linux-mips64el": "0.24.2",
+        "@esbuild/linux-ppc64": "0.24.2",
+        "@esbuild/linux-riscv64": "0.24.2",
+        "@esbuild/linux-s390x": "0.24.2",
+        "@esbuild/linux-x64": "0.24.2",
+        "@esbuild/netbsd-arm64": "0.24.2",
+        "@esbuild/netbsd-x64": "0.24.2",
+        "@esbuild/openbsd-arm64": "0.24.2",
+        "@esbuild/openbsd-x64": "0.24.2",
+        "@esbuild/sunos-x64": "0.24.2",
+        "@esbuild/win32-arm64": "0.24.2",
+        "@esbuild/win32-ia32": "0.24.2",
+        "@esbuild/win32-x64": "0.24.2"
+      }
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.8",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
+      "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "dev": true,
+      "license": "ISC"
+    },
+    "node_modules/postcss": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz",
+      "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "nanoid": "^3.3.8",
+        "picocolors": "^1.1.1",
+        "source-map-js": "^1.2.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/rollup": {
+      "version": "4.31.0",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.31.0.tgz",
+      "integrity": "sha512-9cCE8P4rZLx9+PjoyqHLs31V9a9Vpvfo4qNcs6JCiGWYhw2gijSetFbH6SSy1whnkgcefnUwr8sad7tgqsGvnw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree": "1.0.6"
+      },
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=18.0.0",
+        "npm": ">=8.0.0"
+      },
+      "optionalDependencies": {
+        "@rollup/rollup-android-arm-eabi": "4.31.0",
+        "@rollup/rollup-android-arm64": "4.31.0",
+        "@rollup/rollup-darwin-arm64": "4.31.0",
+        "@rollup/rollup-darwin-x64": "4.31.0",
+        "@rollup/rollup-freebsd-arm64": "4.31.0",
+        "@rollup/rollup-freebsd-x64": "4.31.0",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.31.0",
+        "@rollup/rollup-linux-arm-musleabihf": "4.31.0",
+        "@rollup/rollup-linux-arm64-gnu": "4.31.0",
+        "@rollup/rollup-linux-arm64-musl": "4.31.0",
+        "@rollup/rollup-linux-loongarch64-gnu": "4.31.0",
+        "@rollup/rollup-linux-powerpc64le-gnu": "4.31.0",
+        "@rollup/rollup-linux-riscv64-gnu": "4.31.0",
+        "@rollup/rollup-linux-s390x-gnu": "4.31.0",
+        "@rollup/rollup-linux-x64-gnu": "4.31.0",
+        "@rollup/rollup-linux-x64-musl": "4.31.0",
+        "@rollup/rollup-win32-arm64-msvc": "4.31.0",
+        "@rollup/rollup-win32-ia32-msvc": "4.31.0",
+        "@rollup/rollup-win32-x64-msvc": "4.31.0",
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+      "dev": true,
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/three": {
+      "version": "0.172.0",
+      "resolved": "https://registry.npmjs.org/three/-/three-0.172.0.tgz",
+      "integrity": "sha512-6HMgMlzU97MsV7D/tY8Va38b83kz8YJX+BefKjspMNAv0Vx6dxMogHOrnRl/sbMIs3BPUKijPqDqJ/+UwJbIow==",
+      "license": "MIT"
+    },
+    "node_modules/vite": {
+      "version": "6.0.11",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.11.tgz",
+      "integrity": "sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "esbuild": "^0.24.2",
+        "postcss": "^8.4.49",
+        "rollup": "^4.23.0"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/vitejs/vite?sponsor=1"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.3"
+      },
+      "peerDependencies": {
+        "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+        "jiti": ">=1.21.0",
+        "less": "*",
+        "lightningcss": "^1.21.0",
+        "sass": "*",
+        "sass-embedded": "*",
+        "stylus": "*",
+        "sugarss": "*",
+        "terser": "^5.16.0",
+        "tsx": "^4.8.1",
+        "yaml": "^2.4.2"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        },
+        "jiti": {
+          "optional": true
+        },
+        "less": {
+          "optional": true
+        },
+        "lightningcss": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "sass-embedded": {
+          "optional": true
+        },
+        "stylus": {
+          "optional": true
+        },
+        "sugarss": {
+          "optional": true
+        },
+        "terser": {
+          "optional": true
+        },
+        "tsx": {
+          "optional": true
+        },
+        "yaml": {
+          "optional": true
+        }
+      }
+    }
+  }
+}
diff --git a/Assets/StreamingAssets/ScrollView_Server/package-lock.json.meta b/Assets/StreamingAssets/ScrollView_Server/package-lock.json.meta
new file mode 100644
index 00000000..9592b6cf
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/package-lock.json.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 95e6348e2abe7c14db53f58f9d41129d
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/StreamingAssets/ScrollView_Server/package.json b/Assets/StreamingAssets/ScrollView_Server/package.json
new file mode 100644
index 00000000..309ce56c
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/package.json
@@ -0,0 +1,8 @@
+{
+  "dependencies": {
+    "three": "^0.172.0"
+  },
+  "devDependencies": {
+    "vite": "^6.0.11"
+  }
+}
diff --git a/Assets/StreamingAssets/ScrollView_Server/package.json.meta b/Assets/StreamingAssets/ScrollView_Server/package.json.meta
new file mode 100644
index 00000000..256cbe10
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/package.json.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: ee8e4c4eff362f64091b134f3c3ea0b9
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/StreamingAssets/ScrollView_Server/scrollView.html b/Assets/StreamingAssets/ScrollView_Server/scrollView.html
new file mode 100644
index 00000000..3063e3f4
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/scrollView.html
@@ -0,0 +1,181 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <meta charset="utf-8">
+    <title>Scroll View</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <style>
+        [dropzone] {
+            background-color: grey;
+            margin: 1px;
+            border-width: 1px;
+            border-style: dashed;
+        }
+
+        [data-fact-id] {
+            background-color: lightgray;
+        }
+
+        [data-hint-available] {
+            background-color: yellow
+        }
+
+        math {
+            display: inline-flex;
+            align-items: center;
+            flex-wrap: wrap;
+        }
+
+        .legacySlot {
+            width: 100px;
+            height: 100px;
+            margin: 50px;
+            border-width: 1px;
+        }
+
+        #rectangle {
+            width: 10px;
+            height: 10px;
+            position: absolute;
+            background-color: red;
+        }
+    </style>
+    <script src="jquery-3.7.1.slim.min.js"></script> 
+</head>
+
+<body>
+    <canvas id="math-mind-canvas" width="400" height="300"></canvas>
+    <div id="scrollContainer">
+        <scroll-description title='DefaultScroll' alt='No scroll loaded yet'>
+            <div>No scroll selected yet.</div>
+            <span>Given a triangle</span>
+            <math>
+                <mi>&xutri;<!-- △ --></mi>
+                <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?A"></mi>
+                <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?B"></mi>
+                <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"></mi>
+            </math>
+            <span>right-angled at</span>
+            <math>
+                <!--<mi>&angrtvbd;</mi>--><!-- ⦝ -->
+                <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC">
+                </mi>
+            </math>,<br />
+            <span>the opposite side has length</span>
+            <math>
+                <mi data-solution-id="http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA"></mi>
+                <mo>&equals;</mo>
+                <mrow>
+                    <mi>tan</mi>
+                    <!--<mo>&#8289;</mo>-->
+                    <mo>(</mo>
+                    <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB"></mi>
+                    <mo>)</mo>
+                </mrow>
+                <mo>&#8290;</mo>
+                <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC"></mi>
+            </math>
+            <span>.</span>
+            <div>
+                <svg width='50mm' height='45mm' viewBox='35 0 90 70' version='1.1' id='triangle'
+                    xmlns='http://www.w3.org/2000/svg' xmlns:svg='http://www.w3.org/2000/svg'>
+                    <g id='shape'>
+                        <path
+                            style='fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1'
+                            d='M 42.871972,64.67128 H 84.290656 V 7.6297578 Z' id='triangle' />
+                        <path id='angleABC'
+                            style='fill:none;stroke:#000000;stroke-width:0.265;stroke-dasharray:none;stroke-opacity:1'
+                            d='m 46.024276,60.304806 a 5.3589964,5.3589964 0 0 1 2.252109,4.366474 h -5.358996 z' />
+                        <g id='angleBCA'>
+                            <path
+                                style='fill:none;stroke:#000000;stroke-width:0.264999;stroke-dasharray:none;stroke-opacity:1'
+                                id='rightAngle'
+                                d='m 78.972396,64.665062 a 5.3308268,5.3308268 0 0 1 5.330827,-5.330827 v 5.330827 z' />
+                            <circle
+                                style='fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264999;stroke-dasharray:none;stroke-opacity:1'
+                                id='rightAngleDot' cx='82.081886' cy='62.813831' r='0.32113415' />
+                        </g>
+                    </g>
+                    <g id='labels'
+                        style='font-size:4.23333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583'>
+                        <text xml:space='preserve' x='39.242592' y='67.117035' id='pointB' style='fill:#0000ff'
+                            data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem?B'>${lverb B}</text>
+                        <text xml:space='preserve' x='85.100548' y='68.080437' id='pointC' style='fill:#0000ff'
+                            data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem?C'>${lverb C}</text>
+                        <text xml:space='preserve' x='84.650963' y='6.551136' id='pointA' style='fill:#0000ff'
+                            data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem?A'>${lverb A}</text>
+                        <text xml:space='preserve' x='48.234348' y='62.492699' id='angleAtB' style='fill:#ffcc00'
+                            data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB'>${lverb
+                            angleB}</text>
+                        <text xml:space='preserve' x='71.548683' y='60.951256' id='rightAngleAtC' style='fill:#ffcc00'
+                            data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC'>${lverb
+                            rightAngleC}</text>
+                        <text xml:space='preserve' x='59.409813' y='68.273117' id='distanceBC' style='fill:#008000'
+                            data-slot-id='http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC'>${lverb
+                            distanceBC}</text>
+                        <text xml:space='preserve' x='84.972092' y='35.260529' id='solutionCA' style='fill:#008000'
+                            data-solution-id='http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA'>${lverb
+                            deducedLineCA}</text>
+                    </g>
+                </svg>
+            </div>
+        </scroll-description>
+    </div>
+    <button type="button" title="Apply the scroll" onclick="applyScroll('')">Apply</button><br>
+    <p>You can right click on yellow slots to get a hint.</p>
+
+    <script id="load-other-scripts">
+        /** 
+         * Load all .js files for interactive scrolls. (So we can use e.g. Typescript)
+         * 
+         * This is no more dangerous than having this file in the streaming assets. 
+         * Any malicious code could just be written in here as well ¯\_(ツ)_/¯. 
+        */
+        function loadScript(url) {
+            const head = document.getElementsByTagName('head')[0];
+            const script = document.createElement('script');
+            script.type = 'text/javascript';
+            script.src = url;
+            head.appendChild(script);
+        }
+
+        loadScript("./scroll_interaction/Drop_facts.js")
+        loadScript("./scroll_interaction/SetScrollContent.js")
+        //loadScript("./scroll_interaction/webgl-demo.js")
+
+    </script>
+    <script src="./scroll_interaction/Math_Mind.js" type="module"></script>
+    <data id="Unity-Data-Interface" hidden
+        data-assignments='{&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem?A&quot;:{&quot;Item1&quot;:&quot;(C)&quot;,&quot;Item2&quot;:&quot;http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact310&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem?B&quot;:{&quot;Item1&quot;:&quot;(B)&quot;,&quot;Item2&quot;:&quot;http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact309&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem?C&quot;:{&quot;Item1&quot;:&quot;C&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC&quot;:{&quot;Item1&quot;:&quot;⊾C&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC&quot;:{&quot;Item1&quot;:&quot;BC&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB&quot;:{&quot;Item1&quot;:&quot;∠ABC&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA&quot;:{&quot;Item1&quot;:&quot;CA&quot;,&quot;Item2&quot;:&quot;&quot;}}' 
+        data-scroll-dynamic='{"ref":"http://mathhub.info/FrameIT/frameworld?OppositeLen","label":"OppositeLen","description":"<scroll-description title=&#x27;OppositeLenScroll&#x27; alt=&#x27;Given a triangle △ABC right-angled at ⊾C, the opposite side has length CA = tan(∠ABC) ⋅ BC.&#x27;>     <span>Given a triangle</span>       <math>           <mi>&xutri;<!-- △ --></mi>           <mi data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem?A&#x27;></mi>           <mi data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem?B&#x27;></mi>           <mi data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem?C&#x27;></mi>       </math>       <span>right-angled at</span>       <math>           <!--<mi>&angrtvbd;</mi>--><!-- ⦝ -->           <mi data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC&#x27;></mi>       </math>,<br />       <span>the opposite side has length</span>       <math>           <mi data-solution-id=&#x27;http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA&#x27;></mi>           <mo>&equals;</mo>           <mrow>               <mi>tan</mi>               <!--<mo>&#8289;</mo>-->               <mo>(</mo>               <mi data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB&#x27;></mi>               <mo>)</mo>           </mrow>           <mo>&#8290;</mo>           <mi data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC&#x27;></mi>       </math>       <span>.</span>       <div>           <svg           width=&#x27;50mm&#x27;           height=&#x27;45mm&#x27;           viewBox=&#x27;35 0 90 70&#x27;           version=&#x27;1.1&#x27;           id=&#x27;triangle&#x27;           xmlns=&#x27;http://www.w3.org/2000/svg&#x27;           xmlns:svg=&#x27;http://www.w3.org/2000/svg&#x27;>           <g id=&#x27;shape&#x27;>               <path                   style=&#x27;fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1&#x27;                   d=&#x27;M 42.871972,64.67128 H 84.290656 V 7.6297578 Z&#x27;                   id=&#x27;triangle&#x27; />               <path                   id=&#x27;angleABC&#x27;                   style=&#x27;fill:none;stroke:#000000;stroke-width:0.265;stroke-dasharray:none;stroke-opacity:1&#x27;                   d=&#x27;m 46.024276,60.304806 a 5.3589964,5.3589964 0 0 1 2.252109,4.366474 h -5.358996 z&#x27; />               <g                   id=&#x27;angleBCA&#x27;>                   <path                       style=&#x27;fill:none;stroke:#000000;stroke-width:0.264999;stroke-dasharray:none;stroke-opacity:1&#x27;                       id=&#x27;rightAngle&#x27;                       d=&#x27;m 78.972396,64.665062 a 5.3308268,5.3308268 0 0 1 5.330827,-5.330827 v 5.330827 z&#x27; />                   <circle                       style=&#x27;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264999;stroke-dasharray:none;stroke-opacity:1&#x27;                       id=&#x27;rightAngleDot&#x27;                       cx=&#x27;82.081886&#x27;                       cy=&#x27;62.813831&#x27;                       r=&#x27;0.32113415&#x27; />               </g>           </g>           <g               id=&#x27;labels&#x27;               style=&#x27;font-size:4.23333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583&#x27;           >               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;39.242592&#x27;                   y=&#x27;67.117035&#x27;                   id=&#x27;pointB&#x27;                   style=&#x27;fill:#0000ff&#x27;                   data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem?B&#x27;>B</text>               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;85.100548&#x27;                   y=&#x27;68.080437&#x27;                   id=&#x27;pointC&#x27;                   style=&#x27;fill:#0000ff&#x27;                   data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem?C&#x27;>C</text>               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;84.650963&#x27;                   y=&#x27;6.551136&#x27;                   id=&#x27;pointA&#x27;                   style=&#x27;fill:#0000ff&#x27;                   data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem?A&#x27;>A</text>               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;48.234348&#x27;                   y=&#x27;62.492699&#x27;                   id=&#x27;angleAtB&#x27;                   style=&#x27;fill:#ffcc00&#x27;                   data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB&#x27;>∠ABC</text>               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;71.548683&#x27;                   y=&#x27;60.951256&#x27;                   id=&#x27;rightAngleAtC&#x27;                   style=&#x27;fill:#ffcc00&#x27;                   data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC&#x27;>⊾C</text>               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;59.409813&#x27;                   y=&#x27;68.273117&#x27;                   id=&#x27;distanceBC&#x27;                   style=&#x27;fill:#008000&#x27;                   data-slot-id=&#x27;http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC&#x27;>BC</text>               <text                   xml:space=&#x27;preserve&#x27;                   x=&#x27;84.972092&#x27;                   y=&#x27;35.260529&#x27;                   id=&#x27;solutionCA&#x27;                   style=&#x27;fill:#008000&#x27;                   data-solution-id=&#x27;http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA&#x27;>CA</text>           </g>           </svg>       </div> </scroll-description>","requiredFacts":[{"tp":{"kind":"OMS","uri":"http://mathhub.info/MitM/core/geometry?3DGeometry?point"},"df":null,"ref":{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?A"},"kind":"general","label":"A"},{"tp":{"kind":"OMS","uri":"http://mathhub.info/MitM/core/geometry?3DGeometry?point"},"df":null,"ref":{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?B"},"kind":"general","label":"B"},{"tp":{"kind":"OMS","uri":"http://mathhub.info/MitM/core/geometry?3DGeometry?point"},"df":null,"ref":{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"},"kind":"general","label":"C"},{"tp":{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://mathhub.info/MitM/Foundation?Logic?ded"},"arguments":[{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://mathhub.info/MitM/Foundation?Logic?eq"},"arguments":[{"kind":"OMS","uri":"http://mathhub.info/MitM/Foundation?RealLiterals?real_lit"},{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://mathhub.info/MitM/core/geometry?Geometry/Common?angle_between"},"arguments":[{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?B"},{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"},{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?A"}]},{"kind":"OMLIT<Double>","type":"http://mathhub.info/MitM/Foundation?RealLiterals?real_lit","value":90.0}]}]},"df":null,"ref":{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC"},"kind":"general","label":"⊾C"},{"lhs":{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://mathhub.info/MitM/core/geometry?Geometry/Common?metric"},"arguments":[{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?B"},{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"}]},"valueTp":{"kind":"OMS","uri":"http://mathhub.info/MitM/Foundation?RealLiterals?real_lit"},"value":null,"proof":null,"ref":{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC"},"kind":"veq","label":"BC"},{"lhs":{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://mathhub.info/MitM/core/geometry?Geometry/Common?angle_between"},"arguments":[{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?A"},{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?B"},{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"}]},"valueTp":{"kind":"OMS","uri":"http://mathhub.info/MitM/Foundation?RealLiterals?real_lit"},"value":null,"proof":null,"ref":{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB"},"kind":"veq","label":"∠ABC"}],"acquiredFacts":[{"lhs":{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://mathhub.info/MitM/core/geometry?Geometry/Common?metric"},"arguments":[{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"},{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?A"}]},"valueTp":{"kind":"OMS","uri":"http://mathhub.info/MitM/Foundation?RealLiterals?real_lit"},"value":{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://mathhub.info/MitM/core/arithmetics?RealArithmetics?multiplication"},"arguments":[{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://mathhub.info/MitM/Foundation?Trigonometry?tan"},"arguments":[{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://gl.mathhub.info/MMT/LFX/Sigma?Symbols?Projl"},"arguments":[{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB"}]}]},{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://gl.mathhub.info/MMT/LFX/Sigma?Symbols?Projl"},"arguments":[{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC"}]}]},"proof":{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://mathhub.info/MitM/Foundation?InformalProofs?proofsketch"},"arguments":[{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://mathhub.info/MitM/Foundation?Logic?eq"},"arguments":[{"kind":"OMS","uri":"http://mathhub.info/MitM/Foundation?RealLiterals?real_lit"},{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://mathhub.info/MitM/core/geometry?Geometry/Common?metric"},"arguments":[{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"},{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem?A"}]},{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://mathhub.info/MitM/core/arithmetics?RealArithmetics?multiplication"},"arguments":[{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://mathhub.info/MitM/Foundation?Trigonometry?tan"},"arguments":[{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://gl.mathhub.info/MMT/LFX/Sigma?Symbols?Projl"},"arguments":[{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB"}]}]},{"kind":"OMA","applicant":{"kind":"OMS","uri":"http://gl.mathhub.info/MMT/LFX/Sigma?Symbols?Projl"},"arguments":[{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC"}]}]}]},{"kind":"OMLIT<String>","type":"http://cds.omdoc.org/urtheories?Strings?string","value":"OppositeLen Scroll"}]},"ref":{"kind":"OMS","uri":"http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA"},"kind":"veq","label":"CA"}],"name":"http://mathhub.info/FrameIT/frameworld?OppositeLen","path":null}'>hi</data>
+
+    <!--<script src="visualiseCursor.mjs" defer type="module"></script>-->
+    <!--<script>
+  /* mouse and pointer event handling */
+  const rectangle = document.createElement("div");
+  rectangle.id = "rectangle";
+  
+  console.log("appendChild to", document.body)
+  document.body.appendChild(rectangle);
+  
+  function followCursor(event) {
+  const cursorX = event.clientX;
+  const cursorY = event.clientY +5;
+  //console.log(`MouseEvent X: ${cursorX}, Y: ${cursorY}, Event type: ${event.type}`, event);
+  rectangle.style.left = `${cursorX}px`;
+  rectangle.style.top = `${cursorY}px`;
+  }
+  
+  document.addEventListener("mousemove", followCursor);
+  document.addEventListener("pointermove", followCursor);
+  
+  document.addEventListener("mouseover", followCursor);
+  document.addEventListener("pointerover", followCursor);
+  
+  document.addEventListener("mouseout", followCursor);
+  document.addEventListener("pointerout", followCursor);
+  </script>-->
+</body>
+
+</html>
\ No newline at end of file
diff --git a/Assets/StreamingAssets/StreamToDataPath_withHandler/scrollView.html.meta b/Assets/StreamingAssets/ScrollView_Server/scrollView.html.meta
similarity index 74%
rename from Assets/StreamingAssets/StreamToDataPath_withHandler/scrollView.html.meta
rename to Assets/StreamingAssets/ScrollView_Server/scrollView.html.meta
index 02831017..4f1f1bce 100644
--- a/Assets/StreamingAssets/StreamToDataPath_withHandler/scrollView.html.meta
+++ b/Assets/StreamingAssets/ScrollView_Server/scrollView.html.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 1d3e2132e24f19e41970733210b72ac6
+guid: 51b152fdcb0069c4f8be1d715abb767c
 DefaultImporter:
   externalObjects: {}
   userData: 
diff --git a/Assets/StreamingAssets/StreamToDataPath_withHandler/scroll_interaction.meta b/Assets/StreamingAssets/ScrollView_Server/scroll_interaction.meta
similarity index 77%
rename from Assets/StreamingAssets/StreamToDataPath_withHandler/scroll_interaction.meta
rename to Assets/StreamingAssets/ScrollView_Server/scroll_interaction.meta
index bc705e5d..84db5e89 100644
--- a/Assets/StreamingAssets/StreamToDataPath_withHandler/scroll_interaction.meta
+++ b/Assets/StreamingAssets/ScrollView_Server/scroll_interaction.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: c135f4fc25ecfc745a294bbcae38777f
+guid: 6c80f0cfb687586488462c73db884287
 folderAsset: yes
 DefaultImporter:
   externalObjects: {}
diff --git a/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/.SetScrollContent.js b/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/.SetScrollContent.js
new file mode 100644
index 00000000..7fcf8b06
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/.SetScrollContent.js
@@ -0,0 +1,33 @@
+let currentScrollRef = "" // ref of the scroll currently displayed 
+
+function RenderScroll() {
+    const scroll = JSON.parse(document.querySelector("#Unity-Data-Interface").dataset.scrollDynamic);
+    console.log(scroll.requiredFacts);
+    const scrollContainer = document.querySelector("#scrollContainer");
+
+    // replace the description if the scroll changed, otherwise only its content needs update
+    if (scroll.ref != currentScrollRef) {
+        currentScrollRef = scroll.ref;
+        scrollContainer.innerHTML = scroll.description;
+    }
+
+    // go through the facts in the scroll, show their labels and add dropzones
+    scroll.requiredFacts.forEach(fact => {
+        $("[data-slot-id='" + fact.ref.uri + "']")
+            .text(fact.label)
+            .attr("dropzone", "copy")
+            //.attr("data-fact-id", fact.df == null ? "" : fact.df.ref.uri)
+    })
+
+    // acquired facts only need updated labels
+    scroll.acquiredFacts.forEach(fact => {
+        $("[data-solution-id='" + fact.ref.uri + "']")
+            .text(fact.label)
+    })
+    console.log(scroll.label + 'Scroll rendered')
+}
+
+
+$(function () {
+    RenderScroll()
+});
\ No newline at end of file
diff --git a/Assets/StreamingAssets/StreamToDataPath_withHandler/scroll_interaction/Drop_facts.js b/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Drop_facts.js
similarity index 100%
rename from Assets/StreamingAssets/StreamToDataPath_withHandler/scroll_interaction/Drop_facts.js
rename to Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Drop_facts.js
diff --git a/Assets/StreamingAssets/StreamToDataPath_withHandler/scroll_interaction/Drop_facts.js.meta b/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Drop_facts.js.meta
similarity index 100%
rename from Assets/StreamingAssets/StreamToDataPath_withHandler/scroll_interaction/Drop_facts.js.meta
rename to Assets/StreamingAssets/ScrollView_Server/scroll_interaction/Drop_facts.js.meta
diff --git a/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/SetScrollContent.js b/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/SetScrollContent.js
new file mode 100644
index 00000000..b91bd379
--- /dev/null
+++ b/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/SetScrollContent.js
@@ -0,0 +1,28 @@
+
+function RenderScroll() {
+    const scrollContainer = document.querySelector("#scrollContainer");
+    const description = scrollContainer.textContent;
+    const assignments = JSON.parse(document.querySelector("#assignments").dataset.assignments)
+    console.log(assignments);
+
+    //everything that has a slotID is a scroll slot
+    scrollContainer.querySelectorAll("[data-slot-id]").forEach(element => {
+        //console.log(element);
+        let slotId = element.dataset.slotId;
+        let fact_assignment = assignments[slotId];
+
+        element.setAttribute("dropzone", "copy");
+        element.textContent = fact_assignment.Item1;
+
+        if (fact_assignment.Item2 != "") {
+            element.dataset.factId = fact_assignment.Item2;
+        }
+    });
+
+    //everything that has a solutionID is a scroll solution
+    scrollContainer.querySelectorAll("[data-solution-id]").forEach(element => {
+        element.textContent = assignments[element.dataset.solutionId].Item1;
+    })
+    console.log('Scroll rendered')
+}
+RenderScroll()
\ No newline at end of file
diff --git a/Assets/StreamingAssets/StreamToDataPath_withHandler/scroll_interaction/SetScrollContent.js.meta b/Assets/StreamingAssets/ScrollView_Server/scroll_interaction/SetScrollContent.js.meta
similarity index 100%
rename from Assets/StreamingAssets/StreamToDataPath_withHandler/scroll_interaction/SetScrollContent.js.meta
rename to Assets/StreamingAssets/ScrollView_Server/scroll_interaction/SetScrollContent.js.meta
diff --git a/Assets/StreamingAssets/StreamToDataPath_withHandler/scrollView.html b/Assets/StreamingAssets/StreamToDataPath_withHandler/scrollView.html
deleted file mode 100644
index 3c96afb8..00000000
--- a/Assets/StreamingAssets/StreamToDataPath_withHandler/scrollView.html
+++ /dev/null
@@ -1,212 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Scroll View</title>
-  <meta name="viewport" content="width=device-width, initial-scale=1.0">
-  <style>
-    [dropzone] {
-      background-color: grey;
-      margin: 1px;
-      border-width: 1px;
-      border-style: dashed;
-    }
-    [data-fact-id] {
-        background-color: lightgray;
-    }
-    [data-hint-available] {
-      background-color: yellow
-    }
-    math {
-      display: inline-flex;
-      align-items: center;
-      flex-wrap: wrap;
-    }
-    .legacySlot {
-      width: 100px;
-      height: 100px;
-      margin: 50px;
-      border-width: 1px;
-    }
-    #rectangle {
-      width: 10px;
-      height: 10px;
-      position: absolute;
-      background-color: red;
-    }
-  </style>
-</head>
-<body>
-  <div id="scrollContainer">
-    <div>No scroll selected</div>
-    <scroll-description title='OppositeLenScroll' alt='Given a triangle △A B C right-angled at ⊾C, the opposite side has length CA = tan(angleB) ⋅ BC.'>
-      <span>Given a triangle</span>
-      <math>
-          <mi>&xutri;<!-- △ --></mi>
-          <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?A"></mi>
-          <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?B"></mi>
-          <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem?C"></mi>
-      </math>
-      <span>right-angled at</span>
-      <math>
-          <!--<mi>&angrtvbd;</mi>--><!-- ⦝ -->
-          <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC"></mi>
-      </math>,<br />
-      <span>the opposite side has length</span>
-      <math>
-          <mi data-solution-id="http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA"></mi>
-          <mo>&equals;</mo>
-          <mrow>
-              <mi>tan</mi>
-              <!--<mo>&#8289;</mo>-->
-              <mo>(</mo>
-              <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB"></mi>
-              <mo>)</mo>
-          </mrow>
-          <mo>&#8290;</mo>
-          <mi data-slot-id="http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC"></mi>
-      </math>
-      <span>.</span>
-      <div>
-          <svg
-          width='50mm'
-          height='45mm'
-          viewBox='35 0 90 70'
-          version='1.1'
-          id='triangle'
-          xmlns='http://www.w3.org/2000/svg'
-          xmlns:svg='http://www.w3.org/2000/svg'>
-          <g id='shape'>
-              <path
-                  style='fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1'
-                  d='M 42.871972,64.67128 H 84.290656 V 7.6297578 Z'
-                  id='triangle' />
-              <path
-                  id='angleABC'
-                  style='fill:none;stroke:#000000;stroke-width:0.265;stroke-dasharray:none;stroke-opacity:1'
-                  d='m 46.024276,60.304806 a 5.3589964,5.3589964 0 0 1 2.252109,4.366474 h -5.358996 z' />
-              <g
-                  id='angleBCA'>
-                  <path
-                      style='fill:none;stroke:#000000;stroke-width:0.264999;stroke-dasharray:none;stroke-opacity:1'
-                      id='rightAngle'
-                      d='m 78.972396,64.665062 a 5.3308268,5.3308268 0 0 1 5.330827,-5.330827 v 5.330827 z' />
-                  <circle
-                      style='fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264999;stroke-dasharray:none;stroke-opacity:1'
-                      id='rightAngleDot'
-                      cx='82.081886'
-                      cy='62.813831'
-                      r='0.32113415' />
-              </g>
-          </g>
-          <g
-              id='labels'
-              style='font-size:4.23333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;stroke-width:0.264583'
-          >
-              <text
-                  xml:space='preserve'
-                  x='39.242592'
-                  y='67.117035'
-                  id='pointB'
-                  style='fill:#0000ff'
-                  data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem?B'>${lverb B}</text>
-              <text
-                  xml:space='preserve'
-                  x='85.100548'
-                  y='68.080437'
-                  id='pointC'
-                  style='fill:#0000ff'
-                  data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem?C'>${lverb C}</text>
-              <text
-                  xml:space='preserve'
-                  x='84.650963'
-                  y='6.551136'
-                  id='pointA'
-                  style='fill:#0000ff'
-                  data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem?A'>${lverb A}</text>
-              <text
-                  xml:space='preserve'
-                  x='48.234348'
-                  y='62.492699'
-                  id='angleAtB'
-                  style='fill:#ffcc00'
-                  data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB'>${lverb angleB}</text>
-              <text
-                  xml:space='preserve'
-                  x='71.548683'
-                  y='60.951256'
-                  id='rightAngleAtC'
-                  style='fill:#ffcc00'
-                  data-slot-id='http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC'>${lverb rightAngleC}</text>
-              <text
-                  xml:space='preserve'
-                  x='59.409813'
-                  y='68.273117'
-                  id='distanceBC'
-                  style='fill:#008000'
-                  data-slot-id='http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC'>${lverb distanceBC}</text>
-              <text
-                  xml:space='preserve'
-                  x='84.972092'
-                  y='35.260529'
-                  id='solutionCA'
-                  style='fill:#008000'
-                  data-solution-id='http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA'>${lverb deducedLineCA}</text>
-          </g>
-          </svg>
-      </div>
-  </scroll-description>
-  </div>
-  <button type="button" title="Apply the scroll" onclick="applyScroll('')">Apply</button><br>
-  <p>You can right click on yellow slots to get a hint.</p>
-
-  <script>  
-    /** 
-     * Load all .js files for interactive scrolls. (So we can use e.g. Typescript)
-     * 
-     * This is no more dangerous than having this file in the streaming assets. 
-     * Any malicious code could just be written in here as well ¯\_(ツ)_/¯. 
-    */
-    function loadScript(url)
-    {    
-        const head = document.getElementsByTagName('head')[0];
-        const script = document.createElement('script');
-        script.type = 'text/javascript';
-        script.src = url;
-        head.appendChild(script);
-    }
-
-    loadScript("./scroll_interaction/Drop_facts.js")
-    loadScript("./scroll_interaction/SetScrollContent.js")
-
-  </script>
-  <data id="assignments" hidden data-assignments="{&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem?A&quot;:{&quot;Item1&quot;:&quot;(C)&quot;,&quot;Item2&quot;:&quot;http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact310&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem?B&quot;:{&quot;Item1&quot;:&quot;(B)&quot;,&quot;Item2&quot;:&quot;http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact309&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem?C&quot;:{&quot;Item1&quot;:&quot;C&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem_RightAngleAtC?rightAngleC&quot;:{&quot;Item1&quot;:&quot;⊾C&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?OppositeLen/Problem?distanceBC&quot;:{&quot;Item1&quot;:&quot;BC&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?TriangleProblem_AngleAtB?angleB&quot;:{&quot;Item1&quot;:&quot;∠ABC&quot;,&quot;Item2&quot;:&quot;&quot;},&quot;http://mathhub.info/FrameIT/frameworld?OppositeLen/Solution?deducedLineCA&quot;:{&quot;Item1&quot;:&quot;CA&quot;,&quot;Item2&quot;:&quot;&quot;}}">hi</data>
-  
-  <!--<script src="visualiseCursor.mjs" defer type="module"></script>-->
-  <!--<script>
-  /* mouse and pointer event handling */
-  const rectangle = document.createElement("div");
-  rectangle.id = "rectangle";
-  
-  console.log("appendChild to", document.body)
-  document.body.appendChild(rectangle);
-  
-  function followCursor(event) {
-  const cursorX = event.clientX;
-  const cursorY = event.clientY +5;
-  //console.log(`MouseEvent X: ${cursorX}, Y: ${cursorY}, Event type: ${event.type}`, event);
-  rectangle.style.left = `${cursorX}px`;
-  rectangle.style.top = `${cursorY}px`;
-  }
-  
-  document.addEventListener("mousemove", followCursor);
-  document.addEventListener("pointermove", followCursor);
-  
-  document.addEventListener("mouseover", followCursor);
-  document.addEventListener("pointerover", followCursor);
-  
-  document.addEventListener("mouseout", followCursor);
-  document.addEventListener("pointerout", followCursor);
-  </script>-->
-</body>
-</html>
diff --git a/Assets/StreamingAssets/StreamToDataPath_withHandler/scroll_interaction/SetScrollContent.js b/Assets/StreamingAssets/StreamToDataPath_withHandler/scroll_interaction/SetScrollContent.js
deleted file mode 100644
index f206f4fe..00000000
--- a/Assets/StreamingAssets/StreamToDataPath_withHandler/scroll_interaction/SetScrollContent.js
+++ /dev/null
@@ -1,67 +0,0 @@
-
-function RenderScroll() {
-    const scrollContainer = document.querySelector("#scrollContainer");
-    const description = scrollContainer.textContent;
-    const assignments = JSON.parse(document.querySelector("#assignments").dataset.assignments)
-    console.log(assignments);
-
-    //everything that has a slotID is a scroll slot
-    scrollContainer.querySelectorAll("[data-slot-id]").forEach(element => {
-        //console.log(element);
-        let slotId = element.dataset.slotId;
-        let fact_assignment = assignments[slotId];
-
-        element.setAttribute("dropzone", "copy");
-        element.textContent = fact_assignment.Item1;
-
-        if (fact_assignment.Item2 != "") {
-            element.dataset.factId = fact_assignment.Item2;
-        }
-    });
-
-    //everything that has a solutionID is a scroll solution
-    scrollContainer.querySelectorAll("[data-solution-id]").forEach(element => {
-        element.textContent = assignments[element.dataset.solutionId].Item1;
-    })
-    console.log('Scroll rendered')
-}
-RenderScroll()
-// if (Regex.IsMatch(description, ".*<scroll-description.*"))
-// {
-//     // replace slot templates
-//     description = Regex.Replace(description, "<scroll-slot([^>]*)>([^<]*)</scroll-slot>", match =>
-//     {
-//         var extraAttributes = match.Groups[1].Value;
-//         var slotId = match.Groups[2].Value;
-//         var assignment = SwitchScrollUI.activeScrollData.Assignments[slotId];
-//         /** label of the assigned fact, or the slot label if nothing assigned */
-//         var label = assignment.IsSet    ? assignment.fact.GetLabel(StageStatic.stage.factState)
-//                                         : scroll.requiredFacts.Find(fact => fact.@ref.uri == slotId).label;
-//         /** id of the assigned fact. If nothing is assigned don't add the attribute */
-//         var fact_id = assignment.IsSet  ? $"data-fact-id='{assignment.fact.Id}'"
-//                                         : "";
-//         return $"<mi dropzone='copy' data-slot-id='{slotId}' {fact_id} {extraAttributes}>{label}</mi>";
-//     });
-//     // replace solution templates
-//     description = Regex.Replace(description, "<scroll-solution([^>]*)>([^<]*)</scroll-solution>", match =>
-//     {
-//         var extraAttributes = match.Groups[1].Value;
-//         var solutionId = match.Groups[2].Value;
-//         var label = scroll.acquiredFacts.Find(fact => fact.@ref.uri == solutionId).label;
-//         return $"<mi data-solution-id='{solutionId}' {extraAttributes}>{label}</mi>";
-//     });
-// }
-// else
-// {
-//     // scroll is a legacy plain text scroll, generate html with slots for the required facts
-//     var factSlots = SwitchScrollUI.activeScrollData.Assignments
-//         .Where(pair => pair.Value.IsVisible)
-//         .Select(pair =>
-//             @$"<span class='legacySlot' dropzone='copy' data-slot-id='{pair.Key}' {(pair.Value.IsSet ? $"data-fact-id='{pair.Value.fact.Id}'" : "")}>
-//                 {(pair.Value.IsSet ?
-//                     pair.Value.fact.GetLabel(StageStatic.stage.factState) :
-//                     scroll.requiredFacts.Find(fact => fact.@ref.uri == pair.Key).label )}
-//             </span>");
-
-//     description = $"<scroll-description><p>{scroll.description}</p><div id='legacySlots'>{String.Join("", factSlots)}</div></scroll-description>";
-// }
\ No newline at end of file
-- 
GitLab