Repository: compiler-explorer/compiler-explorer
Pull request #7223 (2024-12-15 08:12:02)

Set MSVC default option to /utf-8, remove it if the user specified /source-charset or /execution-charset
Following the discussion in #7164.
@partouf I believe this would solve also linkage against windows libs built with /utf-8




Patch:
diff --git a/.github/labeler.yml b/.github/labeler.yml
index deb8285a4..6ea83bdd5 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -278,13 +278,6 @@
           - 'etc/config/ocaml.*.properties'
           - 'static/modes/ocaml-mode.ts'
 
-'lang-odin':
-  - changed-files:
-      - any-glob-to-any-file:
-          - 'lib/compilers/odin.ts'
-          - 'etc/config/odin.*.properties'
-          - 'static/modes/odin-mode.ts'
-
 'lang-opencl-c':
   - changed-files:
       - any-glob-to-any-file:
@@ -334,12 +327,6 @@
           - 'lib/compilers/scala.ts'
           - 'etc/config/scala.*.properties'
 
-'lang-slang':
-  - changed-files:
-      - any-glob-to-any-file:
-          - 'lib/compilers/slang.ts'
-          - 'etc/config/slang.*.properties'
-
 'lang-solidity':
   - changed-files:
       - any-glob-to-any-file:
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index b45b4e925..c7ede3ae7 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -150,5 +150,3 @@ From oldest to newest contributor, we would like to thank:
 - [Nicholas Hubbard](https://github.com/nhubbard)
 - [Detjon Mataj](https://github.com/detjonmataj)
 - [Pierre Bayerl](https://github.com/goto40)
-- [James Touton](https://github.com/Bekenn)
-- [Waqar Ahmed](https://github.com/waqar144)
diff --git a/Makefile b/Makefile
index d21735146..291f11f94 100644
--- a/Makefile
+++ b/Makefile
@@ -8,10 +8,7 @@ NODE:=node-not-found
 NPM:=npm-not-found
 NODE_MODULES:=./node_modules/.npm-updated
 NODE_ARGS?=
-TS_NODE_ARGS:=--no-warnings=ExperimentalWarning --import=tsx
-
-# All file paths that are not .ts files that should be watched for changes if launched with watch.
-FILEWATCHER_ARGS:=--watch --include "etc/config/*"
+TS_NODE_ARGS:=--no-warnings=ExperimentalWarning --loader ts-node/esm
 
 # These 'find' scripts cache their results in a dotfile.
 # Doing it this way instead of NODE:=$(shell etc/script/find-node) means
@@ -97,15 +94,15 @@ run:  ## Runs the site like it runs in production
 
 .PHONY: dev
 dev: prereqs ## Runs the site as a developer; including live reload support and installation of git hooks
-	NODE_OPTIONS="$(TS_NODE_ARGS) $(NODE_ARGS)" ./node_modules/.bin/tsx watch $(FILEWATCHER_ARGS) ./app.ts $(EXTRA_ARGS)
+	NODE_OPTIONS="$(TS_NODE_ARGS) $(NODE_ARGS)" ./node_modules/.bin/supervisor -w app.ts,lib,etc/config,static/tsconfig.json -e 'js|ts|node|properties|yaml' -n exit --exec $(NODE) -- ./app.ts $(EXTRA_ARGS)
 
 .PHONY: gpu-dev
 gpu-dev: prereqs ## Runs the site as a developer; including live reload support and installation of git hooks
-	NODE_OPTIONS="$(TS_NODE_ARGS) $(NODE_ARGS)" ./node_modules/.bin/tsx watch $(FILEWATCHER_ARGS) ./app.ts --env gpu $(EXTRA_ARGS)
+	NODE_OPTIONS="$(TS_NODE_ARGS) $(NODE_ARGS)" ./node_modules/.bin/supervisor -w app.ts,lib,etc/config,static/tsconfig.json -e 'js|ts|node|properties|yaml' -n exit --exec $(NODE) -- ./app.ts --env gpu $(EXTRA_ARGS)
 
 .PHONY: debug
 debug: prereqs ## Runs the site as a developer with full debugging; including live reload support and installation of git hooks
-	NODE_OPTIONS="$(TS_NODE_ARGS) $(NODE_ARGS) --inspect 9229" ./node_modules/.bin/tsx watch $(FILEWATCHER_ARGS) ./app.ts --debug $(EXTRA_ARGS)
+	NODE_OPTIONS="$(TS_NODE_ARGS) $(NODE_ARGS) --inspect 9229" ./node_modules/.bin/supervisor -w app.ts,lib,etc/config,static/tsconfig.json -e 'js|ts|node|properties|yaml' -n exit --exec $(NODE) -- ./app.ts --debug $(EXTRA_ARGS)
 
 .PHONY:
 asm-docs:
diff --git a/app.ts b/app.ts
index 73aea33ab..7c805cafd 100755
--- a/app.ts
+++ b/app.ts
@@ -29,6 +29,7 @@ import process from 'process';
 import url from 'url';
 
 import * as Sentry from '@sentry/node';
+import bodyParser from 'body-parser';
 import compression from 'compression';
 import express from 'express';
 import fs from 'fs-extra';
@@ -524,7 +525,6 @@ async function main() {
     // Initialise express and then sentry. Sentry as early as possible to catch errors during startup.
     const webServer = express(),
         router = express.Router();
-
     SetupSentry(aws.getConfig('sentryDsn'), ceProps, releaseBuildNumber, gitReleaseName, defArgs);
 
     startWineInit();
@@ -848,7 +848,7 @@ async function main() {
                 ),
             );
         })
-        .use(express.json({limit: ceProps('bodyParserLimit', maxUploadSize)}))
+        .use(bodyParser.json({limit: ceProps('bodyParserLimit', maxUploadSize)}))
         .use(siteTemplateController.createRouter())
         .use(sourceController.createRouter())
         .use(assemblyDocumentationController.createRouter())
diff --git a/compiler-args-app.ts b/compiler-args-app.ts
index 17f5f4031..5f2517955 100644
--- a/compiler-args-app.ts
+++ b/compiler-args-app.ts
@@ -149,7 +149,7 @@ class CompilerArgsApp {
 if (!opts.parser || !opts.exe) {
     console.error(
         'Usage: ' +
-            'node --no-warnings=ExperimentalWarning --import=tsx compiler-args-app.ts ' +
+            'node --no-warnings=ExperimentalWarning --loader ts-node/esm compiler-args-app.ts ' +
             '--parser=<compilertype> --exe=<path> [--padding=<number>]\n' +
             'for example: --parser=clang --exe=/opt/compiler-explorer/clang-15.0.0/bin/clang++ --padding=50',
     );
diff --git a/docs/AddingASiteTemplate.md b/docs/AddingASiteTemplate.md
index c912283f4..64592a807 100644
--- a/docs/AddingASiteTemplate.md
+++ b/docs/AddingASiteTemplate.md
@@ -1,17 +1,14 @@
 # Adding a new site template
 
-Site templates are configured in [`etc/config/site-templates.yaml`](../etc/config/site-templates.yaml).
+Site templates are configured in [`etc/config/site-templates.conf`](../etc/config/site-templates.conf).
 
-The configuration is a list of site templates each having a name and a raw configuration string. Use the following steps
-to create the configuration string:
+The configuration format is `Template Name=Godbolt.org full link`.
 
-1. [Compiler Explorer](https://godbolt.org) and configure the setup you want to export as a template
-2. Click the "Share" dropdown in the top-right corner of the page
-3. Select the "Copy full link" option
-4. Strip the "https://godbolt.org/#" prefix from the link
-5. Paste the configuration string into your new entry in the templates list.
+To create a site template:
 
-After you have created a new site template, you can generate screenshots using Puppeteer.
+- Setup the template on [https://godbolt.org](https://godbolt.org)
+- Export with a full link from the "Share" dropdown in the top-right corner of the page
+- Add to the config file
 
 ## Screenshot generation
 
@@ -24,7 +21,7 @@ Site template screenshots are generated with a hacky script located at
 To run the script, `cd` to the `etc/scripts/` directory and run
 
 ```bash
-npm i puppeteer --no-save && npx node --no-warnings=ExperimentalWarning --import=tsx generate_site_template_screenshots.ts
+npm i puppeteer --no-save && npx node --no-warnings=ExperimentalWarning --loader ts-node/esm generate_site_template_screenshots.ts
 ```
 
 The script uses puppeteer and chrome to generate screenshots. The script will take a little while to run as it generates
diff --git a/etc/config/ada.amazon.properties b/etc/config/ada.amazon.properties
index f159240a5..2d3af55e2 100644
--- a/etc/config/ada.amazon.properties
+++ b/etc/config/ada.amazon.properties
@@ -7,7 +7,7 @@ compilerType=ada
 
 ###############################
 # GCC (as in GNU Compiler Collection) for x86
-group.gnat.compilers=&gnatassert:gnat82:gnat95:gnat102:gnat104:gnat105:gnat111:gnat112:gnat113:gnat114:gnat121:gnat122:gnat123:gnat124:gnat131:gnat132:gnat133:gnat141:gnat142:gnatsnapshot
+group.gnat.compilers=gnat82:gnat95:gnat102:gnat104:gnat105:gnat111:gnat112:gnat113:gnat114:gnat121:gnat122:gnat123:gnat124:gnat131:gnat132:gnat133:gnat141:gnat142:gnatsnapshot
 group.gnat.intelAsm=-masm=intel
 group.gnat.groupName=X86-64 GNAT
 group.gnat.baseName=x86-64 gnat
@@ -65,42 +65,6 @@ compiler.gnatsnapshot.demangler=/opt/compiler-explorer/gcc-snapshot/bin/c++filt
 compiler.gnatsnapshot.objdumper=/opt/compiler-explorer/gcc-snapshot/bin/objdump
 compiler.gnatsnapshot.semver=(trunk)
 
-## GNAT x86 build with "assertions" (--enable-checking=XXX)
-group.gnatassert.compilers=gnat104assert:gnat105assert:gnat111assert:gnat112assert:gnat113assert:gnat114assert:gnat121assert:gnat122assert:gnat123assert:gnat124assert:gnat131assert:gnat132assert:gnat133assert:gnat141assert:gnat142assert
-group.gnatassert.groupName=GCC x86-64 (assertions)
-
-compiler.gnat104assert.exe=/opt/compiler-explorer/gcc-assertions-10.4.0/bin/gnatmake
-compiler.gnat104assert.semver=10.4 (assertions)
-compiler.gnat105assert.exe=/opt/compiler-explorer/gcc-assertions-10.5.0/bin/gnatmake
-compiler.gnat105assert.semver=10.5 (assertions)
-compiler.gnat111assert.exe=/opt/compiler-explorer/gcc-assertions-11.1.0/bin/gnatmake
-compiler.gnat111assert.semver=11.1 (assertions)
-compiler.gnat112assert.exe=/opt/compiler-explorer/gcc-assertions-11.2.0/bin/gnatmake
-compiler.gnat112assert.semver=11.2 (assertions)
-compiler.gnat113assert.exe=/opt/compiler-explorer/gcc-assertions-11.3.0/bin/gnatmake
-compiler.gnat113assert.semver=11.3 (assertions)
-compiler.gnat114assert.exe=/opt/compiler-explorer/gcc-assertions-11.4.0/bin/gnatmake
-compiler.gnat114assert.semver=11.4 (assertions)
-compiler.gnat121assert.exe=/opt/compiler-explorer/gcc-assertions-12.1.0/bin/gnatmake
-compiler.gnat121assert.semver=12.1 (assertions)
-compiler.gnat122assert.exe=/opt/compiler-explorer/gcc-assertions-12.2.0/bin/gnatmake
-compiler.gnat122assert.semver=12.2 (assertions)
-compiler.gnat123assert.exe=/opt/compiler-explorer/gcc-assertions-12.3.0/bin/gnatmake
-compiler.gnat123assert.semver=12.3 (assertions)
-compiler.gnat124assert.exe=/opt/compiler-explorer/gcc-assertions-12.4.0/bin/gnatmake
-compiler.gnat124assert.semver=12.4 (assertions)
-compiler.gnat131assert.exe=/opt/compiler-explorer/gcc-assertions-13.1.0/bin/gnatmake
-compiler.gnat131assert.semver=13.1 (assertions)
-compiler.gnat132assert.exe=/opt/compiler-explorer/gcc-assertions-13.2.0/bin/gnatmake
-compiler.gnat132assert.semver=13.2 (assertions)
-compiler.gnat133assert.exe=/opt/compiler-explorer/gcc-assertions-13.3.0/bin/gnatmake
-compiler.gnat133assert.semver=13.3 (assertions)
-compiler.gnat141assert.exe=/opt/compiler-explorer/gcc-assertions-14.1.0/bin/gnatmake
-compiler.gnat141assert.semver=14.1 (assertions)
-compiler.gnat142assert.exe=/opt/compiler-explorer/gcc-assertions-14.2.0/bin/gnatmake
-compiler.gnat142assert.semver=14.2 (assertions)
-
-
 ################################
 # Cross GNAT
 group.gnatcross.compilers=&gnatloongarch64:&gnatriscv64:&gnatarm:&gnatarm64:&gnats390x:&gnatmipss:&gnatppcs:&gnatsparcs:&gnatsparc64s:&gnatsparcleons:&gnathppa
diff --git a/etc/config/android-java.amazon.properties b/etc/config/android-java.amazon.properties
index a29ead7d5..291557d12 100644
--- a/etc/config/android-java.amazon.properties
+++ b/etc/config/android-java.amazon.properties
@@ -1,4 +1,4 @@
-compilers=&android-d8:&android-r8:&dex2oat:&android-openjdk
+compilers=&android-d8:&android-r8:&dex2oat
 
 group.android-d8.compilers=java-d8-8156:java-d8-8172:java-d8-8233:java-d8-8242:java-d8-8247:java-d8-8336:java-d8-8337:java-d8-8510:java-d8-8527:java-d8-8535
 group.android-d8.compilerType=android-d8
@@ -139,105 +139,6 @@ compiler.java-dex2oat-3310.objdumper=/opt/compiler-explorer/dex2oat-33.10/x86_64
 compiler.java-dex2oat-3310.d8Id=java-d8-8242
 compiler.java-dex2oat-3310.profmanPath=/opt/compiler-explorer/dex2oat-33.10/x86_64/bin/profman
 
-group.android-openjdk.compilers=android-openjdk-1102:android-openjdk-1201:android-openjdk-1202:android-openjdk-1302:android-openjdk-1402:android-openjdk-1502:android-openjdk-1601:android-openjdk-1700:android-openjdk-1702:android-openjdk-1800:android-openjdk-1802:android-openjdk-1902:android-openjdk-2000:android-openjdk-2002:android-openjdk-2100:android-openjdk-2102:android-openjdk-2200
-group.android-openjdk.compilerType=java
-group.android-openjdk.versionFlag=-version
-group.android-openjdk.groupName=OpenJDK
-group.android-openjdk.demangler=
-group.android-openjdk.postProcess=
-group.android-openjdk.options=
-group.android-openjdk.supportsBinary=false
-group.android-openjdk.needsMulti=false
-group.android-openjdk.supportsExecute=true
-group.android-openjdk.interpreted=true
-group.android-openjdk.isSemVer=true
-group.android-openjdk.baseName=jdk
-
-compiler.android-openjdk-2200.exe=/opt/compiler-explorer/jdk-22.0.0/bin/javac
-compiler.android-openjdk-2200.objdumper=/opt/compiler-explorer/jdk-22.0.0/bin/javap
-compiler.android-openjdk-2200.runtime=/opt/compiler-explorer/jdk-22.0.0/bin/java
-compiler.android-openjdk-2200.semver=22.0.0
-
-compiler.android-openjdk-2102.exe=/opt/compiler-explorer/jdk-21.0.2/bin/javac
-compiler.android-openjdk-2102.objdumper=/opt/compiler-explorer/jdk-21.0.2/bin/javap
-compiler.android-openjdk-2102.runtime=/opt/compiler-explorer/jdk-21.0.2/bin/java
-compiler.android-openjdk-2102.semver=21.0.2
-
-compiler.android-openjdk-2100.exe=/opt/compiler-explorer/jdk-21.0.0/bin/javac
-compiler.android-openjdk-2100.objdumper=/opt/compiler-explorer/jdk-21.0.0/bin/javap
-compiler.android-openjdk-2100.runtime=/opt/compiler-explorer/jdk-21.0.0/bin/java
-compiler.android-openjdk-2100.semver=21.0.0
-
-compiler.android-openjdk-2002.exe=/opt/compiler-explorer/jdk-20.0.2/bin/javac
-compiler.android-openjdk-2002.objdumper=/opt/compiler-explorer/jdk-20.0.2/bin/javap
-compiler.android-openjdk-2002.runtime=/opt/compiler-explorer/jdk-20.0.2/bin/java
-compiler.android-openjdk-2002.semver=20.0.2
-
-compiler.android-openjdk-2000.exe=/opt/compiler-explorer/jdk-20.0.0/bin/javac
-compiler.android-openjdk-2000.objdumper=/opt/compiler-explorer/jdk-20.0.0/bin/javap
-compiler.android-openjdk-2000.runtime=/opt/compiler-explorer/jdk-20.0.0/bin/java
-compiler.android-openjdk-2000.semver=20.0.0
-
-compiler.android-openjdk-1902.exe=/opt/compiler-explorer/jdk-19.0.2/bin/javac
-compiler.android-openjdk-1902.objdumper=/opt/compiler-explorer/jdk-19.0.2/bin/javap
-compiler.android-openjdk-1902.runtime=/opt/compiler-explorer/jdk-19.0.2/bin/java
-compiler.android-openjdk-1902.semver=19.0.2
-
-compiler.android-openjdk-1802.exe=/opt/compiler-explorer/jdk-18.0.2/bin/javac
-compiler.android-openjdk-1802.objdumper=/opt/compiler-explorer/jdk-18.0.2/bin/javap
-compiler.android-openjdk-1802.runtime=/opt/compiler-explorer/jdk-18.0.2/bin/java
-compiler.android-openjdk-1802.semver=18.0.2
-
-compiler.android-openjdk-1800.exe=/opt/compiler-explorer/jdk-18.0.0/bin/javac
-compiler.android-openjdk-1800.objdumper=/opt/compiler-explorer/jdk-18.0.0/bin/javap
-compiler.android-openjdk-1800.runtime=/opt/compiler-explorer/jdk-18.0.0/bin/java
-compiler.android-openjdk-1800.semver=18.0.0
-
-compiler.android-openjdk-1702.exe=/opt/compiler-explorer/jdk-17.0.2/bin/javac
-compiler.android-openjdk-1702.objdumper=/opt/compiler-explorer/jdk-17.0.2/bin/javap
-compiler.android-openjdk-1702.runtime=/opt/compiler-explorer/jdk-17.0.2/bin/java
-compiler.android-openjdk-1702.semver=17.0.2
-
-compiler.android-openjdk-1700.exe=/opt/compiler-explorer/jdk-17.0.0/bin/javac
-compiler.android-openjdk-1700.objdumper=/opt/compiler-explorer/jdk-17.0.0/bin/javap
-compiler.android-openjdk-1700.runtime=/opt/compiler-explorer/jdk-17.0.0/bin/java
-compiler.android-openjdk-1700.semver=17.0.0
-
-compiler.android-openjdk-1601.exe=/opt/compiler-explorer/jdk-16.0.1/bin/javac
-compiler.android-openjdk-1601.objdumper=/opt/compiler-explorer/jdk-16.0.1/bin/javap
-compiler.android-openjdk-1601.runtime=/opt/compiler-explorer/jdk-16.0.1/bin/java
-compiler.android-openjdk-1601.semver=16.0.1
-
-compiler.android-openjdk-1502.exe=/opt/compiler-explorer/jdk-15.0.2/bin/javac
-compiler.android-openjdk-1502.objdumper=/opt/compiler-explorer/jdk-15.0.2/bin/javap
-compiler.android-openjdk-1502.runtime=/opt/compiler-explorer/jdk-15.0.2/bin/java
-compiler.android-openjdk-1502.semver=15.0.2
-
-compiler.android-openjdk-1402.exe=/opt/compiler-explorer/jdk-14.0.2/bin/javac
-compiler.android-openjdk-1402.objdumper=/opt/compiler-explorer/jdk-14.0.2/bin/javap
-compiler.android-openjdk-1402.runtime=/opt/compiler-explorer/jdk-14.0.2/bin/java
-compiler.android-openjdk-1402.semver=14.0.2
-
-compiler.android-openjdk-1302.exe=/opt/compiler-explorer/jdk-13.0.2/bin/javac
-compiler.android-openjdk-1302.objdumper=/opt/compiler-explorer/jdk-13.0.2/bin/javap
-compiler.android-openjdk-1302.runtime=/opt/compiler-explorer/jdk-13.0.2/bin/java
-compiler.android-openjdk-1302.semver=13.0.2
-
-compiler.android-openjdk-1202.exe=/opt/compiler-explorer/jdk-12.0.2/bin/javac
-compiler.android-openjdk-1202.objdumper=/opt/compiler-explorer/jdk-12.0.2/bin/javap
-compiler.android-openjdk-1202.runtime=/opt/compiler-explorer/jdk-12.0.2/bin/java
-compiler.android-openjdk-1202.semver=12.0.2
-
-compiler.android-openjdk-1201.exe=/opt/compiler-explorer/jdk-12.0.1/bin/javac
-compiler.android-openjdk-1201.objdumper=/opt/compiler-explorer/jdk-12.0.1/bin/javap
-compiler.android-openjdk-1201.runtime=/opt/compiler-explorer/jdk-12.0.1/bin/java
-compiler.android-openjdk-1201.semver=12.0.1
-
-compiler.android-openjdk-1102.exe=/opt/compiler-explorer/jdk-11.0.2/bin/javac
-compiler.android-openjdk-1102.objdumper=/opt/compiler-explorer/jdk-11.0.2/bin/javap
-compiler.android-openjdk-1102.runtime=/opt/compiler-explorer/jdk-11.0.2/bin/java
-compiler.android-openjdk-1102.semver=11.0.2
-
 defaultCompiler=java-dex2oat-latest
 
 libs=android-api-stubs:r8-keepanno:androidx-annotation
diff --git a/etc/config/c++.amazon.properties b/etc/config/c++.amazon.properties
index 81943a473..562f3eba5 100644
--- a/etc/config/c++.amazon.properties
+++ b/etc/config/c++.amazon.properties
@@ -17,7 +17,7 @@ llvmDisassembler=/opt/compiler-explorer/clang-18.1.0/bin/llvm-dis
 
 ###############################
 # GCC for x86
-group.gcc86.compilers=&gcc86assert:g346:g404:g412:g447:g453:g464:g471:g472:g473:g474:g481:g482:g483:g484:g485:g490:g491:g492:g493:g494:g510:g520:g530:g540:g550:g6:g62:g63:g64:g65:g71:g72:g73:g74:g75:g81:g82:g83:g84:g85:g91:g92:g93:g94:g95:g101:g102:g103:g104:g105:g111:g112:g113:g114:g121:g122:g123:g124:g131:g132:g133:g141:g142:gsnapshot:gcontracts-trunk:gcontract-labels-trunk:gcontracts-nonattr-trunk:gcxx-modules-trunk:gcxx-coroutines-trunk:gcc-embed-trunk:gcc-static-analysis-trunk
+group.gcc86.compilers=g346:g404:g412:g447:g453:g464:g471:g472:g473:g474:g481:g482:g483:g484:g485:g490:g491:g492:g493:g494:g510:g520:g530:g540:g550:g6:g62:g63:g64:g65:g71:g72:g73:g74:g75:g81:g82:g83:g84:g85:g91:g92:g93:g94:g95:g101:g102:g103:g104:g105:g111:g112:g113:g114:g121:g122:g123:g124:g131:g132:g133:g141:g142:gsnapshot:gcontracts-trunk:gcontract-labels-trunk:gcontracts-nonattr-trunk:gcxx-modules-trunk:gcxx-coroutines-trunk:gcc-embed-trunk:gcc-static-analysis-trunk
 group.gcc86.groupName=GCC x86-64
 group.gcc86.instructionSet=amd64
 group.gcc86.baseName=x86-64 gcc
@@ -238,43 +238,6 @@ compiler.g63.needsMulti=true
 compiler.g71.needsMulti=true
 compiler.g72.needsMulti=true
 
-## GCC x86 build with "assertions" (--enable-checking=XXX)
-group.gcc86assert.compilers=g103assert:g104assert:g105assert:g111assert:g112assert:g113assert:g114assert:g121assert:g122assert:g123assert:g124assert:g131assert:g132assert:g133assert:g141assert:g142assert
-group.gcc86assert.groupName=GCC x86-64 (assertions)
-
-compiler.g103assert.exe=/opt/compiler-explorer/gcc-assertions-10.3.0/bin/g++
-compiler.g103assert.semver=10.3 (assertions)
-compiler.g104assert.exe=/opt/compiler-explorer/gcc-assertions-10.4.0/bin/g++
-compiler.g104assert.semver=10.4 (assertions)
-compiler.g105assert.exe=/opt/compiler-explorer/gcc-assertions-10.5.0/bin/g++
-compiler.g105assert.semver=10.5 (assertions)
-compiler.g111assert.exe=/opt/compiler-explorer/gcc-assertions-11.1.0/bin/g++
-compiler.g111assert.semver=11.1 (assertions)
-compiler.g112assert.exe=/opt/compiler-explorer/gcc-assertions-11.2.0/bin/g++
-compiler.g112assert.semver=11.2 (assertions)
-compiler.g113assert.exe=/opt/compiler-explorer/gcc-assertions-11.3.0/bin/g++
-compiler.g113assert.semver=11.3 (assertions)
-compiler.g114assert.exe=/opt/compiler-explorer/gcc-assertions-11.4.0/bin/g++
-compiler.g114assert.semver=11.4 (assertions)
-compiler.g121assert.exe=/opt/compiler-explorer/gcc-assertions-12.1.0/bin/g++
-compiler.g121assert.semver=12.1 (assertions)
-compiler.g122assert.exe=/opt/compiler-explorer/gcc-assertions-12.2.0/bin/g++
-compiler.g122assert.semver=12.2 (assertions)
-compiler.g123assert.exe=/opt/compiler-explorer/gcc-assertions-12.3.0/bin/g++
-compiler.g123assert.semver=12.3 (assertions)
-compiler.g124assert.exe=/opt/compiler-explorer/gcc-assertions-12.4.0/bin/g++
-compiler.g124assert.semver=12.4 (assertions)
-compiler.g131assert.exe=/opt/compiler-explorer/gcc-assertions-13.1.0/bin/g++
-compiler.g131assert.semver=13.1 (assertions)
-compiler.g132assert.exe=/opt/compiler-explorer/gcc-assertions-13.2.0/bin/g++
-compiler.g132assert.semver=13.2 (assertions)
-compiler.g133assert.exe=/opt/compiler-explorer/gcc-assertions-13.3.0/bin/g++
-compiler.g133assert.semver=13.3 (assertions)
-compiler.g141assert.exe=/opt/compiler-explorer/gcc-assertions-14.1.0/bin/g++
-compiler.g141assert.semver=14.1 (assertions)
-compiler.g142assert.exe=/opt/compiler-explorer/gcc-assertions-14.2.0/bin/g++
-compiler.g142assert.semver=14.2 (assertions)
-
 ################################
 # Clang for x86
 group.clang.compilers=&clangx86assert:clang30:clang31:clang32:clang33:clang341:clang350:clang351:clang352:clang37x:clang36x:clang371:clang380:clang381:clang390:clang391:clang400:clang401:clang500:clang501:clang502:clang600:clang601:clang700:clang701:clang710:clang800:clang801:clang900:clang901:clang1000:clang1001:clang1100:clang1101:clang1200:clang1201:clang1300:clang1301:clang1400:clang1500:clang1600:clang1701:clang1810:clang1910
@@ -460,7 +423,7 @@ compiler.clang1910.ldPath=${exePath}/../lib|${exePath}/../lib/x86_64-unknown-lin
 compiler.clang1910.debugPatched=true
 
 
-group.clangx86trunk.compilers=clang_trunk:clang_assertions_trunk:clang_concepts:clang_p1144:clang_autonsdmi:clang_bb_p2996:clang_p2998:clang_p3068:clang_p3309:clang_p3367:clang_p3372:clang_p3412:clang_lifetime:clang_p1061:clang_parmexpr:clang_patmat:clang_embed:clang_dang:clang_reflection:clang_variadic_friends:clang_widberg:clang_resugar:clang_clangir:clang_dascandy_contracts:clang_ericwf_contracts:clang_p1974:clang_chrisbazley
+group.clangx86trunk.compilers=clang_trunk:clang_assertions_trunk:clang_concepts:clang_p1144:clang_autonsdmi:clang_bb_p2996:clang_p3068:clang_p3309:clang_p3367:clang_p3372:clang_p3412:clang_lifetime:clang_p1061:clang_parmexpr:clang_patmat:clang_embed:clang_dang:clang_reflection:clang_variadic_friends:clang_widberg:clang_resugar:clang_clangir:clang_dascandy_contracts:clang_ericwf_contracts:clang_p1974
 group.clangx86trunk.intelAsm=-mllvm --x86-asm-syntax=intel
 group.clangx86trunk.options=--gcc-toolchain=/opt/compiler-explorer/gcc-snapshot
 group.clangx86trunk.objdumper=/opt/compiler-explorer/gcc-snapshot/bin/objdump
@@ -503,10 +466,6 @@ compiler.clang_bb_p2996.exe=/opt/compiler-explorer/clang-bb-p2996-trunk/bin/clan
 compiler.clang_bb_p2996.semver=(experimental P2996)
 compiler.clang_bb_p2996.notification=Experimental Reflection Support; see <a href="https://github.com/bloomberg/clang-p2996/blob/p2996/P2996.md" target="_blank" rel="noopener noreferrer">P2996<sup><small class="fas fa-external-link-alt opens-new-window" title="Opens in a new window"></small></sup></a>
 compiler.clang_bb_p2996.options=-std=c++26 -freflection -stdlib=libc++
-compiler.clang_p2998.exe=/opt/compiler-explorer/clang-p2998-trunk/bin/clang++
-compiler.clang_p2998.semver=(experimental P2998)
-compiler.clang_p2998.notification=Experimental support for additional template argument deduction from a function call; see <a href="https://github.com/Bekenn/llvm-project/tree/p2998" target="_blank" rel="noopener noreferrer">P2998<sup><small class="fas fa-external-link-alt opens-new-window" title="Opens in a new window"></small></sup></a>
-compiler.clang_p2998.options=-Xclang -p2998
 compiler.clang_p3068.exe=/opt/compiler-explorer/clang-p3068-trunk/bin/clang++
 compiler.clang_p3068.semver=(experimental P3068)
 compiler.clang_p3068.notification=Experimental constexpr Exception Support; see <a href="https://github.com/hanickadot/llvm-project/tree/P3068-constexpr-exceptions" target="_blank" rel="noopener noreferrer">P3068<sup><small class="fas fa-external-link-alt opens-new-window" title="Opens in a new window"></small></sup></a>
@@ -567,9 +526,6 @@ compiler.clang_clangir.notification=ClangIR enabled clang compiler; see <a href=
 compiler.clang_dascandy_contracts.exe=/opt/compiler-explorer/clang-dascandy-contracts-trunk/bin/clang++
 compiler.clang_dascandy_contracts.semver=(dascandy contracts)
 compiler.clang_dascandy_contracts.notification=Dascandy's contracts compiler; see <a href="https://github.com/dascandy/llvm-project/tree/add-contracts" target="_blank" rel="noopener noreferrer">dascandy/llvm-project<sup><small class="fas fa-external-link-alt opens-new-window" title="Opens in a new window"></small></sup></a>
-compiler.clang_chrisbazley.exe=/opt/compiler-explorer/clang-chrisbazley-trunk/bin/clang++
-compiler.clang_chrisbazley.semver=(Chris Bazley N3089)
-compiler.clang_chrisbazley.notification=Chris Bazley's N3089 compiler; see <a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3089.pdf" target="_blank" rel="noopener noreferrer">dascandy/llvm-project<sup><small class="fas fa-external-link-alt opens-new-window" title="Opens in a new window"></small></sup></a>
 compiler.clang_ericwf_contracts.exe=/opt/compiler-explorer/clang-ericwf-contracts-trunk/bin/clang++
 compiler.clang_ericwf_contracts.semver=(EricWF contracts)
 compiler.clang_ericwf_contracts.notification=EricWF's contracts compiler; see <a href="https://github.com/efcs/llvm-project/tree/contracts-nightly" target="_blank" rel="noopener noreferrer">efcs/llvm-project<sup><small class="fas fa-external-link-alt opens-new-window" title="Opens in a new window"></small></sup></a>
@@ -3885,7 +3841,7 @@ compiler.vast-trunk.options=-resource-dir /opt/compiler-explorer/clang-17.0.1/li
 #################################
 #################################
 # Installed libs
-libs=abseil:array:async_simple:belleviews:beman_iterator_interface:beman_optional26:benchmark:benri:blaze:boost:bmulti:brigand:catch2:cccl:cctz:cereal:cmcstl2:cnl:cppcoro:cppitertools:cpptrace:crosscables:ctbignum:cthash:ctre:date:dataframe:dawjson:dlib:doctest:eastl:eigen:enoki:entt:etl:eve:expected_lite:fastor:flux:fmt:gcem:gemmlowp:glaze:glm:gnufs:gnulibbacktrace:gnuexp:googletest:gsl:hdf5:hedley:hfsm:highfive:highway:hotels-template-library:immer:jsoncons:jsoncpp:kiwaku:kokkos:kumi:kvasir:kyosu:lager:lagom:lexy:libassert:libbpf:libguarded:libsimdpp:libuv:llvm:llvmfs:lua:magic_enum:mfem:mimicpp:mlir:mp-coro:mp-units:namedtype:nanorange:nlohmann_json:nsimd:ofw:openssl:outcome:pegtl:pipes:pugixml:pybind11:python:rangesv3:raberu:reactive_plus_plus:scnlib:seastar:seqan3:simde:simdjson:sol2:spdlog:spy:stdexec:strong_type:taojson:taskflow:tbb:thinkcell:tlexpected:toml11:tomlplusplus:trompeloeil:tts:type_safe:unifex:ureact:vcl:xercesc:xsimd:xtensor:xtl:yomm2:zug:cli11:avr-libstdcpp:curl:copperspice:sqlite:ztdcuneicode:ztdencodingtables:ztdidk:ztdstaticcontainers:ztdtext:ztdplatform:qt:quill:pcre2:widberg-defs:jwt-cpp:xieite:option:mdspan
+libs=abseil:array:async_simple:belleviews:beman_iterator_interface:beman_optional26:benchmark:benri:blaze:boost:bmulti:brigand:catch2:cccl:cctz:cereal:cmcstl2:cnl:cppcoro:cppitertools:cpptrace:crosscables:ctbignum:cthash:ctre:date:dataframe:dawjson:dlib:doctest:eastl:eigen:enoki:entt:etl:eve:expected_lite:fastor:flux:fmt:gcem:gemmlowp:glaze:glm:gnufs:gnulibbacktrace:gnuexp:googletest:gsl:hdf5:hedley:hfsm:highfive:highway:hotels-template-library:immer:jsoncons:jsoncpp:kiwaku:kokkos:kumi:kvasir:kyosu:lager:lagom:lexy:libassert:libbpf:libguarded:libsimdpp:libuv:llvm:llvmfs:lua:magic_enum:mfem:mimicpp:mlir:mp-coro:mp-units:namedtype:nanorange:nlohmann_json:nsimd:ofw:openssl:outcome:pegtl:pipes:pugixml:pybind11:python:rangesv3:raberu:reactive_plus_plus:scnlib:seastar:seqan3:simde:simdjson:sol2:spdlog:spy:stdexec:strong_type:taojson:taskflow:tbb:thinkcell:tlexpected:toml11:tomlplusplus:trompeloeil:tts:type_safe:unifex:ureact:vcl:xercesc:xsimd:xtensor:xtl:yomm2:zug:cli11:avr-libstdcpp:curl:copperspice:sqlite:ztdcuneicode:ztdencodingtables:ztdidk:ztdstaticcontainers:ztdtext:ztdplatform:qt:quill:pcre2:widberg-defs:jwt-cpp:xieite:option
 
 
 libs.abseil.name=Abseil
@@ -4731,7 +4687,7 @@ libs.kiwaku.versions.trunk.path=/opt/compiler-explorer/libs/kiwaku/trunk/include
 
 libs.kokkos.name=kokkos
 libs.kokkos.description=C++ Performance Portability Programming Model
-libs.kokkos.versions=4001:4100:4200:4201:4300:4301:4400:4401:4500
+libs.kokkos.versions=4001:4100:4200:4201:4300:4301:4400
 libs.kokkos.staticliblink=kokkoscore:kokkoscontainers:kokkossimd
 libs.kokkos.packagedheaders=true
 libs.kokkos.dependencies=dl
@@ -4743,8 +4699,6 @@ libs.kokkos.versions.4201.version=4.2.01
 libs.kokkos.versions.4300.version=4.3.00
 libs.kokkos.versions.4301.version=4.3.01
 libs.kokkos.versions.4400.version=4.4.00
-libs.kokkos.versions.4401.version=4.4.01
-libs.kokkos.versions.4500.version=4.5.00
 
 libs.kumi.name=kumi
 libs.kumi.description=C++20 Compact Tuple Library
@@ -4865,8 +4819,6 @@ libs.llvm.versions=trunk:401:500:501:502:600:601:700:701:800:900:1000:1001:1100:
 libs.llvm.url=https://llvm.org/
 libs.llvm.versions.trunk.version=trunk
 libs.llvm.versions.trunk.path=/opt/compiler-explorer/libs/llvm/trunk/include
-libs.llvm.versions.trunk.libpath=/opt/compiler-explorer/libs/llvm/trunk/lib
-libs.llvm.versions.trunk.staticliblink=LLVMWindowsManifest:LLVMXRay:LLVMLibDriver:LLVMDlltoolDriver:LLVMTextAPIBinaryReader:LLVMCoverage:LLVMLineEditor:LLVMXCoreDisassembler:LLVMXCoreCodeGen:LLVMXCoreDesc:LLVMXCoreInfo:LLVMX86TargetMCA:LLVMX86Disassembler:LLVMX86AsmParser:LLVMX86CodeGen:LLVMX86Desc:LLVMX86Info:LLVMWebAssemblyDisassembler:LLVMWebAssemblyAsmParser:LLVMWebAssemblyCodeGen:LLVMWebAssemblyUtils:LLVMWebAssemblyDesc:LLVMWebAssemblyInfo:LLVMVEDisassembler:LLVMVEAsmParser:LLVMVECodeGen:LLVMVEDesc:LLVMVEInfo:LLVMSystemZDisassembler:LLVMSystemZAsmParser:LLVMSystemZCodeGen:LLVMSystemZDesc:LLVMSystemZInfo:LLVMSparcDisassembler:LLVMSparcAsmParser:LLVMSparcCodeGen:LLVMSparcDesc:LLVMSparcInfo:LLVMRISCVTargetMCA:LLVMRISCVDisassembler:LLVMRISCVAsmParser:LLVMRISCVCodeGen:LLVMRISCVDesc:LLVMRISCVInfo:LLVMPowerPCDisassembler:LLVMPowerPCAsmParser:LLVMPowerPCCodeGen:LLVMPowerPCDesc:LLVMPowerPCInfo:LLVMNVPTXCodeGen:LLVMNVPTXDesc:LLVMNVPTXInfo:LLVMMSP430Disassembler:LLVMMSP430AsmParser:LLVMMSP430CodeGen:LLVMMSP430Desc:LLVMMSP430Info:LLVMMipsDisassembler:LLVMMipsAsmParser:LLVMMipsCodeGen:LLVMMipsDesc:LLVMMipsInfo:LLVMLoongArchDisassembler:LLVMLoongArchAsmParser:LLVMLoongArchCodeGen:LLVMLoongArchDesc:LLVMLoongArchInfo:LLVMLanaiDisassembler:LLVMLanaiCodeGen:LLVMLanaiAsmParser:LLVMLanaiDesc:LLVMLanaiInfo:LLVMHexagonDisassembler:LLVMHexagonCodeGen:LLVMHexagonAsmParser:LLVMHexagonDesc:LLVMHexagonInfo:LLVMBPFDisassembler:LLVMBPFAsmParser:LLVMBPFCodeGen:LLVMBPFDesc:LLVMBPFInfo:LLVMAVRDisassembler:LLVMAVRAsmParser:LLVMAVRCodeGen:LLVMAVRDesc:LLVMAVRInfo:LLVMARMDisassembler:LLVMARMAsmParser:LLVMARMCodeGen:LLVMARMDesc:LLVMARMUtils:LLVMARMInfo:LLVMAMDGPUTargetMCA:LLVMAMDGPUDisassembler:LLVMAMDGPUAsmParser:LLVMAMDGPUCodeGen:LLVMAMDGPUDesc:LLVMAMDGPUUtils:LLVMAMDGPUInfo:LLVMAArch64Disassembler:LLVMAArch64AsmParser:LLVMAArch64CodeGen:LLVMAArch64Desc:LLVMAArch64Utils:LLVMAArch64Info:LLVMOrcDebugging:LLVMOrcJIT:LLVMWindowsDriver:LLVMMCJIT:LLVMJITLink:LLVMInterpreter:LLVMExecutionEngine:LLVMRuntimeDyld:LLVMOrcTargetProcess:LLVMOrcShared:LLVMDWP:LLVMDebugInfoLogicalView:LLVMDebugInfoGSYM:LLVMOption:LLVMObjectYAML:LLVMObjCopy:LLVMMCA:LLVMMCDisassembler:LLVMLTO:LLVMFrontendOpenACC:LLVMFrontendHLSL:LLVMFrontendDriver:LLVMExtensions:LLVMPasses:LLVMHipStdPar:LLVMCoroutines:LLVMCFGuard:LLVMipo:LLVMInstrumentation:LLVMVectorize:LLVMLinker:LLVMFrontendOpenMP:LLVMFrontendOffloading:LLVMDWARFLinkerParallel:LLVMDWARFLinkerClassic:LLVMDWARFLinker:LLVMGlobalISel:LLVMMIRParser:LLVMAsmPrinter:LLVMSelectionDAG:LLVMCodeGen:LLVMTarget:LLVMObjCARCOpts:LLVMCodeGenTypes:LLVMIRPrinter:LLVMInterfaceStub:LLVMFileCheck:LLVMFuzzMutate:LLVMScalarOpts:LLVMInstCombine:LLVMAggressiveInstCombine:LLVMTransformUtils:LLVMBitWriter:LLVMAnalysis:LLVMProfileData:LLVMSymbolize:LLVMDebugInfoBTF:LLVMDebugInfoPDB:LLVMDebugInfoMSF:LLVMDebugInfoDWARF:LLVMObject:LLVMTextAPI:LLVMMCParser:LLVMIRReader:LLVMAsmParser:LLVMMC:LLVMDebugInfoCodeView:LLVMBitReader:LLVMFuzzerCLI:LLVMCore:LLVMRemarks:LLVMBitstreamReader:LLVMBinaryFormat:LLVMTargetParser:LLVMTableGen:LLVMSupport:LLVMDemangle
 libs.llvm.versions.401.version=4.0.1
 libs.llvm.versions.401.path=/opt/compiler-explorer/libs/llvm/4.0.1/include
 libs.llvm.versions.500.version=5.0.0
@@ -4921,8 +4873,6 @@ libs.llvm.versions.1810.version=18.1.0
 libs.llvm.versions.1810.path=/opt/compiler-explorer/libs/llvm/18.1.0/include
 libs.llvm.versions.1910.version=19.1.0
 libs.llvm.versions.1910.path=/opt/compiler-explorer/libs/llvm/19.1.0/include
-libs.llvm.versions.1910.libpath=/opt/compiler-explorer/libs/llvm/19.1.0/lib
-libs.llvm.versions.1910.staticliblink=LLVMWindowsManifest:LLVMXRay:LLVMLibDriver:LLVMDlltoolDriver:LLVMTextAPIBinaryReader:LLVMCoverage:LLVMLineEditor:LLVMXCoreDisassembler:LLVMXCoreCodeGen:LLVMXCoreDesc:LLVMXCoreInfo:LLVMX86TargetMCA:LLVMX86Disassembler:LLVMX86AsmParser:LLVMX86CodeGen:LLVMX86Desc:LLVMX86Info:LLVMWebAssemblyDisassembler:LLVMWebAssemblyAsmParser:LLVMWebAssemblyCodeGen:LLVMWebAssemblyUtils:LLVMWebAssemblyDesc:LLVMWebAssemblyInfo:LLVMVEDisassembler:LLVMVEAsmParser:LLVMVECodeGen:LLVMVEDesc:LLVMVEInfo:LLVMSystemZDisassembler:LLVMSystemZAsmParser:LLVMSystemZCodeGen:LLVMSystemZDesc:LLVMSystemZInfo:LLVMSparcDisassembler:LLVMSparcAsmParser:LLVMSparcCodeGen:LLVMSparcDesc:LLVMSparcInfo:LLVMRISCVTargetMCA:LLVMRISCVDisassembler:LLVMRISCVAsmParser:LLVMRISCVCodeGen:LLVMRISCVDesc:LLVMRISCVInfo:LLVMPowerPCDisassembler:LLVMPowerPCAsmParser:LLVMPowerPCCodeGen:LLVMPowerPCDesc:LLVMPowerPCInfo:LLVMNVPTXCodeGen:LLVMNVPTXDesc:LLVMNVPTXInfo:LLVMMSP430Disassembler:LLVMMSP430AsmParser:LLVMMSP430CodeGen:LLVMMSP430Desc:LLVMMSP430Info:LLVMMipsDisassembler:LLVMMipsAsmParser:LLVMMipsCodeGen:LLVMMipsDesc:LLVMMipsInfo:LLVMLoongArchDisassembler:LLVMLoongArchAsmParser:LLVMLoongArchCodeGen:LLVMLoongArchDesc:LLVMLoongArchInfo:LLVMLanaiDisassembler:LLVMLanaiCodeGen:LLVMLanaiAsmParser:LLVMLanaiDesc:LLVMLanaiInfo:LLVMHexagonDisassembler:LLVMHexagonCodeGen:LLVMHexagonAsmParser:LLVMHexagonDesc:LLVMHexagonInfo:LLVMBPFDisassembler:LLVMBPFAsmParser:LLVMBPFCodeGen:LLVMBPFDesc:LLVMBPFInfo:LLVMAVRDisassembler:LLVMAVRAsmParser:LLVMAVRCodeGen:LLVMAVRDesc:LLVMAVRInfo:LLVMARMDisassembler:LLVMARMAsmParser:LLVMARMCodeGen:LLVMARMDesc:LLVMARMUtils:LLVMARMInfo:LLVMAMDGPUTargetMCA:LLVMAMDGPUDisassembler:LLVMAMDGPUAsmParser:LLVMAMDGPUCodeGen:LLVMAMDGPUDesc:LLVMAMDGPUUtils:LLVMAMDGPUInfo:LLVMAArch64Disassembler:LLVMAArch64AsmParser:LLVMAArch64CodeGen:LLVMAArch64Desc:LLVMAArch64Utils:LLVMAArch64Info:LLVMOrcDebugging:LLVMOrcJIT:LLVMWindowsDriver:LLVMMCJIT:LLVMJITLink:LLVMInterpreter:LLVMExecutionEngine:LLVMRuntimeDyld:LLVMOrcTargetProcess:LLVMOrcShared:LLVMDWP:LLVMDebugInfoLogicalView:LLVMDebugInfoGSYM:LLVMOption:LLVMObjectYAML:LLVMObjCopy:LLVMMCA:LLVMMCDisassembler:LLVMLTO:LLVMFrontendOpenACC:LLVMFrontendHLSL:LLVMFrontendDriver:LLVMExtensions:LLVMPasses:LLVMHipStdPar:LLVMCoroutines:LLVMCFGuard:LLVMipo:LLVMInstrumentation:LLVMVectorize:LLVMLinker:LLVMFrontendOpenMP:LLVMFrontendOffloading:LLVMDWARFLinkerParallel:LLVMDWARFLinkerClassic:LLVMDWARFLinker:LLVMGlobalISel:LLVMMIRParser:LLVMAsmPrinter:LLVMSelectionDAG:LLVMCodeGen:LLVMTarget:LLVMObjCARCOpts:LLVMCodeGenTypes:LLVMIRPrinter:LLVMInterfaceStub:LLVMFileCheck:LLVMFuzzMutate:LLVMScalarOpts:LLVMInstCombine:LLVMAggressiveInstCombine:LLVMTransformUtils:LLVMBitWriter:LLVMAnalysis:LLVMProfileData:LLVMSymbolize:LLVMDebugInfoBTF:LLVMDebugInfoPDB:LLVMDebugInfoMSF:LLVMDebugInfoDWARF:LLVMObject:LLVMTextAPI:LLVMMCParser:LLVMIRReader:LLVMAsmParser:LLVMMC:LLVMDebugInfoCodeView:LLVMBitReader:LLVMFuzzerCLI:LLVMCore:LLVMRemarks:LLVMBitstreamReader:LLVMBinaryFormat:LLVMTargetParser:LLVMTableGen:LLVMSupport:LLVMDemangle
 
 libs.llvmfs.name=Filesystem (LLVM)
 libs.llvmfs.versions=autodetect
@@ -4949,13 +4899,6 @@ libs.magic_enum.versions.trunk.path=/opt/compiler-explorer/libs/magic_enum/trunk
 libs.magic_enum.versions.073.version=0.7.3
 libs.magic_enum.versions.073.path=/opt/compiler-explorer/libs/magic_enum/v0.7.3/include
 
-libs.mdspan.name=mdspan
-libs.mdspan.versions=06
-libs.mdspan.url=https://github.com/kokkos/mdspan
-libs.mdspan.description=Reference Implementation of MDSpan (c++23)
-libs.mdspan.versions.06.version=0.6
-libs.mdspan.versions.06.path=/opt/compiler-explorer/libs/mdspan-0.6.0/include
-
 libs.mfem.name=mfem
 libs.mfem.versions=47
 libs.mfem.url=https://mfem.org
diff --git a/etc/config/c++.amazonwin.properties b/etc/config/c++.amazonwin.properties
index 589664554..5073e44b2 100644
--- a/etc/config/c++.amazonwin.properties
+++ b/etc/config/c++.amazonwin.properties
@@ -69,7 +69,7 @@ compiler.mingw64_ucrt_clang_1403.exe=Z:/compilers/mingw-w64-11.3.0-14.0.3-10.0.0
 compiler.mingw64_ucrt_clang_1403.semver=14.0.3
 
 group.vcpp.compilers=&vcpp_x86:&vcpp_x64:&vcpp_arm64
-group.vcpp.options=/EHsc /source-charset:utf-8
+group.vcpp.options=/EHsc /utf-8
 group.vcpp.compilerType=win32-vc
 group.vcpp.needsMulti=false
 group.vcpp.includeFlag=/I
diff --git a/etc/config/c.amazon.properties b/etc/config/c.amazon.properties
index 67e8583ca..734817015 100644
--- a/etc/config/c.amazon.properties
+++ b/etc/config/c.amazon.properties
@@ -14,7 +14,7 @@ llvmDisassembler=/opt/compiler-explorer/clang-18.1.0/bin/llvm-dis
 
 ###############################
 # GCC for x86
-group.cgcc86.compilers=&cgcc86assert:cg346:cg404:cg412:cg447:cg453:cg464:cg471:cg472:cg473:cg474:cg481:cg482:cg483:cg484:cg485:cg490:cg491:cg492:cg493:cg494:cg510:cg520:cg530:cg540:cg6:cg62:cg63:cg65:cg71:cg72:cg73:cg74:cg75:cg81:cg82:cg83:cg84:cg85:cg91:cg92:cg93:cg94:cg95:cg101:cg102:cg103:cg104:cg105:cg111:cg112:cg113:cg114:cg121:cg122:cg123:cg124:cg131:cg132:cg133:cg141:cg142:cgsnapshot:cgstatic-analysis
+group.cgcc86.compilers=cg346:cg404:cg412:cg447:cg453:cg464:cg471:cg472:cg473:cg474:cg481:cg482:cg483:cg484:cg485:cg490:cg491:cg492:cg493:cg494:cg510:cg520:cg530:cg540:cg6:cg62:cg63:cg65:cg71:cg72:cg73:cg74:cg75:cg81:cg82:cg83:cg84:cg85:cg91:cg92:cg93:cg94:cg95:cg101:cg102:cg103:cg104:cg105:cg111:cg112:cg113:cg114:cg121:cg122:cg123:cg124:cg131:cg132:cg133:cg141:cg142:cgsnapshot:cgstatic-analysis
 group.cgcc86.groupName=GCC x86-64
 group.cgcc86.instructionSet=amd64
 group.cgcc86.isSemVer=true
@@ -185,44 +185,6 @@ compiler.cg63.needsMulti=true
 compiler.cg71.needsMulti=true
 compiler.cg72.needsMulti=true
 
-## GCC x86 build with "assertions" (--enable-checking=XXX)
-group.cgcc86assert.compilers=cg103assert:cg104assert:cg105assert:cg111assert:cg112assert:cg113assert:cg114assert:cg121assert:cg122assert:cg123assert:cg124assert:cg131assert:cg132assert:cg133assert:cg141assert:cg142assert
-group.cgcc86assert.groupName=GCC x86-64 (assertions)
-
-compiler.cg103assert.exe=/opt/compiler-explorer/gcc-assertions-10.3.0/bin/gcc
-compiler.cg103assert.semver=10.3 (assertions)
-compiler.cg104assert.exe=/opt/compiler-explorer/gcc-assertions-10.4.0/bin/gcc
-compiler.cg104assert.semver=10.4 (assertions)
-compiler.cg105assert.exe=/opt/compiler-explorer/gcc-assertions-10.5.0/bin/gcc
-compiler.cg105assert.semver=10.5 (assertions)
-compiler.cg111assert.exe=/opt/compiler-explorer/gcc-assertions-11.1.0/bin/gcc
-compiler.cg111assert.semver=11.1 (assertions)
-compiler.cg112assert.exe=/opt/compiler-explorer/gcc-assertions-11.2.0/bin/gcc
-compiler.cg112assert.semver=11.2 (assertions)
-compiler.cg113assert.exe=/opt/compiler-explorer/gcc-assertions-11.3.0/bin/gcc
-compiler.cg113assert.semver=11.3 (assertions)
-compiler.cg114assert.exe=/opt/compiler-explorer/gcc-assertions-11.4.0/bin/gcc
-compiler.cg114assert.semver=11.4 (assertions)
-compiler.cg121assert.exe=/opt/compiler-explorer/gcc-assertions-12.1.0/bin/gcc
-compiler.cg121assert.semver=12.1 (assertions)
-compiler.cg122assert.exe=/opt/compiler-explorer/gcc-assertions-12.2.0/bin/gcc
-compiler.cg122assert.semver=12.2 (assertions)
-compiler.cg123assert.exe=/opt/compiler-explorer/gcc-assertions-12.3.0/bin/gcc
-compiler.cg123assert.semver=12.3 (assertions)
-compiler.cg124assert.exe=/opt/compiler-explorer/gcc-assertions-12.4.0/bin/gcc
-compiler.cg124assert.semver=12.4 (assertions)
-compiler.cg131assert.exe=/opt/compiler-explorer/gcc-assertions-13.1.0/bin/gcc
-compiler.cg131assert.semver=13.1 (assertions)
-compiler.cg132assert.exe=/opt/compiler-explorer/gcc-assertions-13.2.0/bin/gcc
-compiler.cg132assert.semver=13.2 (assertions)
-compiler.cg133assert.exe=/opt/compiler-explorer/gcc-assertions-13.3.0/bin/gcc
-compiler.cg133assert.semver=13.3 (assertions)
-compiler.cg141assert.exe=/opt/compiler-explorer/gcc-assertions-14.1.0/bin/gcc
-compiler.cg141assert.semver=14.1 (assertions)
-compiler.cg142assert.exe=/opt/compiler-explorer/gcc-assertions-14.2.0/bin/gcc
-compiler.cg142assert.semver=14.2 (assertions)
-
-
 # Classic x86 compilers (32-bit only)
 group.cgcc-classic.compilers=cg127
 group.cgcc-classic.groupName=GCC x86
diff --git a/etc/config/c.amazonwin.properties b/etc/config/c.amazonwin.properties
index f5b1f5da8..0b5542f19 100644
--- a/etc/config/c.amazonwin.properties
+++ b/etc/config/c.amazonwin.properties
@@ -50,7 +50,7 @@ compiler.cmingw64_ucrt_clang_1403.exe=Z:/compilers/mingw-w64-11.3.0-14.0.3-10.0.
 compiler.cmingw64_ucrt_clang_1403.semver=14.0.3
 
 group.vc.compilers=&vc_x86:&vc_x64:&vc_arm64
-group.vc.options=/EHsc /source-charset:utf-8
+group.vc.options=/EHsc /utf-8
 group.vc.compilerType=win32-vc
 group.vc.needsMulti=false
 group.vc.includeFlag=/I
diff --git a/etc/config/d.amazon.properties b/etc/config/d.amazon.properties
index f94aa3f9f..dec6c990c 100644
--- a/etc/config/d.amazon.properties
+++ b/etc/config/d.amazon.properties
@@ -1,7 +1,7 @@
 compilers=&gdc:&ldc:&dmd:&gdccross
 defaultCompiler=ldc1_39
 
-group.gdc.compilers=&gdcassert:gdc48:gdc49:gdc52:gdc92:gdc93:gdc95:gdc101:gdc102:gdc105:gdc111:gdc113:gdc114:gdc121:gdc122:gdc123:gdc124:gdc131:gdc132:gdc133:gdc141:gdc142:gdctrunk
+group.gdc.compilers=gdc48:gdc49:gdc52:gdc92:gdc93:gdc95:gdc101:gdc102:gdc105:gdc111:gdc113:gdc114:gdc121:gdc122:gdc123:gdc124:gdc131:gdc132:gdc133:gdc141:gdc142:gdctrunk
 group.gdc.groupName=GDC x86-64
 group.gdc.includeFlag=-isystem
 group.gdc.isSemVer=true
@@ -62,37 +62,6 @@ compiler.gdctrunk.objdumper=/opt/compiler-explorer/gcc-snapshot/bin/objdump
 compiler.gdctrunk.semver=(trunk)
 compiler.gdctrunk.isNightly=true
 
-## GDC x86 build with "assertions" (--enable-checking=XXX)
-group.gdcassert.compilers=gdc105assert:gdc111assert:gdc113assert:gdc114assert:gdc121assert:gdc122assert:gdc123assert:gdc124assert:gdc131assert:gdc132assert:gdc133assert:gdc141assert:gdc142assert
-group.gdcassert.groupName=GDC x86-64 (assertions)
-
-compiler.gdc105assert.exe=/opt/compiler-explorer/gcc-assertions-10.5.0/bin/gdc
-compiler.gdc105assert.semver=10.5 (assertions)
-compiler.gdc111assert.exe=/opt/compiler-explorer/gcc-assertions-11.1.0/bin/gdc
-compiler.gdc111assert.semver=11.1 (assertions)
-compiler.gdc113assert.exe=/opt/compiler-explorer/gcc-assertions-11.3.0/bin/gdc
-compiler.gdc113assert.semver=11.3 (assertions)
-compiler.gdc114assert.exe=/opt/compiler-explorer/gcc-assertions-11.4.0/bin/gdc
-compiler.gdc114assert.semver=11.4 (assertions)
-compiler.gdc121assert.exe=/opt/compiler-explorer/gcc-assertions-12.1.0/bin/gdc
-compiler.gdc121assert.semver=12.1 (assertions)
-compiler.gdc122assert.exe=/opt/compiler-explorer/gcc-assertions-12.2.0/bin/gdc
-compiler.gdc122assert.semver=12.2 (assertions)
-compiler.gdc123assert.exe=/opt/compiler-explorer/gcc-assertions-12.3.0/bin/gdc
-compiler.gdc123assert.semver=12.3 (assertions)
-compiler.gdc124assert.exe=/opt/compiler-explorer/gcc-assertions-12.4.0/bin/gdc
-compiler.gdc124assert.semver=12.4 (assertions)
-compiler.gdc131assert.exe=/opt/compiler-explorer/gcc-assertions-13.1.0/bin/gdc
-compiler.gdc131assert.semver=13.1 (assertions)
-compiler.gdc132assert.exe=/opt/compiler-explorer/gcc-assertions-13.2.0/bin/gdc
-compiler.gdc132assert.semver=13.2 (assertions)
-compiler.gdc133assert.exe=/opt/compiler-explorer/gcc-assertions-13.3.0/bin/gdc
-compiler.gdc133assert.semver=13.3 (assertions)
-compiler.gdc141assert.exe=/opt/compiler-explorer/gcc-assertions-14.1.0/bin/gdc
-compiler.gdc141assert.semver=14.1 (assertions)
-compiler.gdc142assert.exe=/opt/compiler-explorer/gcc-assertions-14.2.0/bin/gdc
-compiler.gdc142assert.semver=14.2 (assertions)
-
 ## CROSS GDC
 group.gdccross.compilers=&gdcloongarch64:&gdcs390x:&gdcppc:&gdcppc64:&gdcppc64le:&gdcmips64:&gdcmips:&gdcmipsel:&gdcarm:&gdcarm64:&gdcriscv:&gdcriscv64:&gdchppa
 group.gdccross.supportsExecute=false
diff --git a/etc/config/fortran.amazon.properties b/etc/config/fortran.amazon.properties
index f14d673e0..fc23070e9 100644
--- a/etc/config/fortran.amazon.properties
+++ b/etc/config/fortran.amazon.properties
@@ -9,7 +9,7 @@ buildenvsetup.host=https://conan.compiler-explorer.com
 
 ###############################
 # GCC (as in GNU Compiler Collection) for x86
-group.gfortran_86.compilers=&gfortranassert:gfortran494:gfortran550:gfortran63:gfortran71:gfortran72:gfortran73:gfortran81:gfortran82:gfortran83:gfortran84:gfortran85:gfortran91:gfortran92:gfortran93:gfortran94:gfortran101:gfortran102:gfortran103:gfortran104:gfortran105:gfortran111:gfortran112:gfortran113:gfortran114:gfortran121:gfortran122:gfortran123:gfortran124:gfortran131:gfortran132:gfortran133:gfortran141:gfortran142:gfortransnapshot
+group.gfortran_86.compilers=gfortran494:gfortran550:gfortran63:gfortran71:gfortran72:gfortran73:gfortran81:gfortran82:gfortran83:gfortran84:gfortran85:gfortran91:gfortran92:gfortran93:gfortran94:gfortran101:gfortran102:gfortran103:gfortran104:gfortran105:gfortran111:gfortran112:gfortran113:gfortran114:gfortran121:gfortran122:gfortran123:gfortran124:gfortran131:gfortran132:gfortran133:gfortran141:gfortran142:gfortransnapshot
 group.gfortran_86.groupName=GFORTRAN x86-64
 group.gfortran_86.isSemVer=true
 group.gfortran_86.baseName=x86-64 gfortran
@@ -86,43 +86,6 @@ compiler.gfortransnapshot.objdumper=/opt/compiler-explorer/gcc-snapshot/bin/objd
 compiler.gfortransnapshot.semver=(trunk)
 compiler.gfortransnapshot.isNightly=true
 
-## GFORTRAN x86 build with "assertions" (--enable-checking=XXX)
-group.gfortranassert.compilers=gfortran103assert:gfortran104assert:gfortran105assert:gfortran111assert:gfortran112assert:gfortran113assert:gfortran114assert:gfortran121assert:gfortran122assert:gfortran123assert:gfortran124assert:gfortran131assert:gfortran132assert:gfortran133assert:gfortran141assert:gfortran142assert
-group.gfortranassert.groupName=GFORTRAN x86-64 (assertions)
-
-compiler.gfortran103assert.exe=/opt/compiler-explorer/gcc-assertions-10.3.0/bin/gfortran
-compiler.gfortran103assert.semver=10.3 (assertions)
-compiler.gfortran104assert.exe=/opt/compiler-explorer/gcc-assertions-10.4.0/bin/gfortran
-compiler.gfortran104assert.semver=10.4 (assertions)
-compiler.gfortran105assert.exe=/opt/compiler-explorer/gcc-assertions-10.5.0/bin/gfortran
-compiler.gfortran105assert.semver=10.5 (assertions)
-compiler.gfortran111assert.exe=/opt/compiler-explorer/gcc-assertions-11.1.0/bin/gfortran
-compiler.gfortran111assert.semver=11.1 (assertions)
-compiler.gfortran112assert.exe=/opt/compiler-explorer/gcc-assertions-11.2.0/bin/gfortran
-compiler.gfortran112assert.semver=11.2 (assertions)
-compiler.gfortran113assert.exe=/opt/compiler-explorer/gcc-assertions-11.3.0/bin/gfortran
-compiler.gfortran113assert.semver=11.3 (assertions)
-compiler.gfortran114assert.exe=/opt/compiler-explorer/gcc-assertions-11.4.0/bin/gfortran
-compiler.gfortran114assert.semver=11.4 (assertions)
-compiler.gfortran121assert.exe=/opt/compiler-explorer/gcc-assertions-12.1.0/bin/gfortran
-compiler.gfortran121assert.semver=12.1 (assertions)
-compiler.gfortran122assert.exe=/opt/compiler-explorer/gcc-assertions-12.2.0/bin/gfortran
-compiler.gfortran122assert.semver=12.2 (assertions)
-compiler.gfortran123assert.exe=/opt/compiler-explorer/gcc-assertions-12.3.0/bin/gfortran
-compiler.gfortran123assert.semver=12.3 (assertions)
-compiler.gfortran124assert.exe=/opt/compiler-explorer/gcc-assertions-12.4.0/bin/gfortran
-compiler.gfortran124assert.semver=12.4 (assertions)
-compiler.gfortran131assert.exe=/opt/compiler-explorer/gcc-assertions-13.1.0/bin/gfortran
-compiler.gfortran131assert.semver=13.1 (assertions)
-compiler.gfortran132assert.exe=/opt/compiler-explorer/gcc-assertions-13.2.0/bin/gfortran
-compiler.gfortran132assert.semver=13.2 (assertions)
-compiler.gfortran133assert.exe=/opt/compiler-explorer/gcc-assertions-13.3.0/bin/gfortran
-compiler.gfortran133assert.semver=13.3 (assertions)
-compiler.gfortran141assert.exe=/opt/compiler-explorer/gcc-assertions-14.1.0/bin/gfortran
-compiler.gfortran141assert.semver=14.1 (assertions)
-compiler.gfortran142assert.exe=/opt/compiler-explorer/gcc-assertions-14.2.0/bin/gfortran
-compiler.gfortran142assert.semver=14.2 (assertions)
-
 ###############################
 # Intel Parallel Studio XE for x86
 group.ifort.compilers=ifort19:ifort202112:ifort202120:ifort202130:ifort202140:ifort202150:ifort202160:ifort202170:ifort202171:ifort202180:ifort202190:ifort2021100:ifort2021110
diff --git a/etc/config/gimple.amazon.properties b/etc/config/gimple.amazon.properties
index 90315dcea..0d3d74341 100644
--- a/etc/config/gimple.amazon.properties
+++ b/etc/config/gimple.amazon.properties
@@ -12,7 +12,7 @@ externalparser.exe=/usr/local/bin/asm-parser
 
 ###############################
 # GCC for x86
-group.gimplegcc86.compilers=&gimplegcc86assert:gimpleg91:gimpleg92:gimpleg93:gimpleg94:gimpleg95:gimpleg101:gimpleg102:gimpleg103:gimpleg104:gimpleg105:gimpleg111:gimpleg112:gimpleg113:gimpleg114:gimpleg121:gimpleg122:gimpleg123:gimpleg124:gimpleg131:gimpleg132:gimpleg133:gimpleg141:gimpleg142:gimplegsnapshot:gimplegstatic-analysis
+group.gimplegcc86.compilers=gimpleg91:gimpleg92:gimpleg93:gimpleg94:gimpleg95:gimpleg101:gimpleg102:gimpleg103:gimpleg104:gimpleg105:gimpleg111:gimpleg112:gimpleg113:gimpleg114:gimpleg121:gimpleg122:gimpleg123:gimpleg124:gimpleg131:gimpleg132:gimpleg133:gimpleg141:gimpleg142:gimplegsnapshot:gimplegstatic-analysis
 group.gimplegcc86.groupName=GCC x86-64
 group.gimplegcc86.instructionSet=amd64
 group.gimplegcc86.isSemVer=true
@@ -83,43 +83,6 @@ compiler.gimplegstatic-analysis.semver=(static analysis)
 compiler.gimplegstatic-analysis.options=-fanalyzer -fdiagnostics-urls=never -fdiagnostics-color=always
 compiler.gimplegstatic-analysis.notification=Experimental static analyzer; see <a href="https://gcc.gnu.org/wiki/DavidMalcolm/StaticAnalyzer" target="_blank" rel="noopener noreferrer">GCC wiki page<sup><small class="fas fa-external-link-alt opens-new-window" title="Opens in a new window"></small></sup></a>
 
-## GCC build with "assertions" (--enable-checking=XXX)
-group.gimplegcc86assert.compilers=gimpleg103assert:gimpleg104assert:gimpleg105assert:gimpleg111assert:gimpleg112assert:gimpleg113assert:gimpleg114assert:gimpleg121assert:gimpleg122assert:gimpleg123assert:gimpleg124assert:gimpleg131assert:gimpleg132assert:gimpleg133assert:gimpleg141assert:gimpleg142assert
-group.gimplegcc86assert.groupName=GCC x86-64 (assertions)
-
-compiler.gimpleg103assert.exe=/opt/compiler-explorer/gcc-assertions-10.3.0/bin/gcc
-compiler.gimpleg103assert.semver=10.3 (assertions)
-compiler.gimpleg104assert.exe=/opt/compiler-explorer/gcc-assertions-10.4.0/bin/gcc
-compiler.gimpleg104assert.semver=10.4 (assertions)
-compiler.gimpleg105assert.exe=/opt/compiler-explorer/gcc-assertions-10.5.0/bin/gcc
-compiler.gimpleg105assert.semver=10.5 (assertions)
-compiler.gimpleg111assert.exe=/opt/compiler-explorer/gcc-assertions-11.1.0/bin/gcc
-compiler.gimpleg111assert.semver=11.1 (assertions)
-compiler.gimpleg112assert.exe=/opt/compiler-explorer/gcc-assertions-11.2.0/bin/gcc
-compiler.gimpleg112assert.semver=11.2 (assertions)
-compiler.gimpleg113assert.exe=/opt/compiler-explorer/gcc-assertions-11.3.0/bin/gcc
-compiler.gimpleg113assert.semver=11.3 (assertions)
-compiler.gimpleg114assert.exe=/opt/compiler-explorer/gcc-assertions-11.4.0/bin/gcc
-compiler.gimpleg114assert.semver=11.4 (assertions)
-compiler.gimpleg121assert.exe=/opt/compiler-explorer/gcc-assertions-12.1.0/bin/gcc
-compiler.gimpleg121assert.semver=12.1 (assertions)
-compiler.gimpleg122assert.exe=/opt/compiler-explorer/gcc-assertions-12.2.0/bin/gcc
-compiler.gimpleg122assert.semver=12.2 (assertions)
-compiler.gimpleg123assert.exe=/opt/compiler-explorer/gcc-assertions-12.3.0/bin/gcc
-compiler.gimpleg123assert.semver=12.3 (assertions)
-compiler.gimpleg124assert.exe=/opt/compiler-explorer/gcc-assertions-12.4.0/bin/gcc
-compiler.gimpleg124assert.semver=12.4 (assertions)
-compiler.gimpleg131assert.exe=/opt/compiler-explorer/gcc-assertions-13.1.0/bin/gcc
-compiler.gimpleg131assert.semver=13.1 (assertions)
-compiler.gimpleg132assert.exe=/opt/compiler-explorer/gcc-assertions-13.2.0/bin/gcc
-compiler.gimpleg132assert.semver=13.2 (assertions)
-compiler.gimpleg133assert.exe=/opt/compiler-explorer/gcc-assertions-13.3.0/bin/gcc
-compiler.gimpleg133assert.semver=13.3 (assertions)
-compiler.gimpleg141assert.exe=/opt/compiler-explorer/gcc-assertions-14.1.0/bin/gcc
-compiler.gimpleg141assert.semver=14.1 (assertions)
-compiler.gimpleg142assert.exe=/opt/compiler-explorer/gcc-assertions-14.2.0/bin/gcc
-compiler.gimpleg142assert.semver=14.2 (assertions)
-
 ################################
 # GCC for AVR
 group.gimpleavr.compilers=gimpleavrg920:gimpleavrg930:gimpleavrg1030:gimpleavrg1100:gimpleavrg1210:gimpleavrg1220:gimpleavrg1230:gimpleavrg1310:gimpleavrg1320:gimpleavrg1330:gimpleavrg1410:gimpleavrg1420
diff --git a/etc/config/go.amazon.properties b/etc/config/go.amazon.properties
index 0fe945ae7..1894c4199 100644
--- a/etc/config/go.amazon.properties
+++ b/etc/config/go.amazon.properties
@@ -2,7 +2,7 @@ compilers=&gccgo:&gl:&cross
 defaultCompiler=gl1232
 objdumper=/opt/compiler-explorer/gcc-13.1.0/bin/objdump
 
-group.gccgo.compilers=&gccgoassert:gccgo494:gccgo630:gccgo720:gccgo830:gccgo930:gccgo950:gccgo102:gccgo105:gccgo111:gccgo112:gccgo113:gccgo114:gccgo121:gccgo122:gccgo123:gccgo124:gccgo131:gccgo132:gccgo133:gccgo141:gccgo142
+group.gccgo.compilers=gccgo494:gccgo630:gccgo720:gccgo830:gccgo930:gccgo950:gccgo102:gccgo105:gccgo111:gccgo112:gccgo113:gccgo114:gccgo121:gccgo122:gccgo123:gccgo124:gccgo131:gccgo132:gccgo133:gccgo141:gccgo142
 group.gccgo.isSemVer=true
 group.gccgo.baseName=x86 gccgo
 compiler.gccgo494.exe=/opt/compiler-explorer/gcc-4.9.4/bin/gccgo
@@ -50,40 +50,6 @@ compiler.gccgo141.semver=14.1
 compiler.gccgo142.exe=/opt/compiler-explorer/gcc-14.2.0/bin/gccgo
 compiler.gccgo142.semver=14.2
 
-## GCC x86 build with "assertions" (--enable-checking=XXX)
-group.gccgoassert.compilers=gccgo105assert:gccgo111assert:gccgo112assert:gccgo113assert:gccgo114assert:gccgo121assert:gccgo122assert:gccgo123assert:gccgo124assert:gccgo131assert:gccgo132assert:gccgo133assert:gccgo141assert:gccgo142assert
-group.gccgoassert.groupName=x86 gccgo (assertions)
-
-compiler.gccgo105assert.exe=/opt/compiler-explorer/gcc-assertions-10.5.0/bin/gccgo
-compiler.gccgo105assert.semver=10.5.0 (assertions)
-compiler.gccgo111assert.exe=/opt/compiler-explorer/gcc-assertions-11.1.0/bin/gccgo
-compiler.gccgo111assert.semver=11.1.0 (assertions)
-compiler.gccgo112assert.exe=/opt/compiler-explorer/gcc-assertions-11.2.0/bin/gccgo
-compiler.gccgo112assert.semver=11.2.0 (assertions)
-compiler.gccgo113assert.exe=/opt/compiler-explorer/gcc-assertions-11.3.0/bin/gccgo
-compiler.gccgo113assert.semver=11.3.0 (assertions)
-compiler.gccgo114assert.exe=/opt/compiler-explorer/gcc-assertions-11.4.0/bin/gccgo
-compiler.gccgo114assert.semver=11.4.0 (assertions)
-compiler.gccgo121assert.exe=/opt/compiler-explorer/gcc-assertions-12.1.0/bin/gccgo
-compiler.gccgo121assert.semver=12.1.0 (assertions)
-compiler.gccgo122assert.exe=/opt/compiler-explorer/gcc-assertions-12.2.0/bin/gccgo
-compiler.gccgo122assert.semver=12.2.0 (assertions)
-compiler.gccgo123assert.exe=/opt/compiler-explorer/gcc-assertions-12.3.0/bin/gccgo
-compiler.gccgo123assert.semver=12.3.0 (assertions)
-compiler.gccgo124assert.exe=/opt/compiler-explorer/gcc-assertions-12.4.0/bin/gccgo
-compiler.gccgo124assert.semver=12.4.0 (assertions)
-compiler.gccgo131assert.exe=/opt/compiler-explorer/gcc-assertions-13.1.0/bin/gccgo
-compiler.gccgo131assert.semver=13.1 (assertions)
-compiler.gccgo132assert.exe=/opt/compiler-explorer/gcc-assertions-13.2.0/bin/gccgo
-compiler.gccgo132assert.semver=13.2 (assertions)
-compiler.gccgo133assert.exe=/opt/compiler-explorer/gcc-assertions-13.3.0/bin/gccgo
-compiler.gccgo133assert.semver=13.3 (assertions)
-compiler.gccgo141assert.exe=/opt/compiler-explorer/gcc-assertions-14.1.0/bin/gccgo
-compiler.gccgo141assert.semver=14.1 (assertions)
-compiler.gccgo142assert.exe=/opt/compiler-explorer/gcc-assertions-14.2.0/bin/gccgo
-compiler.gccgo142assert.semver=14.2 (assertions)
-
-
 group.gl.compilers=&x86gl:&armgl:&mipsgl:&ppcgl:&riscvgl:&s390xgl:&wasmgl
 group.gl.versionFlag=version
 group.gl.compilerType=golang
diff --git a/etc/config/modula2.amazon.properties b/etc/config/modula2.amazon.properties
index 617162026..9d3fbabd6 100644
--- a/etc/config/modula2.amazon.properties
+++ b/etc/config/modula2.amazon.properties
@@ -15,10 +15,9 @@ needsMulti=false
 externalparser=CEAsmParser
 externalparser.exe=/usr/local/bin/asm-parser
 
-group.gm2.compilers=&gm2assert:gm2131:gm2132:gm2133:gm2141:gm2142:gm2snapshot
+group.gm2.compilers=gm2131:gm2132:gm2133:gm2141:gm2142:gm2snapshot
 group.gm2.instructionSet=amd64
 group.gm2.isSemVer=true
-group.gm2.groupName=GCC GM2 x86-64
 group.gm2.baseName=x86-64 gcc gm2
 
 compiler.gm2131.exe=/opt/compiler-explorer/gcc-13.1.0/bin/gm2
@@ -35,19 +34,3 @@ compiler.gm2142.semver=14.2
 
 compiler.gm2snapshot.exe=/opt/compiler-explorer/gcc-snapshot/bin/gm2
 compiler.gm2snapshot.semver=(snapshot)
-
-## GFORTRAN x86 build with "assertions" (--enable-checking=XXX)
-group.gm2assert.compilers=gm2131assert:gm2132assert:gm2133assert:gm2141assert:gm2142assert
-group.gm2assert.groupName=GM2 x86-64 (assertions)
-
-compiler.gm2131assert.exe=/opt/compiler-explorer/gcc-assertions-13.1.0/bin/gm2
-compiler.gm2131assert.semver=13.1 (assertions)
-compiler.gm2132assert.exe=/opt/compiler-explorer/gcc-assertions-13.2.0/bin/gm2
-compiler.gm2132assert.semver=13.2 (assertions)
-compiler.gm2133assert.exe=/opt/compiler-explorer/gcc-assertions-13.3.0/bin/gm2
-compiler.gm2133assert.semver=13.3 (assertions)
-
-compiler.gm2141assert.exe=/opt/compiler-explorer/gcc-assertions-14.1.0/bin/gm2
-compiler.gm2141assert.semver=14.1 (assertions)
-compiler.gm2142assert.exe=/opt/compiler-explorer/gcc-assertions-14.2.0/bin/gm2
-compiler.gm2142assert.semver=14.2 (assertions)
diff --git a/etc/config/objc++.amazon.properties b/etc/config/objc++.amazon.properties
index 67a6ac7e9..9400b893c 100644
--- a/etc/config/objc++.amazon.properties
+++ b/etc/config/objc++.amazon.properties
@@ -14,7 +14,7 @@ llvmDisassembler=/opt/compiler-explorer/clang-18.1.0/bin/llvm-dis
 
 ###############################
 # GCC for x86
-group.objcppgcc86.compilers=&objcppgcc86assert:objcppg105:objcppg114:objcppg122:objcppg123:objcppg124:objcppg131:objcppg132:objcppg133:objcppg141:objcppg142:objcppgsnapshot
+group.objcppgcc86.compilers=objcppg105:objcppg114:objcppg122:objcppg123:objcppg124:objcppg131:objcppg132:objcppg133:objcppg141:objcppg142:objcppgsnapshot
 group.objcppgcc86.groupName=GCC x86-64
 group.objcppgcc86.instructionSet=amd64
 group.objcppgcc86.baseName=x86-64 gcc
@@ -62,40 +62,6 @@ compiler.objcppgsnapshot.objdumper=/opt/compiler-explorer/gcc-snapshot/bin/objdu
 compiler.objcppgsnapshot.semver=(trunk)
 compiler.objcppgsnapshot.isNightly=true
 
-## OBJC++ GCC x86 build with "assertions" (--enable-checking=XXX)
-group.objcppgcc86assert.groupName=GCC x86-64 (assertions)
-group.objcppgcc86assert.compilers=objcppg105assert:objcppg114assert:objcppg122assert:objcppg123assert:objcppg124assert:objcppg131assert:objcppg132assert:objcppg133assert:objcppg141assert:objcppg142assert
-
-compiler.objcppg105assert.exe=/opt/compiler-explorer/gcc-assertions-10.5.0/bin/g++
-compiler.objcppg105assert.semver=10.5 (assertions)
-
-compiler.objcppg114assert.exe=/opt/compiler-explorer/gcc-assertions-11.4.0/bin/g++
-compiler.objcppg114assert.semver=11.4 (assertions)
-
-compiler.objcppg122assert.exe=/opt/compiler-explorer/gcc-assertions-12.2.0/bin/g++
-compiler.objcppg122assert.semver=12.2 (assertions)
-
-compiler.objcppg123assert.exe=/opt/compiler-explorer/gcc-assertions-12.3.0/bin/g++
-compiler.objcppg123assert.semver=12.3 (assertions)
-
-compiler.objcppg124assert.exe=/opt/compiler-explorer/gcc-assertions-12.4.0/bin/g++
-compiler.objcppg124assert.semver=12.4 (assertions)
-
-compiler.objcppg131assert.exe=/opt/compiler-explorer/gcc-assertions-13.1.0/bin/g++
-compiler.objcppg131assert.semver=13.1 (assertions)
-
-compiler.objcppg132assert.exe=/opt/compiler-explorer/gcc-assertions-13.2.0/bin/g++
-compiler.objcppg132assert.semver=13.2 (assertions)
-
-compiler.objcppg133assert.exe=/opt/compiler-explorer/gcc-assertions-13.3.0/bin/g++
-compiler.objcppg133assert.semver=13.3 (assertions)
-
-compiler.objcppg141assert.exe=/opt/compiler-explorer/gcc-assertions-14.1.0/bin/g++
-compiler.objcppg141assert.semver=14.1 (assertions)
-
-compiler.objcppg142assert.exe=/opt/compiler-explorer/gcc-assertions-14.2.0/bin/g++
-compiler.objcppg142assert.semver=14.2 (assertions)
-
 
 group.objcppcross.compilers=&objcppgccs
 
diff --git a/etc/config/objc.amazon.properties b/etc/config/objc.amazon.properties
index 0f52371bf..58a72cbd9 100644
--- a/etc/config/objc.amazon.properties
+++ b/etc/config/objc.amazon.properties
@@ -9,7 +9,7 @@ externalparser.exe=/usr/local/bin/asm-parser
 
 ###############################
 # GCC for x86
-group.objcgcc86.compilers=&objcgcc86assert:objcg346:objcg404:objcg650:objcg105:objcg114:objcg122:objcg123:objcg124:objcg131:objcg132:objcg133:objcg141:objcg142:objcgsnapshot
+group.objcgcc86.compilers=objcg346:objcg404:objcg650:objcg105:objcg114:objcg122:objcg123:objcg124:objcg131:objcg132:objcg133:objcg141:objcg142:objcgsnapshot
 group.objcgcc86.groupName=GCC x86-64
 group.objcgcc86.instructionSet=amd64
 group.objcgcc86.isSemVer=true
@@ -64,40 +64,6 @@ compiler.objcgsnapshot.objdumper=/opt/compiler-explorer/gcc-snapshot/bin/objdump
 compiler.objcgsnapshot.semver=(trunk)
 compiler.objcgsnapshot.isNightly=true
 
-## OBJC GCC x86 build with "assertions" (--enable-checking=XXX)
-group.objcgcc86assert.compilers=objcg105assert:objcg114assert:objcg122assert:objcg123assert:objcg124assert:objcg131assert:objcg132assert:objcg133assert:objcg141assert:objcg142assert
-group.objcgcc86assert.groupName=GCC x86-64 (assertions)
-
-compiler.objcg105assert.exe=/opt/compiler-explorer/gcc-assertions-10.5.0/bin/gcc
-compiler.objcg105assert.semver=10.5 (assertions)
-
-compiler.objcg114assert.exe=/opt/compiler-explorer/gcc-assertions-11.4.0/bin/gcc
-compiler.objcg114assert.semver=11.4 (assertions)
-
-compiler.objcg122assert.exe=/opt/compiler-explorer/gcc-assertions-12.2.0/bin/gcc
-compiler.objcg122assert.semver=12.2 (assertions)
-
-compiler.objcg123assert.exe=/opt/compiler-explorer/gcc-assertions-12.3.0/bin/gcc
-compiler.objcg123assert.semver=12.3 (assertions)
-
-compiler.objcg124assert.exe=/opt/compiler-explorer/gcc-assertions-12.4.0/bin/gcc
-compiler.objcg124assert.semver=12.4 (assertions)
-
-compiler.objcg131assert.exe=/opt/compiler-explorer/gcc-assertions-13.1.0/bin/gcc
-compiler.objcg131assert.semver=13.1 (assertions)
-
-compiler.objcg132assert.exe=/opt/compiler-explorer/gcc-assertions-13.2.0/bin/gcc
-compiler.objcg132assert.semver=13.2 (assertions)
-
-compiler.objcg133assert.exe=/opt/compiler-explorer/gcc-assertions-13.3.0/bin/gcc
-compiler.objcg133assert.semver=13.3 (assertions)
-
-compiler.objcg141assert.exe=/opt/compiler-explorer/gcc-assertions-14.1.0/bin/gcc
-compiler.objcg141assert.semver=14.1 (assertions)
-
-compiler.objcg142assert.exe=/opt/compiler-explorer/gcc-assertions-14.2.0/bin/gcc
-compiler.objcg142assert.semver=14.2 (assertions)
-
 ###############################
 # Cross Compilers
 group.objccross.compilers=&objcppcs:&objcmipss:&objcgccarm:&objcrv:&objcs390x:&objcloongarch64:&objcsparc:&objcsparc64:&objcsparcleon:&objcvax:&objchppa
diff --git a/etc/config/odin.amazon.properties b/etc/config/odin.amazon.properties
deleted file mode 100644
index 81887838f..000000000
--- a/etc/config/odin.amazon.properties
+++ /dev/null
@@ -1,15 +0,0 @@
-compilers=&odin
-compilerType=odin
-defaultCompiler=odin202411
-supportsBinary=true
-supportsExecute=true
-
-objdumper=/opt/compiler-explorer/gcc-14.2.0/bin/objdump
-clangPath=/opt/compiler-explorer/clang-19.1.0/bin/clang
-
-group.odin.compilers=odin202411
-group.odin.isSemVer=false
-group.odin.baseName=odin
-
-compiler.odin202411.exe=/opt/compiler-explorer/odin-dev-2024-11/odin
-compiler.odin202411.name=Odin (2024-11)
diff --git a/etc/config/odin.defaults.properties b/etc/config/odin.defaults.properties
deleted file mode 100644
index 8940278c0..000000000
--- a/etc/config/odin.defaults.properties
+++ /dev/null
@@ -1,10 +0,0 @@
-compilers=odin:/usr/bin/odin
-objdumper=objdump
-supportsBinary=true
-supportsExecute=true
-compilerType=odin
-versionFlag=version
-
-supportsLibraryCodeFilter=true
-
-binaryHideFuncRe=^(__.*|main|runtime\..*|fmt\..*|reflect\..*|bufio\..*|io\..*|os\..*|strconv\..*|utf8\..*|strings\..*|mem\..*|time\..*|unix\..*|strconv_decimal\..*|utf16\..*|bytes\..*|math\..*|thread\..*|text\..*|_(init|start|fini)|_dl_relocate_static_pie|.*@plt.*)$
diff --git a/etc/config/rust.amazon.properties b/etc/config/rust.amazon.properties
index 91d720058..8f88a2161 100644
--- a/etc/config/rust.amazon.properties
+++ b/etc/config/rust.amazon.properties
@@ -212,7 +212,7 @@ group.rustgcc.options=-frust-incomplete-and-experimental-compiler-do-not-use
 group.rustgcc.notification=Rust GCC Frontend - Very early snapshot
 
 # native compiler
-group.gcc86.compilers=&gccrsassert:gccrs-snapshot:gccrs-g141:gccrs-g142:gcc-snapshot
+group.gcc86.compilers=gccrs-snapshot:gccrs-g141:gccrs-g142:gcc-snapshot
 group.gcc86.groupName=x86-64 GCCRS
 group.gcc86.baseName=x86-64 GCCRS
 group.gcc86.unwiseOptions=-march=native
@@ -231,16 +231,6 @@ compiler.gccrs-snapshot.exe=/opt/compiler-explorer/gcc-gccrs-master/bin/gccrs
 compiler.gccrs-snapshot.semver=(GCCRS master)
 compiler.gccrs-snapshot.isNightly=true
 
-## GCC (from upstream GCC, not GCCRS github) x86 build with "assertions" (--enable-checking=XXX)
-group.gccrsassert.compilers=gccrs-g141assert:gccrs-g142assert
-group.gccrsassert.groupName=x86-64 GCC (assertions)
-
-compiler.gccrs-g141assert.exe=/opt/compiler-explorer/gcc-assertions-14.1.0/bin/gccrs
-compiler.gccrs-g141assert.semver=14.1 (GCC assertions)
-
-compiler.gccrs-g142assert.exe=/opt/compiler-explorer/gcc-assertions-14.2.0/bin/gccrs
-compiler.gccrs-g142assert.semver=14.2 (GCC assertions)
-
 # cross compilers
 group.gcccross.compilers=&rustgccbpf
 group.gcccross.supportsExecute=false
diff --git a/etc/config/site-templates.conf b/etc/config/site-templates.conf
new file mode 100644
index 000000000..c49abe710
--- /dev/null
+++ b/etc/config/site-templates.conf
@@ -0,0 +1,11 @@
+meta.screenshot_dimensions=1000x800
+Diff of Two Sources=z:OYLghAFBqd5TKALEBjA9gEwKYFFMCWALugE4A0BIEAZgQDbYB2AhgLbYgDkAjF%2BTXRMiAZVQtGIHgBYBQogFUAztgAKAD24AGfgCsp5eiyahUAUgBMAIUtXyKxqiIEh1ZpgDC6egFc2TA3cAGQImbAA5PwAjbFIQC3IAB3QlYhcmL19/A2TU5yEQsMi2GLiEh2wndJEiFlIiTL8AnntsR3ymGrqiQojo2Pj7WvrG7JalYZ7QvpKBiwBKe3QfUlROLksAZlDUXxwAajNNjwA3SpJSI9wzLQBBG9uT9AJMfcx0AH0ldA4PgHcyABrCChIjzI42O4PJ4vfaJUjoNZKJQfYjYNhKCAYJgTfYTTAgEBnJxkI4eUFXSwANn2xPmhwA7JDbvtWfsWD4SHiAF6HTYAEVplQAdKludgIODNsy2ftBKQIPjCWLsB8iPsCHzBVoIRq%2BR4ebqCLZbPSzEyHrLZe8vj9VQDSMDiWYAKxWY0u/lSmVs838h5%2Bh5cRb0bgu/gBLg6cjobgeE3WPHLVbYQ4WTZ8chEbTBxaAkAurSGbjSfhsAtFyPR2NcfhKEBF7NR4PkOCwFAYHD4YhkSjUOiMVgcbiZwTCMQSTgyOTCZRqTTN8j6BJGExoBN2CpVVwQdyjAIWFrBabFUogBlJFJpIT7%2BItXLXpi9U8DC9bjpdEbeJp31rtaqTM%2B/RxG%2Bky3oeQzdEBswgYs3wrGs3BbDseypmSxIXJSUJ3DCrw2t8vwOsCoLegGOHPK88KItgyKokQ6KYtiuJKkS5ykscFKbNcFg0nSjI%2Bqy8oQByXJomw%2BwgEKqBmhadxWmy%2BF2v8QIgvRbCkXJvoMv6ULaUGIZhhGOYxnGG5JghaHphY/BNjo8yLEg2AsDgcSSsWXCluQ5aFuQVb8DWdYNlmOb2eQ%2BbSC6wpUgAnDw0VaFSWhaC6FiHtFmzuZsRmLgFwXNosbbIGgPyJAwsR9liJVlXEuzGMAPCbFoLQDvRpD1hAUTGVEoR1AAniO/AYGwHDCAA8kw9D9YuOBsHVkjTQQpDnAQZz1ou2DqJUnLrJmoJtMZ9AEFEpB9V4ODGUQpAEOWvAtjQRjAEoABqBDYH8o2JMwA0zqI4iSNOY6KCoGjGfoLSrqYG6GEd9aQIs6CJB0a0ALSjVlf7LTue7fmM5DHkUwE5FeHS3vexPpNBZ7jG0mOdGBOPNBj2501BJ6E%2BM9NZIzEyswTMFSHByaIS0l3YDtLahlw4a%2BcZNbqAAHFSyNUtI%2By1SY%2BwNcKWjCjw%2BwQPG1i2OQ%2BzdhcaYZibXhsKVjCkBbPDzDZIWth2VV2xVQ22wM6v1Y1zUMK17WdYu3WsKQU2ZkNI1EONk3GTNc3rNGhBLVUq3GRtW30d9e2S9Gh3HadWDJzZV03Xwiz3Swj0vW9H1fbdP0Tv9siA3OIOLsuhh1euRvWNDUSw25CNI9wqPo%2B%2B6RuEwngM4Es%2BUwMZN5OkpOXqvBRs/z1P/kIn4NPPu%2B0wfS9xBz3Trzz9RnwLSwWYMoviwZUvZdW3AK0rKtqxDmubNrut9aGxsAPU2hBzZbASPsa23t7aQKdnlOyrsQCEBoDQCqgMW5TjbvIDuC4C5IHrODQhqCaBEF6p9IKpBCGDGoUoUh5DKFaBftLPyJkuD8gIGg/Ydc/ixH2J/ZWqtfZ/wAXrE4SgBGKyET/OqoidaZlsrmcgjlnIDDcvmF00hhSNXllodK0VorSAZAyPRDIqTuU8uWHgSUZY5W4IFBISjQqS2snY9%2BtZEHKLOG1ae0ggA
+Diff of Two Compilers=z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYTStJg1DIApACYAQuYukl9ZATwDKjdAGFUtAK4sGIM6SuADJ4DJgAcj4ARpjEINIADqgKhE4MHt6%2B/qRJKY4CIWGRLDFx0naYDmlCBEzEBBk%2BfgEVVQI1dQSFEdGx8ba19Y1ZLYNdoT0lfZIAlLaoXsTI7BwA9KsA1AAqAJ4JmBs7C8QbaFgbCLGYpBskG7SoTOgbhhuYqqwJ9AB0JhoAgqECBsFABHLx1TAQIEbBg%2BGYbEwAdisAI26I2xEwBEWDFhPg2ACp8SwTABmVH/ZEAEQ4c1onAArLw/BwtKRUJw3NZrCDjstEWYyTxSARNHS5gBrECMjT6TiSFnijmcXgKEBysVsumkOCwJBoFgJOixciUQ3G%2BhxYBcMxcPh0AixdUQKLKqKhOo7Tgiw1sQQAeQYtG92tIWBYhmA4jD%2BCxVQAbph1WH3pUvE6fbwgZgGWHaHgosQvR4sMqCMQ8Cws3MqAZgAoAGp4TAAdwD%2B1ZIv4ghEYnYUhkgkUKnUYd09oMRhQPMs%2BkL6sgc1QCXyDBTAFoA2SNhvI0sEOTqQpJTsDJLMGrc5U1y4GO5PE09MEJsVSnpcqkBMM/PbP2vujfPp7VaNcOiGR8shA682gYcDxiKXo4hAsYfz0BQxkApCJDmBR%2BQHUUsRWHh6SZJUw05DhVAADgANg3WjJA2YBkGQDZbW%2BLgNggblLGsG5cEIO5zGFG4PCNE0ThErgZl4LUtDmCADVQCSrTNCALUklApxtSQNDlGhaCdYgXTdMMPWYYhQ19FT/QIIMQ2VCMoxjdk4xvPAkxTdk02QDNiOzQRc2VAsixLDAVnZCsqxrPh6ybFt207LMh2EURxEHHt5CUNRlV0AIdJnPi51CxcIGXVc0k3bdd33ZBDzJY9T3PS9bBg28IFcND7RfRCpmQnJki/dJIN/Qa8jSLD%2BvQ9rqlQ0aZvsMDMNfbCUM6bqBk6Kb3xk%2BZFmWPQK0wALSI4ZlSFZdlKJo%2BjGNOHT2Mkb4NBe7jeKsOcNkEogpKFe0NnEy1YkFMkzFk0VxUUpB8CoKh1KyvsMukLKR1y/MEHVSdMdhqgCD2dg5WITHsmJhRcfx/YNTOi6rt4SjqTwOGNmbNsQduhimJYtiOK4hMFA2Dn7uQR6pBel65KhqUZTlPNFUu5VKLVbJ5IleUODMcjrtVSHtRmOYkxMtJ4iAA
+C++ Cmake=z:OYLghAFBqd5QCxAFwE4FN0BoCWIIDGAtgIYDW6AgqsAM4gDkAtACIDCAspQNICiA%2BgCEAqgEkAMi34AVAJoAFXgFIAzCwBK6ADYB1HMgQt0AI1EA7AGYB7BlgJWiABxxb0qcSTPAAriWDpRABMQAiUAJkFwwTtvWmQHAHlvZEdkgDEXdDMSInQUBHR%2BdAAPdAJkkmNXLAtM%2Blh0QP0rVCCQADYazLaARgAWLtds3JBSHDMAOgJHRyxQBlscWnMCLW9AxsYABkXaDhJxgGUrb1QCPIYe3YTHLO3bLU9gNoWASiwIRubW4J7BgN%2BAFZ/sM8pxyOhxEtkLQJshisg5oxHKgrAArMrICC0BAkW60V5KLaUImUYgQ/hEcY4IjeIj8DAAR28OAwgQgADVeOpDqIEgA5ADUKgmgMJxNJJECgSKpXKyEqrmxuPxzJIGFJgq1gpxePQtAA9ARWat0FMZprtbr8QaMAQFV5XObHJatWNJtNHOKScSFTR0Mh%2BFpxmQgzhjKh1Th9cq9bQ1RridrBRYiMhAt7dis1htggwdrg9gczMdTud7oWbnd8w8nm1yRR3p8mvEfiAwv9ep1akMcnkMLQTmd9QaClotFY4QikQxSQAJbQTrCCgDuLS0gTAYFJpKYe6YpOkBUFvDMgVJWbMq3Wmxrhf2RyH5cu11uZgrjy89aiUSbX1bbQqJ2vwAJwgn2IA4JOnozpe165hWSwPiWT4XFclZvh%2BdZ5gwf4ti0bQDD2ALtls4EjFBEwILBhbZjeeYFkhxalsOjDoUsVbvnen7PDhrzvEs4IUPIqIYvaFZoiAfxmOgK4ZK4bRhD07xaIwgK2FxBZWIw0gYOggrhCo6HIPc/FYGQpGin0ADsIF9ICYRbICNl2c5WCqQwfQaRW2kLFg9BkSZNZNjAUChRASD2BsvD4aguD4MRoKjMWzo1FYZjIIcBAkK4UlEelyDCLQ6DyMUEkdO5TwhD%2BET%2BdomJQe%2BnxnmwVhrEQ749J0WSBFCMn8nSxhuCAQGOFYtD6I1rXtZ1nRjRNyCNX16ADUQQ2oCNdWuPajWHH6yDTXSs1bQ16V7eqyDLat62bXEF2HR1UmdHdqCXeMK2DcNKjvIOZYXIZ4zwfpqhsKmyBGi0ZoIKoygShKYQqIDObA2EYSUdDqM7sS4zIIK7oQK8BnWZESbamDIAgCiOMQOEYTyfp9gZVkMIgEogJsGYSjE1zLC08u/iBoEJAKgThIqCTJLWbzxK4e5aneXe2nuqlQU7E2kVWNFsXxRAiUQUJkLQrC8KItYGVZTleT9GlGVFSVZV3pJfw8SEpAUCdO3pfgPUPZ1WA9Vdn0bT0fzzZN6W%2B1JWBh4t6WB2tw0hx7sclvtkd/MV20p%2Bdr3xzdScvQdbVHVHhd54nyn%2BahjANoUVJmDSdIMugzKso0nLcryArCqK3qkii6KYrG%2BJ98SUoyiUZQVFU6AQAYhST/KiroK6gqUZ6q/K56o%2BUH6AthmYobBhGUYxvPspTwqM%2Br2DGYXip8tYJptjaQbUJxMb06q7LEUhJr6AxW%2BDrPWIwByoUNGOCcU5TYFQtrla2ZtCrFVKuVDsLtQgRCiMnRq3sWrF0en8AO71rrDTmuNcOZh07R3ISncuG1nr1U9qne6%2BC/aZ1Osw3OxCg4VULlQsu3CE70J%2BtXWcxIFzjisMuNcqANxbixpQfcB5iRHn0qec8MsH4MHUk/HyIAwF/QgYuScJssDf3Vn/LWQC8C60yEldeMwbaZWyvA/KttkEOwLJJIC6CarRHYUw3BgQqFEP6jwsCMcpqsKjpEuOgibpgQCdnNO0SM6MOSRdOhIBEkpJmqXfaWSQIiL%2BowAGV5kYGRUKDOIGAcgwx3AjJGN5KlsBqeMYA9S4aUDiMEEAbSvCCn3kLEWhMuYS2TD0imOALA1PQDkNeMyaaowMcOIxkjoG0zFuM7UsR2mClELjVQLAdTpimbMnIxhvAWH4PoNwwsWggwILiVA9TxarwwMgU4ZgTm9P6cACAByIDTIJMuQF/FVASx5vfOW2iFZaUgtBRx5iPgaysa2YBdiILoycXAq2bikH23KgMXxmDapJJwc1YJqT/ZnkKdQhaUS8mhxoUteJw1EnpN2rkkuaSs5csyWyjaOSWFMv8gUwV2TimsVnI0iwZ50AWEFGkBICR%2BBzgaSoDYtQZJKpVWqhRZSgYtL%2BZ0n03TTl9LQHsoZwsSAEwhQahGPVpnQo8jo5%2BWBtLYvMe8AoUphoE3MiAPoAAOCYfQI2RqjVGmFXksBEBAICMiHrfK2ACmY0yHxwrhQ1k4TIcUbH2Dza4DawAehbCAj2ZAbh6AQGMBWYw4x1QAE82K2EbdkVAzaEjGDEkFdCRbcgZQSGYLQra7wbEucANgOUtD0BfFgDYpBHQXALE0O0i0ABu%2BoKyL2SGhRYTMPIFmPpGLtrUNgVitQml87wLCPDoByaMK5OJtpxS4vFTi7YoMdptElkRarH3qFAJKYMsDbo2gwayPQVC4XeFYRwKd51MB6UcjBAHBCOUFEwBIKhsP3viC/CDqAcAbGAz9TlXtKUhNpRK5lDKI7UtiWYLJvKOE5yLqK8lZ1xVhKEfkkVPKxUCr4/nd4aBMBSS0e6vRDBBTFBDe0Jg7Q%2BiDIIAQQU5aJh4YgLpTABkEbKVsD6rAfqNgbUDRZQEIpnLtC2CBECYQQJbGsiGrYMHiWMDjQmvoWwrIhpUL55yAWgudBTYwNNIBAqZrgLAJAJwUjJGAbAj9eUv0ePKkBCT6BSNRxXJGRwbbpNwpfowJIiXcZWEVQppTKm1Maa0zp1qxa3AGZUN9YzplfVzPM/gLR3n2ztAmCHALYR2gjZUGNnoHZwt%2BXTci2LiAQB7vRTY9UdB5CeG0IcBAVgVweqLc4R4KdNsyS0DtvbXEB0OCO8NMt027A3fzfyCCflDv5vKxd/bb7F7UDoPo/U4DRzGOgf7OUe0mhcVsIg3FaXEHfs8bYJ2lUvDVVJdEID8AICgbTOB4aUGYNwc9YhxqyHUNqHQ1ELDOG8NMAIzYT1xHSM7sgO8VA3gMo0nQNIKwbVyNish6d7bu3vsLuy3lgrRWYUycVowXgcpkgtHk4p5TqngDqc0z0CYYRBQQDYH45cemUZGVeJ14K/XbAJva9p9rtu7d290bLubUWM3m6DYCLXgIvfe5997zoHlYOO/hX5EzFlbLhock5Fy9lHKAn94wMIlupJbGTbJs3astGJ6D6VkPXW8eoAml7PoQA%3D
+LLVM IR=g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:18,endLineNumber:6,positionColumn:18,positionLineNumber:6,selectionStartColumn:18,selectionStartLineNumber:6,startColumn:18,startLineNumber:6),source:'int+sum(int*+arr,+int+n)+%7B%0A++++int+value+%3D+0%3B%0A++++for(int+i+%3D+0%3B+i+%3C+n%3B+i%2B%2B)+%7B%0A++++++++value+%2B%3D+arr%5Bi%5D%3B%0A++++%7D%0A++++return+value%3B%0A%7D'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:25.411059109631243,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:ir,i:(compilerName:'x86-64+clang+14.0.0',editorid:1,fontScale:14,fontUsePx:'0',j:1,selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),treeid:'1'),l:'5',n:'0',o:'LLVM+IR+Viewer+x86-64+clang+14.0.0+(Editor+%231,+Compiler+%231)',t:'0')),header:(),k:42.23569365874194,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang1400,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!(),options:'-O3+-march%3Dskylake',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1,tree:'1'),l:'5',n:'0',o:'x86-64+clang+14.0.0+(C%2B%2B,+Editor+%231,+Compiler+%231)',t:'0')),k:32.353247231626824,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4
+Preprocessor=g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:1,endLineNumber:6,positionColumn:1,positionLineNumber:6,selectionStartColumn:1,selectionStartLineNumber:6,startColumn:1,startLineNumber:6),source:'%23define+MUL(x,+y)+(x+*+y)+%0A%0Aint+mystery(int+a,+int+b)+%7B%0A++++return+MUL(a+%2B+b,+2)%3B%0A%7D%0A'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:30.466941342614383,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:pp,i:(clang-format:'1',editorid:1,filter-headers:'0',fontScale:14,fontUsePx:'0',j:1,treeid:'1'),l:'5',n:'0',o:'Preprocessor+Output+x86-64+clang+14.0.0+(Editor+%231,+Compiler+%231)',t:'0')),header:(),k:42.496476357000276,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang1400,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!(),options:'',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1,tree:'1'),l:'5',n:'0',o:'x86-64+clang+14.0.0+(C%2B%2B,+Editor+%231,+Compiler+%231)',t:'0')),k:27.036582300385337,l:'4',m:100,n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4
+Pascal IDE=z:OYLghAFBqd5TKALEAXATgU0wGgJYgQDGAtgIYDWmAgusAM4gDkTORA9iQA54A2m6ADJkAdsACuZYJgCSAExBcy9ImV5tx9VJwDy41F30AxPphFkSmZqwBmpxrExy829PJABaAIw47/dwBMvqbmliDkqEg24iJE9AD0EVExcQB0SvQ4oEwxLgDUSdGx9ACkAMwAQiUADNQ11HgiqAI2ZESY9fWamKW1ef0FZJFFcY2oNuVVtfWoAJ5cHX0DACoAskNIRin0eeUAInlEvMr0EMsyTS1tTjoARgBWmESoOHky65FbxQCU9QN5hluvDwRD%2B/wGI1QeHYIjyAGUAI6SLDEGFaPIicQkEBvS7SdDfHEXZr4yZg/pmORk6a1PDcfiWJpDaEiTq1SEsvJrDZfNKI5GYVEidGY7G4kkCQnizCkyr1W4yxrk%2BFIshYPIgfYYrF5ABU2pI1OolKN9UpqXqrDw9AuR3EciczGqVvo60acPY4nQ7WYXhdOgWIl9rGOYncGVUvG%2BOAgThc7DcCiCflkCjKwX4oSsmAAHhYuPxUnIuOgstZ8DbYrx7Y6mM6K26RB6vT66/7A06Q6JgO4WNHY85XO50yn3AAWDNmCxWQrbRIbEb0MY2dLKMssCu26sOhRthtkd2e71WJh%2BisBsydnChnu7pjfaPWgDC6yoAAV0OxHs9gzh7iAfBETAAHcTH8BQAFZo14ZgINYIM93YZhliwTBdgCMoz1QTsHxwCgQDKCDUmqMcAE4ADYAA4ymo6ovAAdi8ciJxgpgx3gq8kI3RhqhwbC237RAIBQDgHQAUUHBN8EIFMsxAXN80LYtSxsGFUDhSMrC8CdVKaABVehMDfHMr3/IIb0UZRIxwQz%2BGeFlCEpJ92GrEggx8SlBEaTAADksQVdAAIgnAuHYJcoRhZzXPckKwpcFkvKAvySACoKbMwOyIqbVA1VQKKsRi2yniyuEcvQVBEt8/yBDSrRcvytyAJssqKu85LUq8KCbKPVsS3YYB0AsPIFPpDo5Rpahul6ah/lnYplzyRo8jAJg5riedhm2ZdV3oFacGVNadiWlbDo25Jih2lbTVqAA3NVlV5RguQ%2BTZtiNBVgCVJZ%2BgAdXQFxMEEEQIBWgAJDLeHYV4foTXg5DABH72umaBkejUtW5T5tlSJ8sCGMaphR/oxJzFxnIddGygOR7Un5NVBTKX5xuNEQ5AtWp72vWCOMQ%2BS81GosSz4nCYxE9hxMk0sCAgWTp3CBc50O7aMl8NSNLULSdLUgyjJMvd/3TCyIzUdLMoc2NWYamLPLa6rAonULwpZK2msd%2BKYUq9qaonIr7JhUr6pcgqmt9kqWs9u2QB9lqXZ8OryojlLvejegepPXJUEGTb5qaCZmfqMYrnaNlqDmBZlXeHltl2KnFsudBWmL77wRKCCKiu%2BiKjIMgyiIW4AkozAPDKMpqluDwxy8UivA8MhKLHjwiFImxOv7mw5Ho0iqXovYrogvYS/BCEUiylUBSFEUsSJPFJWviV0CNf4TXz2lRsZHKspL81OdYuCcAQ%2BsSFTpK1zjtYWAloxIEwGQB0gUIDRnwsxVIpEILVEwuRJipFKID0IlzNirBsReGqLxABrAuKsB4uA50uFWIBAISAeiARiIQUotgwiARSKTwYvRf%2BnFyz8WoTGISKBcxPH0FJaWaoGBvlEBlOESB2DAQQmeDg3A%2BDMhhDIoCvB5GKOUawVRPB%2BCBRsFwIgZQAhBEMaYdAeh1IKKUb%2BURRBaAMHLM40qzgEK2DVppACWt9KGWMqZJqRsrIm2BLcBw8CcDsC4FlRgTAPCrD2BlLgSA8AULTr%2BLQXitFyIcfoviqEmrAUGlwYM0Fua8N5kwEmYjXB5BzJRciHhmJ5FMUQPIZRUhMICHkCAMiVAmy5KhdCmFvisAEfeSB0DYGECqfgnA2IAj0WQVw%2BizF6LVBYWw8iNTAHlkodMmhzAyg80ORuE50YboCCXDCKOQA%3D%3D
+Java IDE=g:!((g:!((g:!((h:tree,i:(cmakeArgs:'',compilerLanguageId:java,customOutputFilename:'',files:!((editorId:1,fileId:1,filename:shapes/Square.java,g:'',isIncluded:'0',isMainSource:'1',isOpen:'0',langId:''),(editorId:2,fileId:2,filename:example.java,g:'package+myapp%3B%0A%0Apublic+class+example+%7B%0A%0A%7D',isIncluded:'0',isMainSource:'0',isOpen:'0',langId:java)),isCMakeProject:'1',j:1,newFileId:5),l:'5',n:'0',o:'Tree+%231',t:'0')),header:(),k:29.896907216494846,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:codeEditor,i:(filename:shapes/Square.java,fontScale:14,fontUsePx:'0',j:1,lang:java,selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:'package+shapes%3B%0A%0Apublic+class+Square+%7B%0A++++public+int+square(int+num)+%7B%0A++++++++return+num+*+num%3B%0A++++%7D%0A%7D%0A'),l:'5',n:'0',o:shapes/Square.java,t:'0'),(h:codeEditor,i:(filename:example.java,fontScale:14,fontUsePx:'0',j:2,lang:java,selection:(endColumn:1,endLineNumber:2,positionColumn:1,positionLineNumber:2,selectionStartColumn:1,selectionStartLineNumber:2,startColumn:1,startLineNumber:2),source:'import+shapes.*%3B%0A%0Aclass+Main+%7B%0A++++public+static+void+main(String%5B%5D+args)+%7B%0A++++++++Square+sq+%3D+new+Square()%3B%0A++++++++int+val+%3D+sq.square(args.length)%3B%0A++++++++System.out.println(%22Answer:+%22+%2B+Integer.toString(val))%3B%0A++++%7D%0A%7D'),l:'5',n:'0',o:example.java,t:'0')),k:80.08193737395916,l:'4',m:60.81932773109243,n:'0',o:'',s:1,t:'0'),(g:!((h:executor,i:(argsPanelShown:'0',compilationPanelShown:'1',compiler:java1601,compilerOutShown:'0',execArgs:'hello+world',execStdin:'',fontScale:14,fontUsePx:'0',j:1,lang:java,libs:!(),options:'',source:'1',stdinPanelShown:'1',tree:1,wrap:'1'),l:'5',n:'0',o:'Executor+jdk+16.0.1+(Java,+Tree+%231)',t:'0')),header:(),l:'4',m:39.18067226890757,n:'0',o:'',s:0,t:'0')),k:70.10309278350515,l:'3',n:'0',o:'',t:'0')),l:'2',n:'0',o:'',t:'0')),version:4
+Ada IDE=z:OYLghAFBqd5QCxAFwE4FN0BoCWIIDGAtgIYDW6AgqsAM4gDkDWBA9kQA44A26qAMiQB2wAK4lg6AJIATECRkkWo2snYB5Ucg5aAYj3RCSRdI2YAzA/VjoZONalkgAjFku8nAJjcGjJkOgAHsYcvAB0CgBGWKBMuLRSQgTcojK2jAAMzDi0ALIkOEIAyqyiqASmDFnx6hyGmczcwsBOTACUWBC29qyOct7u0nIAzD68fqbmrKwRMrQxZvGJyanpVdl5BcWl5ZXOG7X161hNIq0MHV12Dk6jg04ALGOGxpPTs9GxG8spaXLHOXyhRKZQqjH2NTqQgaJ2a50u3RucgAtK57nIAKzPCYgQo6ZBhZCBZALBjOTzDACkGUoFIe1MozgynnpNO%2BSV%2Ba2qgK2IN24IOUIFsLOcgUJDaHRyAGF8hQAAqoVgAK3QBGQwuVLiwQnQAHd9B45AA2DrcRgY5jQ46sRgAFQw6AA1JSKRCNetJVgyC4ABxhB7OB4PACcxoyvoxAHZjc5hsNjSdGA9mEQXBkMjqYba4vRMx6spcYFBixAkGw0gBRa69XD4QY4qYzBTzKZCZBFAgkXguJ5t5AAVVo6HlgRhWu8p1A4qww946pwrGhXSEMmlrBSRGhrkMMn4hXQADlRERInwQN4OKxaPZF0J15vt1grzfkHf97rj6fz9452q30uRTICQqDIA%2BJ5Pn%2BC6AcBoEfkeJ5nqgF6zrBYEbhB2qqCByDwV%2BSEXh0tA7GCDB6vYCBOpQihhHaQTIAA%2BlI6iUsMABCTqcVxXEqM61EkLR9FMSx7EMgyHAkAQZASM6ujTE6OQMpx5iiEkAFCE6uQAJ4MboqkEE6ECUE6IBOokyDoJIqCsRxuimYa6AMXaWl1G0ToYMgZQaeZll8DZDK7k6cmsDZFxJgwlpZjaIBNrM8wFhcHQIOgCjnhAHQ%2BsMzhhMaYZxsanhBr6GaeIm5oMCmWBpp4GJhMyIbBsaDwZFGGLDL6ni%2BlF1Q5sweZYAlRbwGWIAVug1Y9KgdYQA2rwBMEnDhFEbhLh2XY9kGK3tkOI5jscWquFO8iKLO6Dzup%2BC7uBW4gBi3i7nhiHnlGz7XreS7XdCd2va%2B74Hvhz2nedd5AThn23b%2BZ3/iDaGPd%2ByEvdhoHg99SO4f9T0I0RJGVORyCUfxgnEsJNlOrxVE0XRxPMf5NJ45RwWk%2BTjOiTSHBKhUMhlM6lYLaEzqKTSnF2UFBhOS56C05QZ7AIUSlOocGkQLoWBmUIukGKrrqeHiWiEsS2ttFLnHyloDHwYZ2t2slTpCJjTrmEqRBBdMpnay6pWaTpelJIZoxBW0YAMFIpCSEbrOUIFvMhLwoVmhaVrZvNMfoB8A0NF6yWpch6XhZVabxmE0YZMarVMhiDyRhSibWj1iz9YNnSluWrBVjWU14DNvhzbFy39p23amJt/Y7aO44gKMR0zlBF0rmuGE3c4IZYA9GPwy4rgvu994L9uy9b%2BpcMEc4rgzzDYO7y4y9nzBOFH%2BeJ%2BoRfj5X0/cFr8fzjY6CuMURTAlU0YjTdi3FQHk0JoAkmEd6b/zCD5KyTkhLAI4uAmi8C%2BCIOpiJNiYk2aSWkpIJ0kRW5aRdqwBStB5YqTUneL2ul9KGWMqZdB1kQEiwcuLVy7l0CeVQN5dsvlUAUPlpxSgBADLMIEVZEyrEAAiToMjGyIZZOWQsuJ6gQAYQyQhWDIFgZA5iYRKyrgYuocwGteCGV0JKJ03BpgcBEVxAA4jw5WqsxEEHDjgtRnFAp2NYA4iO3EPJeSoh7DiHilGBW0vQpIUtAoszYmFcqkVa7MFtL3GQ0RBpJRSmkHO8cKqphAIGMIwwQwhl9FGX0ldcoxixGkrAvVZwgHzBnDKEMwiRmcMaXpnUoyeEGU1cKwxE7RTiI3OAsBm4gFKNoLQ002CcAMKgQ8c0GCBF9MaZETUnTACMHo8kYRPAWFWgPDafZVqjz2tUA6A1HQ4DkK4PUqASAcAFIU1JScGCaHmXo1g5gnSbO2bs/ZJBDmeGOYZdcyzeBCNdFlNozAcnegvCGIuWUKTlIxLGDI5Swx52KYMspUYQylRDAMkMGQQzDAyA075fVWnp09E3YaLdYV8EWewLgcKQBguQOSbwaQABuOAKgADUcD6kVsKdwFlUD0AgJEGEkRCggS0sKJZJh2zqCENwDVxw0ikBED2Q1OAMALmFegegxwghqi0JUbkAjyrVG4DgSIrzUBaXXGkGEaAcBpjJGFcwTQ6CSulUKINW01qD17NG6549DrNGOkoN1kRrC5wCepG1fUobQWXFdS%2BO5Vz32QpvN66lwblt%2BkuUtWE83qVBsjItQNoa33fp%2BTGWE0JVrfujTt68v73MwC4T5Yy64MCBVsnZDw9kHKdEczwhkHSYA9oi5F7SsBZ3yfgQp%2BcQBRijDlTwLVaWeCjNSkuIZ6XjMZW0z0HTOphCjPGX0wwYznoyD05kIzx3pMWCi8qJzur/omZuq1Cq7wlKAA%3D
+Android Java IDE=z:OYLghAFBqd5QCxAFwE4FN0BoCWIIDGAtgIYDW6AgqsAM4gDkAtACIDCAspQNICiA%2BgCEAqgEkAMi34AVAJoAFXgFIAzCxboARgFdgDLAQD2RAA44ANulTiSAO2DaSwdKIAmIO69SGcrpgCsSADcSA21aZGMAeW1kE1iAMQt0WxIidEZ9ADNk%2Blh0VxxI1DcQAEYsHMtSiqqUtIyTbzqAOibDLJbkAA9kLFAGfRxaUVsCc21XAsYyodoOEhxbAGVDbVQCDIZZ3FookxTGAAZ9cztgUsGASiwIAqLDEvcAJkrk0te61PSQdG60kyWFqBEL9TK7UbjSbTBgnXYLJardabY5zfaHWGnc6XBg3O6FYqlFRvaruAAsJPqP3aDhIqFcLQIWWAYMGELGEym7m2cwRKzWGy2O2G6NsqKwZ3sOKuN2GnHI6Hk3n86AIyBm%2Bn85SwtnQAHckqSQABWG7mRjG/RizFYQyMaQYdAAaiUzxUO3VmJlWAQ6BIU1Q%2BBuZBAzyOLQAbFGVM8I0cI2SybHjSpjRLGGSreK7Wz6EcsJ6TniYIgQEYprwCY9cPgvg0QO1Wo2ur1KoZbMhlgQSJZyhSsu3kMJaIruuKtRVJaBPN5fAFgqER5Y1Th2/gUq42IYJkQxRUN%2BIlugAHLaIiaKwgCkmQy0Iqr2xbnd7rA3u/IB%2BH3Wn8%2BXilL1UP3bZZkDpZAnzPF8AJXYDQNQZAvxPM8L0Df84PA7dIO1CIwMQn8UKvG5aAFFEGAACWWeRxGWABHRwMFUQQmFUZQVDYJYihYiArgANSUI5KAoqjaPo9BGOYlReFoOi6XQCBRCuUR%2BMoaiZIYlRBGU3F0wYS0dWzBtmmSNpmhbPpC20iAkHLdBKweVAawgOtqW8Wl6UZZk2w7LsewyMp%2B0HYdR3HEBiSnDxbC8Hw/BBRd0GXICxTuSKIN3ULiQPI98MvCo33vdtUrFFRiTyxK8OQnKsGgxKQLAwr0qq%2BLAIfWr4PK39AwqHD4Pq4qqvQ9qCLKIiSK2JgKHQEwnXGEhaFoJ0RNkl0AHZBCdeJNHMHACCdAAqRiVpYbTzV0rMbTtGl6IZJkWQsvFrMMCsqwcvAnOSb4Mj%2BAEgVirzO27Xt/L%2BoL5DHG0tVecKZ2i%2BdQWqh91xSzC0teTLvwqzrltfW98sfZGxVeUrPyyjHyix%2BHYLq/HQ0ahKWoGkmOrJ/qqefGnuoQxmhuWkbkS2AB6fmnWkABPA4nRFgVpse51fQwLAnUeJ1zEMf0nTsJ0vtMIFlMF3WhambpnlV5B1qMywmAcXwCml0wLBIRKQH1p1KFcVwXWeZ5G2M5semQV1nidSIPeeSFORtupaAD9XIumraCDIIPfSdDAsgwWgECdHRkEiWx1f9gTBaT51NEMHPjEVrJi9tsxLFQRXYniU2TDseKWidBIleQZPvcsJ0B1QUg%2BidEcxMLoWEBzkx6EFqYgniwwDlQFpod8RljH5yIzAIfml4H0gxnQfnNFm%2BKj179BaH5g/HHMcwRaYAgMAd9AmHSWb1jEt0phyXUmFQbQlhaBvzsLfe%2B%2BtnYACUAAcTolSGAAOJXSdBNKaAC%2B5LCbk7ceLs3Yh0unSa6zJo7BwDmHaE7tI7R08HHbaidu7OlTunTO2dc752rs7Uu5ciCV2rkYO2dcG5xFiOtVu5h26d3rvApBhCnThCcNgEemBnaTziDPfmepNEtDcq4aSol15EGvqAns/MjC2ByA4VADsHz83kc4ZSykZpzQWmpZ0ShVrKSdF49a2hNrbRHqBD8O0limz0bJCAISnS2DPFcFamkBLeMSSndAyB1h52iTw3aUSzyMU8d49xLAHHLUKQJY6Fozo7DtFrQE6BgQLgLKib0IZEwtCOAATjKG0540DirPDaSoeMQMTqZn0udcE9BXh3VuCWKyZZjC1ysI5fhCzAyxSYIbY2DsmBnGQJfPoVRdmoHoBATQ4pNBLDpCLDUWBzmpFQCLKImgVRqmufw9IHYoi2HvuKKYOhgBsB7OYegPIsBTAPsAXsNpCgYBXPPYFcI/iqliEKIYHZ4rii2poKx9ytxTHFGgHARBrnz1QKXEcGhwVbXsI0yoZw6A8RwPqUU1yBzeQBn5AKHYQZgzhBDCU5wIpRTnL9TFeQoAfUFbOPwJAzBMAiL42gWASUzDKFGN00CIyWQlagaB41MAt1sLYQwSrLwMB6SoZauIbiL0SsC/QhgSWoGtmKoiTUYJJQ3PVfckVBqVSJgVamuUcZlS5pVCmKx0Jetps1SmbVQ2dRZj1QNibOboyZsNAsjpyhmnKaMuEOYXaQOkE6DZJtlYvwiE6CADpMAe3dFcfQd1gyhWNC0Z4ZIyjLTJMaOMsYkwap0iM60%2BbxkgHzE2nSzwzojrZBOkld41xkiAA%3D%3D%3D
+Android Kotlin IDE=z:OYLghAFBqd5QCxAFwE4FN0BoCWIIDGAtgIYDW6AgqsAM4gDkAtACIDCAspQNICiA%2BgCEAqgEkAMi34AVAJoAFXgFIAzCxboARgFdgDLAQD2RAA44ANulTiSAO2DaSwdKIAmIO69SGcrpmUNkcxxbA21aZGMAeW1kE1iAMQt0WxIidEZ9ADNk%2Blh0VxxI1DcQAEYsHMtSiqqUtIyTbzqAOibDLJbkAA9kLFAGfRxaUVsCc21XAsYyodoOEhCAZUNtVAIMhlncWiiTFMYABn1zO2BSwYBKLAgCosMS9wAmSuTSl7rU9JB0brSTSwtMh9AZzUbjSbTBjHHYLZardabGHDPYHaEnM4XBjXW6FYqlFSvaruAAsRPq33aDhIqFcLQIWWA/UyO3BEym7i2czhthWaw2MzmqNsRwx9ixl2uw045HQ8m8ACt0ARkIKsArylhbOgAO5JYkgACs13MjEN%2BhF6KwhkY0gw6AA1Eoniptqr0ZKsAh0CQpqh8NcyCAnmUWgA2Q6G11lEkklRxmMATiwpoYJItoutLPohyw7uOOJgiBARimvDxD1w%2BE%2BDRA7Va9a6vUqhlsyCWBBIlnKZKyreQwlocu6mY1FVO9g8ti8Pj8ASCISwQ8sKpwrfwKVcbEMEyIIuTm/EIXQADltERNFYQISTIZaEU17Zt7v91hb/fkI%2Bj9qzxer4Tl2VT9WyWZAaWQZ9z1fQDVxAsDUGQb9T3PS9/QA%2BCIJ3KCQGTCJwKQ39UOva5aARAUGAACSWeRxCWABHRwMFUQQmFUZQVDYEIijYiBLgANSUQ5KComj6MY9BmNYlReFoBiaXQCBREuURBMoWi5KYlRBGxFMzQzLks3rZI2maJs%2BnzHSICQUt0HLe5UCrCAa0pbxqVpelGRbNsOy7DIYy8gch3kEcrQ1QkJ1ATxvF8fxAmCUIYOAkVbmnSC901Q9j0Iq8KnfB9WzSkVcrvfLbAIlCcqXdAVyS0DwMKzVEsfOqEPKv9/QqPCEIazqMLaoiyhIsjNn8TATAdcYSFoWgHTE%2BSnQAdkEB14k0YICAdAAqZjFpYHTU3NLVMxtKlGLpBkmQsnFrMMMsKwcvAnOSL4Ml%2Bf5AWBAKfO7fy%2BzbQdh1HYMUzOKcZxi%2Bd4qqmrHw3VKsPSipMp/CqOrDN8SqSnqMY/L8stR8p0aauD6oRoroaA5q%2Bvx9rCaXDDsa6xCaYGsMhv5TYAHpOYdaQAE99gdPmEQm27HW9DAsAdB4HXMQxfQdOwHTe0xAVU7n1Z5qZuieeXkBW5pkiYBxfAKUXTAsEgkpATWHUoVxXCdJ4niMwFGx6ZBnSeB1Iidp42UhR26loL3FenCb1rIH3vQdDAsgwWgEAdHRkEiWxFc9oTuejx1NECSIiGlrIc/NsxLFQaXYnifWTDsaqWgdBIZeQGPXcdPtUFIPoHSHCSs55hBU5MehuamAA3arDH2VAWii2d6WMTnIjMAhOenjvSDGdBOc0KbquPNvaE5zfHHMcw%2BaYAgMCt9AmHSKa1gkl0phybUmFQbRLFoO%2B7FP8/NdtgAJQABwOnlIYAA4mdB0FB0DjQ/pYB0IRq4237nbB2ftTo0nOoyUOvsvYBw5A6YOodPARxwAQKOLdHRxwTknFOacM4l1tnnVOxgi4lyMBbculc4ixBWnXcwDcm4V3AVA7BDpwhOGwD3TAttB5xBHpzHUKiWhuVcLJcSC8iDH1/l2TmRhbA5AcKgK2j5OZSOcKpVSq11oRymjNOaGBFqCFUg6dxxDtDp00fJCAthzwgAdKMZAlxAnBKdGoB0/jC6bSieeaxC0WCqX2npI6VobQqwBOgIE5lRSeiDCSBaLRYyGhJE8Q4C0FokhjGUKpuk0z6RhDaQYS5gZXRuEWKyJZjBlysI5LhvT/SQxCEwbWusrZMFOMgdAEQiTTNQPQCAmhMyaBCDSPmapVmpFQHzKImglQqjVFw9IbYoi2HPpmKYOhgBsC7OYegBkpib2AN2K0hQMCrgng8mEvxlSxE2NsEI0zUwwmCJoUxOztxTEzGgHARA1QT1QHnIcGhnnxQGAWSopw6B8RwLqYUao/rtk7D9Xs/YAbBSBi8CKYNopzjiouMFeQoAvVpbOJgJAzBMAiNoTQtAsCIpmGUMMYYXTALDJZVlqBgGjTgXYWwhgBVXgYMAlQKgFrYmuFPJKDz9CGERagU2zKSLVUpuuFKW4yYZWnP1SqeUsZWuKrjVstqOoU1gryBmjr3W1WpijWmvVSYvkan65CAbrhoEwOUE0qTLRNMYHbQB0gHRjL1rLG%2BEQHQQDtJgJ2rpLj6CuoGa8hwWiJhJImJ4YZKnAKeGU6twD6npjSfGlpOY8x5JjQwJ4jS9UsiLUqhZsMSRAA%3D
diff --git a/etc/config/site-templates.yaml b/etc/config/site-templates.yaml
deleted file mode 100644
index bc1d9e7b4..000000000
--- a/etc/config/site-templates.yaml
+++ /dev/null
@@ -1,35 +0,0 @@
-meta:
-  screenshot_dimensions:
-    width: 1000
-    height: 800
-templates:
-  - name: Diff of Two Sources
-    reference: |
-      z:OYLghAFBqd5TKALEBjA9gEwKYFFMCWALugE4A0BIEAZgQDbYB2AhgLbYgDkAjF%2BTXRMiAZVQtGIHgBYBQogFUAztgAKAD24AGfgCsp5eiyahUAUgBMAIUtXyKxqiIEh1ZpgDC6egFc2TA3cAGQImbAA5PwAjbFIQC3IAB3QlYhcmL19/A2TU5yEQsMi2GLiEh2wndJEiFlIiTL8AnntsR3ymGrqiQojo2Pj7WvrG7JalYZ7QvpKBiwBKe3QfUlROLksAZlDUXxwAajNNjwA3SpJSI9wzLQBBG9uT9AJMfcx0AH0ldA4PgHcyABrCChIjzI42O4PJ4vfaJUjoNZKJQfYjYNhKCAYJgTfYTTAgEBnJxkI4eUFXSwANn2xPmhwA7JDbvtWfsWD4SHiAF6HTYAEVplQAdKludgIODNsy2ftBKQIPjCWLsB8iPsCHzBVoIRq%2BR4ebqCLZbPSzEyHrLZe8vj9VQDSMDiWYAKxWY0u/lSmVs838h5%2Bh5cRb0bgu/gBLg6cjobgeE3WPHLVbYQ4WTZ8chEbTBxaAkAurSGbjSfhsAtFyPR2NcfhKEBF7NR4PkOCwFAYHD4YhkSjUOiMVgcbiZwTCMQSTgyOTCZRqTTN8j6BJGExoBN2CpVVwQdyjAIWFrBabFUogBlJFJpIT7%2BItXLXpi9U8DC9bjpdEbeJp31rtaqTM%2B/RxG%2Bky3oeQzdEBswgYs3wrGs3BbDseypmSxIXJSUJ3DCrw2t8vwOsCoLegGOHPK88KItgyKokQ6KYtiuJKkS5ykscFKbNcFg0nSjI%2Bqy8oQByXJomw%2BwgEKqBmhadxWmy%2BF2v8QIgvRbCkXJvoMv6ULaUGIZhhGOYxnGG5JghaHphY/BNjo8yLEg2AsDgcSSsWXCluQ5aFuQVb8DWdYNlmOb2eQ%2BbSC6wpUgAnDw0VaFSWhaC6FiHtFmzuZsRmLgFwXNosbbIGgPyJAwsR9liJVlXEuzGMAPCbFoLQDvRpD1hAUTGVEoR1AAniO/AYGwHDCAA8kw9D9YuOBsHVkjTQQpDnAQZz1ou2DqJUnLrJmoJtMZ9AEFEpB9V4ODGUQpAEOWvAtjQRjAEoABqBDYH8o2JMwA0zqI4iSNOY6KCoGjGfoLSrqYG6GEd9aQIs6CJB0a0ALSjVlf7LTue7fmM5DHkUwE5FeHS3vexPpNBZ7jG0mOdGBOPNBj2501BJ6E%2BM9NZIzEyswTMFSHByaIS0l3YDtLahlw4a%2BcZNbqAAHFSyNUtI%2By1SY%2BwNcKWjCjw%2BwQPG1i2OQ%2BzdhcaYZibXhsKVjCkBbPDzDZIWth2VV2xVQ22wM6v1Y1zUMK17WdYu3WsKQU2ZkNI1EONk3GTNc3rNGhBLVUq3GRtW30d9e2S9Gh3HadWDJzZV03Xwiz3Swj0vW9H1fbdP0Tv9siA3OIOLsuhh1euRvWNDUSw25CNI9wqPo%2B%2B6RuEwngM4Es%2BUwMZN5OkpOXqvBRs/z1P/kIn4NPPu%2B0wfS9xBz3Trzz9RnwLSwWYMoviwZUvZdW3AK0rKtqxDmubNrut9aGxsAPU2hBzZbASPsa23t7aQKdnlOyrsQCEBoDQCqgMW5TjbvIDuC4C5IHrODQhqCaBEF6p9IKpBCGDGoUoUh5DKFaBftLPyJkuD8gIGg/Ydc/ixH2J/ZWqtfZ/wAXrE4SgBGKyET/OqoidaZlsrmcgjlnIDDcvmF00hhSNXllodK0VorSAZAyPRDIqTuU8uWHgSUZY5W4IFBISjQqS2snY9%2BtZEHKLOG1ae0ggA
-  - name: Diff of Two Compilers
-    reference: |
-      z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYTStJg1DIApACYAQuYukl9ZATwDKjdAGFUtAK4sGIM6SuADJ4DJgAcj4ARpjEINIADqgKhE4MHt6%2B/qRJKY4CIWGRLDFx0naYDmlCBEzEBBk%2BfgEVVQI1dQSFEdGx8ba19Y1ZLYNdoT0lfZIAlLaoXsTI7BwA9KsA1AAqAJ4JmBs7C8QbaFgbCLGYpBskG7SoTOgbhhuYqqwJ9AB0JhoAgqECBsFABHLx1TAQIEbBg%2BGYbEwAdisAI26I2xEwBEWDFhPg2ACp8SwTABmVH/ZEAEQ4c1onAArLw/BwtKRUJw3NZrCDjstEWYyTxSARNHS5gBrECMjT6TiSFnijmcXgKEBysVsumkOCwJBoFgJOixciUQ3G%2BhxYBcMxcPh0AixdUQKLKqKhOo7Tgiw1sQQAeQYtG92tIWBYhmA4jD%2BCxVQAbph1WH3pUvE6fbwgZgGWHaHgosQvR4sMqCMQ8Cws3MqAZgAoAGp4TAAdwD%2B1ZIv4ghEYnYUhkgkUKnUYd09oMRhQPMs%2BkL6sgc1QCXyDBTAFoA2SNhvI0sEOTqQpJTsDJLMGrc5U1y4GO5PE09MEJsVSnpcqkBMM/PbP2vujfPp7VaNcOiGR8shA682gYcDxiKXo4hAsYfz0BQxkApCJDmBR%2BQHUUsRWHh6SZJUw05DhVAADgANg3WjJA2YBkGQDZbW%2BLgNggblLGsG5cEIO5zGFG4PCNE0ThErgZl4LUtDmCADVQCSrTNCALUklApxtSQNDlGhaCdYgXTdMMPWYYhQ19FT/QIIMQ2VCMoxjdk4xvPAkxTdk02QDNiOzQRc2VAsixLDAVnZCsqxrPh6ybFt207LMh2EURxEHHt5CUNRlV0AIdJnPi51CxcIGXVc0k3bdd33ZBDzJY9T3PS9bBg28IFcND7RfRCpmQnJki/dJIN/Qa8jSLD%2BvQ9rqlQ0aZvsMDMNfbCUM6bqBk6Kb3xk%2BZFmWPQK0wALSI4ZlSFZdlKJo%2BjGNOHT2Mkb4NBe7jeKsOcNkEogpKFe0NnEy1YkFMkzFk0VxUUpB8CoKh1KyvsMukLKR1y/MEHVSdMdhqgCD2dg5WITHsmJhRcfx/YNTOi6rt4SjqTwOGNmbNsQduhimJYtiOK4hMFA2Dn7uQR6pBel65KhqUZTlPNFUu5VKLVbJ5IleUODMcjrtVSHtRmOYkxMtJ4iAA
-  - name: C++ Cmake
-    reference: |
-      z:OYLghAFBqd5QCxAFwE4FN0BoCWIIDGAtgIYDW6AgqsAM4gDkAtACIDCAspQNICiA%2BgCEAqgEkAMi34AVAJoAFXgFIAzCwBK6ADYB1HMgQt0AI1EA7AGYB7BlgJWiABxxb0qcSTPAAriWDpRABMQAiUAJkFwwTtvWmQHAHlvZEdkgDEXdDMSInQUBHR%2BdAAPdAJkkmNXLAtM%2Blh0QP0rVCCQADYazLaARgAWLtds3JBSHDMAOgJHRyxQBlscWnMCLW9AxsYABkXaDhJxgGUrb1QCPIYe3YTHLO3bLU9gNoWASiwIRubW4J7BgN%2BAFZ/sM8pxyOhxEtkLQJshisg5oxHKgrAArMrICC0BAkW60V5KLaUImUYgQ/hEcY4IjeIj8DAAR28OAwgQgADVeOpDqIEgA5ADUKgmgMJxNJJECgSKpXKyEqrmxuPxzJIGFJgq1gpxePQtAA9ARWat0FMZprtbr8QaMAQFV5XObHJatWNJtNHOKScSFTR0Mh%2BFpxmQgzhjKh1Th9cq9bQ1RridrBRYiMhAt7dis1htggwdrg9gczMdTud7oWbnd8w8nm1yRR3p8mvEfiAwv9ep1akMcnkMLQTmd9QaClotFY4QikQxSQAJbQTrCCgDuLS0gTAYFJpKYe6YpOkBUFvDMgVJWbMq3Wmxrhf2RyH5cu11uZgrjy89aiUSbX1bbQqJ2vwAJwgn2IA4JOnozpe165hWSwPiWT4XFclZvh%2BdZ5gwf4ti0bQDD2ALtls4EjFBEwILBhbZjeeYFkhxalsOjDoUsVbvnen7PDhrzvEs4IUPIqIYvaFZoiAfxmOgK4ZK4bRhD07xaIwgK2FxBZWIw0gYOggrhCo6HIPc/FYGQpGin0ADsIF9ICYRbICNl2c5WCqQwfQaRW2kLFg9BkSZNZNjAUChRASD2BsvD4aguD4MRoKjMWzo1FYZjIIcBAkK4UlEelyDCLQ6DyMUEkdO5TwhD%2BET%2BdomJQe%2BnxnmwVhrEQ749J0WSBFCMn8nSxhuCAQGOFYtD6I1rXtZ1nRjRNyCNX16ADUQQ2oCNdWuPajWHH6yDTXSs1bQ16V7eqyDLat62bXEF2HR1UmdHdqCXeMK2DcNKjvIOZYXIZ4zwfpqhsKmyBGi0ZoIKoygShKYQqIDObA2EYSUdDqM7sS4zIIK7oQK8BnWZESbamDIAgCiOMQOEYTyfp9gZVkMIgEogJsGYSjE1zLC08u/iBoEJAKgThIqCTJLWbzxK4e5aneXe2nuqlQU7E2kVWNFsXxRAiUQUJkLQrC8KItYGVZTleT9GlGVFSVZV3pJfw8SEpAUCdO3pfgPUPZ1WA9Vdn0bT0fzzZN6W%2B1JWBh4t6WB2tw0hx7sclvtkd/MV20p%2Bdr3xzdScvQdbVHVHhd54nyn%2BahjANoUVJmDSdIMugzKso0nLcryArCqK3qkii6KYrG%2BJ98SUoyiUZQVFU6AQAYhST/KiroK6gqUZ6q/K56o%2BUH6AthmYobBhGUYxvPspTwqM%2Br2DGYXip8tYJptjaQbUJxMb06q7LEUhJr6AxW%2BDrPWIwByoUNGOCcU5TYFQtrla2ZtCrFVKuVDsLtQgRCiMnRq3sWrF0en8AO71rrDTmuNcOZh07R3ISncuG1nr1U9qne6%2BC/aZ1Osw3OxCg4VULlQsu3CE70J%2BtXWcxIFzjisMuNcqANxbixpQfcB5iRHn0qec8MsH4MHUk/HyIAwF/QgYuScJssDf3Vn/LWQC8C60yEldeMwbaZWyvA/KttkEOwLJJIC6CarRHYUw3BgQqFEP6jwsCMcpqsKjpEuOgibpgQCdnNO0SM6MOSRdOhIBEkpJmqXfaWSQIiL%2BowAGV5kYGRUKDOIGAcgwx3AjJGN5KlsBqeMYA9S4aUDiMEEAbSvCCn3kLEWhMuYS2TD0imOALA1PQDkNeMyaaowMcOIxkjoG0zFuM7UsR2mClELjVQLAdTpimbMnIxhvAWH4PoNwwsWggwILiVA9TxarwwMgU4ZgTm9P6cACAByIDTIJMuQF/FVASx5vfOW2iFZaUgtBRx5iPgaysa2YBdiILoycXAq2bikH23KgMXxmDapJJwc1YJqT/ZnkKdQhaUS8mhxoUteJw1EnpN2rkkuaSs5csyWyjaOSWFMv8gUwV2TimsVnI0iwZ50AWEFGkBICR%2BBzgaSoDYtQZJKpVWqhRZSgYtL%2BZ0n03TTl9LQHsoZwsSAEwhQahGPVpnQo8jo5%2BWBtLYvMe8AoUphoE3MiAPoAAOCYfQI2RqjVGmFXksBEBAICMiHrfK2ACmY0yHxwrhQ1k4TIcUbH2Dza4DawAehbCAj2ZAbh6AQGMBWYw4x1QAE82K2EbdkVAzaEjGDEkFdCRbcgZQSGYLQra7wbEucANgOUtD0BfFgDYpBHQXALE0O0i0ABu%2BoKyL2SGhRYTMPIFmPpGLtrUNgVitQml87wLCPDoByaMK5OJtpxS4vFTi7YoMdptElkRarH3qFAJKYMsDbo2gwayPQVC4XeFYRwKd51MB6UcjBAHBCOUFEwBIKhsP3viC/CDqAcAbGAz9TlXtKUhNpRK5lDKI7UtiWYLJvKOE5yLqK8lZ1xVhKEfkkVPKxUCr4/nd4aBMBSS0e6vRDBBTFBDe0Jg7Q%2BiDIIAQQU5aJh4YgLpTABkEbKVsD6rAfqNgbUDRZQEIpnLtC2CBECYQQJbGsiGrYMHiWMDjQmvoWwrIhpUL55yAWgudBTYwNNIBAqZrgLAJAJwUjJGAbAj9eUv0ePKkBCT6BSNRxXJGRwbbpNwpfowJIiXcZWEVQppTKm1Maa0zp1qxa3AGZUN9YzplfVzPM/gLR3n2ztAmCHALYR2gjZUGNnoHZwt%2BXTci2LiAQB7vRTY9UdB5CeG0IcBAVgVweqLc4R4KdNsyS0DtvbXEB0OCO8NMt027A3fzfyCCflDv5vKxd/bb7F7UDoPo/U4DRzGOgf7OUe0mhcVsIg3FaXEHfs8bYJ2lUvDVVJdEID8AICgbTOB4aUGYNwc9YhxqyHUNqHQ1ELDOG8NMAIzYT1xHSM7sgO8VA3gMo0nQNIKwbVyNish6d7bu3vsLuy3lgrRWYUycVowXgcpkgtHk4p5TqngDqc0z0CYYRBQQDYH45cemUZGVeJ14K/XbAJva9p9rtu7d290bLubUWM3m6DYCLXgIvfe5997zoHlYOO/hX5EzFlbLhock5Fy9lHKAn94wMIlupJbGTbJs3astGJ6D6VkPXW8eoAml7PoQA%3D
-  - name: Preprocessor
-    reference: |
-      g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:1,endLineNumber:6,positionColumn:1,positionLineNumber:6,selectionStartColumn:1,selectionStartLineNumber:6,startColumn:1,startLineNumber:6),source:'%23define+MUL(x,+y)+(x+*+y)+%0A%0Aint+mystery(int+a,+int+b)+%7B%0A++++return+MUL(a+%2B+b,+2)%3B%0A%7D%0A'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:30.466941342614383,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:pp,i:(clang-format:'1',editorid:1,filter-headers:'0',fontScale:14,fontUsePx:'0',j:1,treeid:'1'),l:'5',n:'0',o:'Preprocessor+Output+x86-64+clang+14.0.0+(Editor+%231,+Compiler+%231)',t:'0')),header:(),k:42.496476357000276,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang1400,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!(),options:'',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1,tree:'1'),l:'5',n:'0',o:'x86-64+clang+14.0.0+(C%2B%2B,+Editor+%231,+Compiler+%231)',t:'0')),k:27.036582300385337,l:'4',m:100,n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4
-  - name: LLVM IR
-    reference: |
-      g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:18,endLineNumber:6,positionColumn:18,positionLineNumber:6,selectionStartColumn:18,selectionStartLineNumber:6,startColumn:18,startLineNumber:6),source:'int+sum(int*+arr,+int+n)+%7B%0A++++int+value+%3D+0%3B%0A++++for(int+i+%3D+0%3B+i+%3C+n%3B+i%2B%2B)+%7B%0A++++++++value+%2B%3D+arr%5Bi%5D%3B%0A++++%7D%0A++++return+value%3B%0A%7D'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:25.411059109631243,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:ir,i:(compilerName:'x86-64+clang+14.0.0',editorid:1,fontScale:14,fontUsePx:'0',j:1,selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),treeid:'1'),l:'5',n:'0',o:'LLVM+IR+Viewer+x86-64+clang+14.0.0+(Editor+%231,+Compiler+%231)',t:'0')),header:(),k:42.23569365874194,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang1400,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!(),options:'-O3+-march%3Dskylake',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1,tree:'1'),l:'5',n:'0',o:'x86-64+clang+14.0.0+(C%2B%2B,+Editor+%231,+Compiler+%231)',t:'0')),k:32.353247231626824,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4
-  - name: Pascal IDE
-    reference: |
-      z:OYLghAFBqd5TKALEAXATgU0wGgJYgQDGAtgIYDWmAgusAM4gDkTORA9iQA54A2m6ADJkAdsACuZYJgCSAExBcy9ImV5tx9VJwDy41F30AxPphFkSmZqwBmpxrExy829PJABaAIw47/dwBMvqbmliDkqEg24iJE9AD0EVExcQB0SvQ4oEwxLgDUSdGx9ACkAMwAQiUADNQ11HgiqAI2ZESY9fWamKW1ef0FZJFFcY2oNuVVtfWoAJ5cHX0DACoAskNIRin0eeUAInlEvMr0EMsyTS1tTjoARgBWmESoOHky65FbxQCU9QN5hluvDwRD%2B/wGI1QeHYIjyAGUAI6SLDEGFaPIicQkEBvS7SdDfHEXZr4yZg/pmORk6a1PDcfiWJpDaEiTq1SEsvJrDZfNKI5GYVEidGY7G4kkCQnizCkyr1W4yxrk%2BFIshYPIgfYYrF5ABU2pI1OolKN9UpqXqrDw9AuR3EciczGqVvo60acPY4nQ7WYXhdOgWIl9rGOYncGVUvG%2BOAgThc7DcCiCflkCjKwX4oSsmAAHhYuPxUnIuOgstZ8DbYrx7Y6mM6K26RB6vT66/7A06Q6JgO4WNHY85XO50yn3AAWDNmCxWQrbRIbEb0MY2dLKMssCu26sOhRthtkd2e71WJh%2BisBsydnChnu7pjfaPWgDC6yoAAV0OxHs9gzh7iAfBETAAHcTH8BQAFZo14ZgINYIM93YZhliwTBdgCMoz1QTsHxwCgQDKCDUmqMcAE4ADYAA4ymo6ovAAdi8ciJxgpgx3gq8kI3RhqhwbC237RAIBQDgHQAUUHBN8EIFMsxAXN80LYtSxsGFUDhSMrC8CdVKaABVehMDfHMr3/IIb0UZRIxwQz%2BGeFlCEpJ92GrEggx8SlBEaTAADksQVdAAIgnAuHYJcoRhZzXPckKwpcFkvKAvySACoKbMwOyIqbVA1VQKKsRi2yniyuEcvQVBEt8/yBDSrRcvytyAJssqKu85LUq8KCbKPVsS3YYB0AsPIFPpDo5Rpahul6ah/lnYplzyRo8jAJg5riedhm2ZdV3oFacGVNadiWlbDo25Jih2lbTVqAA3NVlV5RguQ%2BTZtiNBVgCVJZ%2BgAdXQFxMEEEQIBWgAJDLeHYV4foTXg5DABH72umaBkejUtW5T5tlSJ8sCGMaphR/oxJzFxnIddGygOR7Un5NVBTKX5xuNEQ5AtWp72vWCOMQ%2BS81GosSz4nCYxE9hxMk0sCAgWTp3CBc50O7aMl8NSNLULSdLUgyjJMvd/3TCyIzUdLMoc2NWYamLPLa6rAonULwpZK2msd%2BKYUq9qaonIr7JhUr6pcgqmt9kqWs9u2QB9lqXZ8OryojlLvejegepPXJUEGTb5qaCZmfqMYrnaNlqDmBZlXeHltl2KnFsudBWmL77wRKCCKiu%2BiKjIMgyiIW4AkozAPDKMpqluDwxy8UivA8MhKLHjwiFImxOv7mw5Ho0iqXovYrogvYS/BCEUiylUBSFEUsSJPFJWviV0CNf4TXz2lRsZHKspL81OdYuCcAQ%2BsSFTpK1zjtYWAloxIEwGQB0gUIDRnwsxVIpEILVEwuRJipFKID0IlzNirBsReGqLxABrAuKsB4uA50uFWIBAISAeiARiIQUotgwiARSKTwYvRf%2BnFyz8WoTGISKBcxPH0FJaWaoGBvlEBlOESB2DAQQmeDg3A%2BDMhhDIoCvB5GKOUawVRPB%2BCBRsFwIgZQAhBEMaYdAeh1IKKUb%2BURRBaAMHLM40qzgEK2DVppACWt9KGWMqZJqRsrIm2BLcBw8CcDsC4FlRgTAPCrD2BlLgSA8AULTr%2BLQXitFyIcfoviqEmrAUGlwYM0Fua8N5kwEmYjXB5BzJRciHhmJ5FMUQPIZRUhMICHkCAMiVAmy5KhdCmFvisAEfeSB0DYGECqfgnA2IAj0WQVw%2BizF6LVBYWw8iNTAHlkodMmhzAyg80ORuE50YboCCXDCKOQA%3D%3D
-  - name: Java IDE
-    reference: |
-      g:!((g:!((g:!((h:tree,i:(cmakeArgs:'',compilerLanguageId:java,customOutputFilename:'',files:!((editorId:1,fileId:1,filename:shapes/Square.java,g:'',isIncluded:'0',isMainSource:'1',isOpen:'0',langId:''),(editorId:2,fileId:2,filename:example.java,g:'package+myapp%3B%0A%0Apublic+class+example+%7B%0A%0A%7D',isIncluded:'0',isMainSource:'0',isOpen:'0',langId:java)),isCMakeProject:'1',j:1,newFileId:5),l:'5',n:'0',o:'Tree+%231',t:'0')),header:(),k:29.896907216494846,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:codeEditor,i:(filename:shapes/Square.java,fontScale:14,fontUsePx:'0',j:1,lang:java,selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:'package+shapes%3B%0A%0Apublic+class+Square+%7B%0A++++public+int+square(int+num)+%7B%0A++++++++return+num+*+num%3B%0A++++%7D%0A%7D%0A'),l:'5',n:'0',o:shapes/Square.java,t:'0'),(h:codeEditor,i:(filename:example.java,fontScale:14,fontUsePx:'0',j:2,lang:java,selection:(endColumn:1,endLineNumber:2,positionColumn:1,positionLineNumber:2,selectionStartColumn:1,selectionStartLineNumber:2,startColumn:1,startLineNumber:2),source:'import+shapes.*%3B%0A%0Aclass+Main+%7B%0A++++public+static+void+main(String%5B%5D+args)+%7B%0A++++++++Square+sq+%3D+new+Square()%3B%0A++++++++int+val+%3D+sq.square(args.length)%3B%0A++++++++System.out.println(%22Answer:+%22+%2B+Integer.toString(val))%3B%0A++++%7D%0A%7D'),l:'5',n:'0',o:example.java,t:'0')),k:80.08193737395916,l:'4',m:60.81932773109243,n:'0',o:'',s:1,t:'0'),(g:!((h:executor,i:(argsPanelShown:'0',compilationPanelShown:'1',compiler:java1601,compilerOutShown:'0',execArgs:'hello+world',execStdin:'',fontScale:14,fontUsePx:'0',j:1,lang:java,libs:!(),options:'',source:'1',stdinPanelShown:'1',tree:1,wrap:'1'),l:'5',n:'0',o:'Executor+jdk+16.0.1+(Java,+Tree+%231)',t:'0')),header:(),l:'4',m:39.18067226890757,n:'0',o:'',s:0,t:'0')),k:70.10309278350515,l:'3',n:'0',o:'',t:'0')),l:'2',n:'0',o:'',t:'0')),version:4
-  - name: Ada IDE
-    reference: |
-      z:OYLghAFBqd5QCxAFwE4FN0BoCWIIDGAtgIYDW6AgqsAM4gDkDWBA9kQA44A26qAMiQB2wAK4lg6AJIATECRkkWo2snYB5Ucg5aAYj3RCSRdI2YAzA/VjoZONalkgAjFku8nAJjcGjJkOgAHsYcvAB0CgBGWKBMuLRSQgTcojK2jAAMzDi0ALIkOEIAyqyiqASmDFnx6hyGmczcwsBOTACUWBC29qyOct7u0nIAzD68fqbmrKwRMrQxZvGJyanpVdl5BcWl5ZXOG7X161hNIq0MHV12Dk6jg04ALGOGxpPTs9GxG8spaXLHOXyhRKZQqjH2NTqQgaJ2a50u3RucgAtK57nIAKzPCYgQo6ZBhZCBZALBjOTzDACkGUoFIe1MozgynnpNO%2BSV%2Ba2qgK2IN24IOUIFsLOcgUJDaHRyAGF8hQAAqoVgAK3QBGQwuVLiwQnQAHd9B45AA2DrcRgY5jQ46sRgAFQw6AA1JSKRCNetJVgyC4ABxhB7OB4PACcxoyvoxAHZjc5hsNjSdGA9mEQXBkMjqYba4vRMx6spcYFBixAkGw0gBRa69XD4QY4qYzBTzKZCZBFAgkXguJ5t5AAVVo6HlgRhWu8p1A4qww946pwrGhXSEMmlrBSRGhrkMMn4hXQADlRERInwQN4OKxaPZF0J15vt1grzfkHf97rj6fz9452q30uRTICQqDIA%2BJ5Pn%2BC6AcBoEfkeJ5nqgF6zrBYEbhB2qqCByDwV%2BSEXh0tA7GCDB6vYCBOpQihhHaQTIAA%2BlI6iUsMABCTqcVxXEqM61EkLR9FMSx7EMgyHAkAQZASM6ujTE6OQMpx5iiEkAFCE6uQAJ4MboqkEE6ECUE6IBOokyDoJIqCsRxuimYa6AMXaWl1G0ToYMgZQaeZll8DZDK7k6cmsDZFxJgwlpZjaIBNrM8wFhcHQIOgCjnhAHQ%2BsMzhhMaYZxsanhBr6GaeIm5oMCmWBpp4GJhMyIbBsaDwZFGGLDL6ni%2BlF1Q5sweZYAlRbwGWIAVug1Y9KgdYQA2rwBMEnDhFEbhLh2XY9kGK3tkOI5jscWquFO8iKLO6Dzup%2BC7uBW4gBi3i7nhiHnlGz7XreS7XdCd2va%2B74Hvhz2nedd5AThn23b%2BZ3/iDaGPd%2ByEvdhoHg99SO4f9T0I0RJGVORyCUfxgnEsJNlOrxVE0XRxPMf5NJ45RwWk%2BTjOiTSHBKhUMhlM6lYLaEzqKTSnF2UFBhOS56C05QZ7AIUSlOocGkQLoWBmUIukGKrrqeHiWiEsS2ttFLnHyloDHwYZ2t2slTpCJjTrmEqRBBdMpnay6pWaTpelJIZoxBW0YAMFIpCSEbrOUIFvMhLwoVmhaVrZvNMfoB8A0NF6yWpch6XhZVabxmE0YZMarVMhiDyRhSibWj1iz9YNnSluWrBVjWU14DNvhzbFy39p23amJt/Y7aO44gKMR0zlBF0rmuGE3c4IZYA9GPwy4rgvu994L9uy9b%2BpcMEc4rgzzDYO7y4y9nzBOFH%2BeJ%2BoRfj5X0/cFr8fzjY6CuMURTAlU0YjTdi3FQHk0JoAkmEd6b/zCD5KyTkhLAI4uAmi8C%2BCIOpiJNiYk2aSWkpIJ0kRW5aRdqwBStB5YqTUneL2ul9KGWMqZdB1kQEiwcuLVy7l0CeVQN5dsvlUAUPlpxSgBADLMIEVZEyrEAAiToMjGyIZZOWQsuJ6gQAYQyQhWDIFgZA5iYRKyrgYuocwGteCGV0JKJ03BpgcBEVxAA4jw5WqsxEEHDjgtRnFAp2NYA4iO3EPJeSoh7DiHilGBW0vQpIUtAoszYmFcqkVa7MFtL3GQ0RBpJRSmkHO8cKqphAIGMIwwQwhl9FGX0ldcoxixGkrAvVZwgHzBnDKEMwiRmcMaXpnUoyeEGU1cKwxE7RTiI3OAsBm4gFKNoLQ002CcAMKgQ8c0GCBF9MaZETUnTACMHo8kYRPAWFWgPDafZVqjz2tUA6A1HQ4DkK4PUqASAcAFIU1JScGCaHmXo1g5gnSbO2bs/ZJBDmeGOYZdcyzeBCNdFlNozAcnegvCGIuWUKTlIxLGDI5Swx52KYMspUYQylRDAMkMGQQzDAyA075fVWnp09E3YaLdYV8EWewLgcKQBguQOSbwaQABuOAKgADUcD6kVsKdwFlUD0AgJEGEkRCggS0sKJZJh2zqCENwDVxw0ikBED2Q1OAMALmFegegxwghqi0JUbkAjyrVG4DgSIrzUBaXXGkGEaAcBpjJGFcwTQ6CSulUKINW01qD17NG6549DrNGOkoN1kRrC5wCepG1fUobQWXFdS%2BO5Vz32QpvN66lwblt%2BkuUtWE83qVBsjItQNoa33fp%2BTGWE0JVrfujTt68v73MwC4T5Yy64MCBVsnZDw9kHKdEczwhkHSYA9oi5F7SsBZ3yfgQp%2BcQBRijDlTwLVaWeCjNSkuIZ6XjMZW0z0HTOphCjPGX0wwYznoyD05kIzx3pMWCi8qJzur/omZuq1Cq7wlKAA%3D
-  - name: Android Java IDE
-    reference: |
-      z:OYLghAFBqd5QCxAFwE4FN0BoCWIIDGAtgIYDW6AgqsAM4gDkAtACIDCAspQNICiA%2BgCEAqgEkAMi34AVAJoAFXgFIAzCxboARgFdgDLAQD2RAA44ANulTiSAO2DaSwdKIAmIO69SGcrpgCsSADcSA21aZGMAeW1kE1iAMQt0WxIidEZ9ADNk%2Blh0VxxI1DcQAEYsHMtSiqqUtIyTbzqAOibDLJbkAA9kLFAGfRxaUVsCc21XAsYyodoOEhxbAGVDbVQCDIZZ3FookxTGAAZ9cztgUsGASiwIAqLDEvcAJkrk0te61PSQdG60kyWFqBEL9TK7UbjSbTBgnXYLJardabY5zfaHWGnc6XBg3O6FYqlFRvaruAAsJPqP3aDhIqFcLQIWWAYMGELGEym7m2cwRKzWGy2O2G6NsqKwZ3sOKuN2GnHI6Hk3n86AIyBm%2Bn85SwtnQAHckqSQABWG7mRjG/RizFYQyMaQYdAAaiUzxUO3VmJlWAQ6BIU1Q%2BBuZBAzyOLQAbFGVM8I0cI2SybHjSpjRLGGSreK7Wz6EcsJ6TniYIgQEYprwCY9cPgvg0QO1Wo2ur1KoZbMhlgQSJZyhSsu3kMJaIruuKtRVJaBPN5fAFgqER5Y1Th2/gUq42IYJkQxRUN%2BIlugAHLaIiaKwgCkmQy0Iqr2xbnd7rA3u/IB%2BH3Wn8%2BXilL1UP3bZZkDpZAnzPF8AJXYDQNQZAvxPM8L0Df84PA7dIO1CIwMQn8UKvG5aAFFEGAACWWeRxGWABHRwMFUQQmFUZQVDYJYihYiArgANSUI5KAoqjaPo9BGOYlReFoOi6XQCBRCuUR%2BMoaiZIYlRBGU3F0wYS0dWzBtmmSNpmhbPpC20iAkHLdBKweVAawgOtqW8Wl6UZZk2w7LsewyMp%2B0HYdR3HEBiSnDxbC8Hw/BBRd0GXICxTuSKIN3ULiQPI98MvCo33vdtUrFFRiTyxK8OQnKsGgxKQLAwr0qq%2BLAIfWr4PK39AwqHD4Pq4qqvQ9qCLKIiSK2JgKHQEwnXGEhaFoJ0RNkl0AHZBCdeJNHMHACCdAAqRiVpYbTzV0rMbTtGl6IZJkWQsvFrMMCsqwcvAnOSb4Mj%2BAEgVirzO27Xt/L%2BoL5DHG0tVecKZ2i%2BdQWqh91xSzC0teTLvwqzrltfW98sfZGxVeUrPyyjHyix%2BHYLq/HQ0ahKWoGkmOrJ/qqefGnuoQxmhuWkbkS2AB6fmnWkABPA4nRFgVpse51fQwLAnUeJ1zEMf0nTsJ0vtMIFlMF3WhambpnlV5B1qMywmAcXwCml0wLBIRKQH1p1KFcVwXWeZ5G2M5semQV1nidSIPeeSFORtupaAD9XIumraCDIIPfSdDAsgwWgECdHRkEiWx1f9gTBaT51NEMHPjEVrJi9tsxLFQRXYniU2TDseKWidBIleQZPvcsJ0B1QUg%2BidEcxMLoWEBzkx6EFqYgniwwDlQFpod8RljH5yIzAIfml4H0gxnQfnNFm%2BKj179BaH5g/HHMcwRaYAgMAd9AmHSWb1jEt0phyXUmFQbQlhaBvzsLfe%2B%2BtnYACUAAcTolSGAAOJXSdBNKaAC%2B5LCbk7ceLs3Yh0unSa6zJo7BwDmHaE7tI7R08HHbaidu7OlTunTO2dc752rs7Uu5ciCV2rkYO2dcG5xFiOtVu5h26d3rvApBhCnThCcNgEemBnaTziDPfmepNEtDcq4aSol15EGvqAns/MjC2ByA4VADsHz83kc4ZSykZpzQWmpZ0ShVrKSdF49a2hNrbRHqBD8O0limz0bJCAISnS2DPFcFamkBLeMSSndAyB1h52iTw3aUSzyMU8d49xLAHHLUKQJY6Fozo7DtFrQE6BgQLgLKib0IZEwtCOAATjKG0540DirPDaSoeMQMTqZn0udcE9BXh3VuCWKyZZjC1ysI5fhCzAyxSYIbY2DsmBnGQJfPoVRdmoHoBATQ4pNBLDpCLDUWBzmpFQCLKImgVRqmufw9IHYoi2HvuKKYOhgBsB7OYegPIsBTAPsAXsNpCgYBXPPYFcI/iqliEKIYHZ4rii2poKx9ytxTHFGgHARBrnz1QKXEcGhwVbXsI0yoZw6A8RwPqUU1yBzeQBn5AKHYQZgzhBDCU5wIpRTnL9TFeQoAfUFbOPwJAzBMAiL42gWASUzDKFGN00CIyWQlagaB41MAt1sLYQwSrLwMB6SoZauIbiL0SsC/QhgSWoGtmKoiTUYJJQ3PVfckVBqVSJgVamuUcZlS5pVCmKx0Jetps1SmbVQ2dRZj1QNibOboyZsNAsjpyhmnKaMuEOYXaQOkE6DZJtlYvwiE6CADpMAe3dFcfQd1gyhWNC0Z4ZIyjLTJMaOMsYkwap0iM60%2BbxkgHzE2nSzwzojrZBOkld41xkiAA%3D%3D%3D
-  - name: Android Kotlin IDE
-    reference: |
-      z:OYLghAFBqd5QCxAFwE4FN0BoCWIIDGAtgIYDW6AgqsAM4gDkAtACIDCAspQNICiA%2BgCEAqgEkAMi34AVAJoAFXgFIAzCxboARgFdgDLAQD2RAA44ANulTiSAO2DaSwdKIAmIO69SGcrpmUNkcxxbA21aZGMAeW1kE1iAMQt0WxIidEZ9ADNk%2Blh0VxxI1DcQAEYsHMtSiqqUtIyTbzqAOibDLJbkAA9kLFAGfRxaUVsCc21XAsYyodoOEhCAZUNtVAIMhlncWiiTFMYABn1zO2BSwYBKLAgCosMS9wAmSuTSl7rU9JB0brSTSwtMh9AZzUbjSbTBjHHYLZardabGHDPYHaEnM4XBjXW6FYqlFSvaruAAsRPq33aDhIqFcLQIWWA/UyO3BEym7i2czhthWaw2MzmqNsRwx9ixl2uw045HQ8m8ACt0ARkIKsArylhbOgAO5JYkgACs13MjEN%2BhF6KwhkY0gw6AA1Eoniptqr0ZKsAh0CQpqh8NcyCAnmUWgA2Q6G11lEkklRxmMATiwpoYJItoutLPohyw7uOOJgiBARimvDxD1w%2BE%2BDRA7Va9a6vUqhlsyCWBBIlnKZKyreQwlocu6mY1FVO9g8ti8Pj8ASCISwQ8sKpwrfwKVcbEMEyIIuTm/EIXQADltERNFYQISTIZaEU17Zt7v91hb/fkI%2Bj9qzxer4Tl2VT9WyWZAaWQZ9z1fQDVxAsDUGQb9T3PS9/QA%2BCIJ3KCQGTCJwKQ39UOva5aARAUGAACSWeRxCWABHRwMFUQQmFUZQVDYEIijYiBLgANSUQ5KComj6MY9BmNYlReFoBiaXQCBREuURBMoWi5KYlRBGxFMzQzLks3rZI2maJs%2BnzHSICQUt0HLe5UCrCAa0pbxqVpelGRbNsOy7DIYy8gch3kEcrQ1QkJ1ATxvF8fxAmCUIYOAkVbmnSC901Q9j0Iq8KnfB9WzSkVcrvfLbAIlCcqXdAVyS0DwMKzVEsfOqEPKv9/QqPCEIazqMLaoiyhIsjNn8TATAdcYSFoWgHTE%2BSnQAdkEB14k0YICAdAAqZjFpYHTU3NLVMxtKlGLpBkmQsnFrMMMsKwcvAnOSL4Ml%2Bf5AWBAKfO7fy%2BzbQdh1HYMUzOKcZxi%2Bd4qqmrHw3VKsPSipMp/CqOrDN8SqSnqMY/L8stR8p0aauD6oRoroaA5q%2Bvx9rCaXDDsa6xCaYGsMhv5TYAHpOYdaQAE99gdPmEQm27HW9DAsAdB4HXMQxfQdOwHTe0xAVU7n1Z5qZuieeXkBW5pkiYBxfAKUXTAsEgkpATWHUoVxXCdJ4niMwFGx6ZBnSeB1Iidp42UhR26loL3FenCb1rIH3vQdDAsgwWgEAdHRkEiWxFc9oTuejx1NECSIiGlrIc/NsxLFQaXYnifWTDsaqWgdBIZeQGPXcdPtUFIPoHSHCSs55hBU5MehuamAA3arDH2VAWii2d6WMTnIjMAhOenjvSDGdBOc0KbquPNvaE5zfHHMcw%2BaYAgMCt9AmHSKa1gkl0phybUmFQbRLFoO%2B7FP8/NdtgAJQABwOnlIYAA4mdB0FB0DjQ/pYB0IRq4237nbB2ftTo0nOoyUOvsvYBw5A6YOodPARxwAQKOLdHRxwTknFOacM4l1tnnVOxgi4lyMBbculc4ixBWnXcwDcm4V3AVA7BDpwhOGwD3TAttB5xBHpzHUKiWhuVcLJcSC8iDH1/l2TmRhbA5AcKgK2j5OZSOcKpVSq11oRymjNOaGBFqCFUg6dxxDtDp00fJCAthzwgAdKMZAlxAnBKdGoB0/jC6bSieeaxC0WCqX2npI6VobQqwBOgIE5lRSeiDCSBaLRYyGhJE8Q4C0FokhjGUKpuk0z6RhDaQYS5gZXRuEWKyJZjBlysI5LhvT/SQxCEwbWusrZMFOMgdAEQiTTNQPQCAmhMyaBCDSPmapVmpFQHzKImglQqjVFw9IbYoi2HPpmKYOhgBsC7OYegBkpib2AN2K0hQMCrgng8mEvxlSxE2NsEI0zUwwmCJoUxOztxTEzGgHARA1QT1QHnIcGhnnxQGAWSopw6B8RwLqYUao/rtk7D9Xs/YAbBSBi8CKYNopzjiouMFeQoAvVpbOJgJAzBMAiNoTQtAsCIpmGUMMYYXTALDJZVlqBgGjTgXYWwhgBVXgYMAlQKgFrYmuFPJKDz9CGERagU2zKSLVUpuuFKW4yYZWnP1SqeUsZWuKrjVstqOoU1gryBmjr3W1WpijWmvVSYvkan65CAbrhoEwOUE0qTLRNMYHbQB0gHRjL1rLG%2BEQHQQDtJgJ2rpLj6CuoGa8hwWiJhJImJ4YZKnAKeGU6twD6npjSfGlpOY8x5JjQwJ4jS9UsiLUqhZsMSRAA%3D
diff --git a/etc/config/slang.amazon.properties b/etc/config/slang.amazon.properties
deleted file mode 100644
index 7a25d2d13..000000000
--- a/etc/config/slang.amazon.properties
+++ /dev/null
@@ -1,13 +0,0 @@
-compilers=&defaultslangc
-
-defaultCompiler=slangc_2024_14_6
-supportsBinary=false
-compilerType=slang
-instructionSet=spirv
-
-disassemblerPath=/opt/compiler-explorer/SPIRV-Tools-master/build/tools/spirv-dis
-
-group.defaultslangc.compilers=slangc_2024_14_6
-group.defaultslangc.versionFlag=-version
-compiler.slangc_2024_14_6.exe=/opt/compiler-explorer/slang-2024.14.6/bin/slangc
-compiler.slangc_2024_14_6.name=slangc 2024.14.6
diff --git a/etc/config/slang.defaults.properties b/etc/config/slang.defaults.properties
deleted file mode 100644
index 6383fa90f..000000000
--- a/etc/config/slang.defaults.properties
+++ /dev/null
@@ -1,13 +0,0 @@
-compilers=&defaultslangc
-
-defaultCompiler=slangc_2024_14_6
-supportsBinary=false
-compilerType=slang
-instructionSet=spirv
-
-disassemblerPath=/opt/compiler-explorer/SPIRV-Tools-master/build/tools/spirv-dis
-
-group.defaultslangc.compilers=slangc_2024_14_6
-group.defaultslangc.versionFlag=-version
-compiler.slangc_2024_14_6.exe=/usr/bin/slangc
-compiler.slangc_2024_14_6.name=slangc 2024.14.6
diff --git a/etc/config/spirv.amazon.properties b/etc/config/spirv.amazon.properties
index 6b3b003d6..e5280d8d8 100644
--- a/etc/config/spirv.amazon.properties
+++ b/etc/config/spirv.amazon.properties
@@ -1,4 +1,4 @@
-compilers=&spirv-opt:&spirv-val:&spirv-cross
+compilers=&spirv-opt:&spirv-val
 defaultCompiler=spirv-opt-master
 
 supportsBinary=false
@@ -15,17 +15,9 @@ group.spirv-val.baseName=SPIRV-Tools Validator
 group.spirv-val.compilers=spirv-val-master
 group.spirv-val.compilerType=spirv-tools
 
-group.spirv-cross.groupName=Translate
-group.spirv-cross.baseName=SPIRV-Cross
-group.spirv-cross.compilers=spirv-cross-sdk-296
-group.spirv-cross.compilerType=spirv-tools
-
 assemblerPath=/opt/compiler-explorer/SPIRV-Tools-master/build/tools/spirv-as
 disassemblerPath=/opt/compiler-explorer/SPIRV-Tools-master/build/tools/spirv-dis
 compiler.spirv-opt-master.exe=/opt/compiler-explorer/SPIRV-Tools-master/build/tools/spirv-opt
 compiler.spirv-opt-master.name=spirv-opt (trunk)
 compiler.spirv-val-master.exe=/opt/compiler-explorer/SPIRV-Tools-master/build/tools/spirv-val
 compiler.spirv-val-master.name=spirv-val (trunk)
-
-compiler.spirv-cross-sdk-296.exe=/opt/compiler-explorer/vulkan-sdk/v1.3.296.0/x86_64/bin/spirv-cross
-compiler.spirv-cross-sdk-296.name=spirv-cross (sdk-296)
diff --git a/etc/config/sponsors.yaml b/etc/config/sponsors.yaml
index fdcc0ded0..7f0c6242b 100644
--- a/etc/config/sponsors.yaml
+++ b/etc/config/sponsors.yaml
@@ -12,15 +12,6 @@ levels:
         priority: 100
         topIconShowEvery: 3
         statsId: solid_sands
-      - name: Intel
-        description: We engineer solutions for our customers’ greatest challenges with reliable, cloud to edge computing, inspired by Moore’s Law.
-        icon: https://static.ce-cdn.net/intel/logo-classicblue-3000px-single-colour.png
-        img: https://static.ce-cdn.net/intel/logo-classicblue-3000px.png
-        url: https://intel.com/
-        priority: 400
-        topIconShowEvery: 1
-        displayType: SideBySide
-        statsId: intel
       - name: Google
         description: Google’s mission is to organize the world's information and make it universally accessible and useful.
         img: https://static.ce-cdn.net/google/logo_Google_FullColor_xxxhdpi_830x271px.png
diff --git a/etc/scripts/build-dist-win.ps1 b/etc/scripts/build-dist-win.ps1
index c4dc2aa2f..dccb15a7f 100644
--- a/etc/scripts/build-dist-win.ps1
+++ b/etc/scripts/build-dist-win.ps1
@@ -70,7 +70,7 @@ Add-Content -Path $env:GITHUB_OUTPUT -Value "branch=$BRANCH"
 Add-Content -Path $env:GITHUB_OUTPUT -Value "release_name=$RELEASE_NAME"
 
 # Run to make sure we haven't just made something that won't work
-node --import=tsx --no-warnings=ExperimentalWarning ./app.js --version --dist
+node --no-warnings=ExperimentalWarning --loader ts-node/esm ./app.js --version --dist
 if ($LASTEXITCODE -ne 0) {
    throw "node exited with error $LASTEXITCODE"
 }
diff --git a/etc/scripts/build-dist.sh b/etc/scripts/build-dist.sh
index 0b27ca9e8..ae21a4fe4 100755
--- a/etc/scripts/build-dist.sh
+++ b/etc/scripts/build-dist.sh
@@ -47,7 +47,7 @@ echo "branch=${GITHUB_REF#refs/heads/}" >> "${GITHUB_OUTPUT}"
 echo "release_name=${RELEASE_NAME}" >> "${GITHUB_OUTPUT}"
 
 # Run to make sure we haven't just made something that won't work
-node --no-warnings=ExperimentalWarning --import=tsx ./app.js --version --dist
+node --no-warnings=ExperimentalWarning --loader ts-node/esm ./app.js --version --dist
 
 rm -rf "${ROOT}/out/dist-bin"
 mkdir -p "${ROOT}/out/dist-bin"
diff --git a/etc/scripts/docenizers/docenizer-java.sh b/etc/scripts/docenizers/docenizer-java.sh
index 6fcb489bd..0cb16fc93 100755
--- a/etc/scripts/docenizers/docenizer-java.sh
+++ b/etc/scripts/docenizers/docenizer-java.sh
@@ -4,4 +4,4 @@ JVMS_PATH=$(pwd)/vendor/jvms.html
 
 [ -f "$JVMS_PATH" ] || curl https://docs.oracle.com/javase/specs/jvms/se18/html/jvms-6.html -o "$JVMS_PATH"
 
-npx node --no-warnings=ExperimentalWarning --import=tsx docenizer-java.ts > ../../../lib/asm-docs/generated/asm-docs-java.ts
+npx node --no-warnings=ExperimentalWarning --loader ts-node/esm docenizer-java.ts > ../../../lib/asm-docs/generated/asm-docs-java.ts
diff --git a/etc/scripts/docenizers/docenizer-llvm.sh b/etc/scripts/docenizers/docenizer-llvm.sh
index 2f13b1721..aec89c6e8 100755
--- a/etc/scripts/docenizers/docenizer-llvm.sh
+++ b/etc/scripts/docenizers/docenizer-llvm.sh
@@ -4,4 +4,4 @@ LANGREF_PATH=$(pwd)/vendor/LangRef.html
 
 [ -f "$LANGREF_PATH" ] || curl https://llvm.org/docs/LangRef.html -o "$LANGREF_PATH"
 
-npx node --no-warnings=ExperimentalWarning --import=tsx docenizer-llvm.ts > ../../../lib/asm-docs/generated/asm-docs-llvm.ts
+npx node --no-warnings=ExperimentalWarning --loader ts-node/esm docenizer-llvm.ts > ../../../lib/asm-docs/generated/asm-docs-llvm.ts
diff --git a/etc/scripts/generate_site_template_screenshots.ts b/etc/scripts/generate_site_template_screenshots.ts
index 96f6c0ba2..053ace821 100644
--- a/etc/scripts/generate_site_template_screenshots.ts
+++ b/etc/scripts/generate_site_template_screenshots.ts
@@ -22,40 +22,42 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 // POSSIBILITY OF SUCH DAMAGE.
 
-// This is a script for generating screenshots for the site templates configured in etc/config/site-templates.yaml
-//
-// It should be run in the etc/scripts/ directory, because it uses relative paths
-// It requires puppeteer which is not installed by default. You can install it locally with:
-//   `npm i --no-save puppeteer`
-// Run with `node --import=tsx generate_site_template_screenshots.ts`
+/*
+ * Note:
+ * - This script should be run in the etc/scripts/ directory, it uses relative paths
+ * - This script requires puppeteer which is not installed by default (I install it globally)
+ * - Run with npx ts-node-esm generate_site_template_screenshots.ts
+ */
 
-import * as fsp from 'node:fs/promises';
-import * as fss from 'node:fs';
+import * as puppeteer from "puppeteer";
+import * as fs from "fs";
 
-import * as puppeteer from 'puppeteer';
-import * as yaml from 'yaml';
+const godbolt    = "https://godbolt.org";
+const output_dir = "../../views/resources/template_screenshots";
+const config     = "../config/site-templates.conf";
 
-const godbolt = 'https://godbolt.org';
-const output_dir = '../../views/resources/template_screenshots';
-const config = '../config/site-templates.yaml';
+const defaultViewport = {
+    width: 500,
+    height: 500
+};
 
 // Note: Hardcoded, may need to be updated in the future
 // array of pairs [theme, colourScheme]
 const themes = [
-    ['default', 'rainbow'],
-    ['dark', 'gray-shade'],
-    ['darkplus', 'gray-shade'],
-    ['pink', 'pink'],
-    ['real-dark', 'gray-shade'],
-    ['onedark', 'gray-shade'],
+    ["default",   "rainbow"],
+    ["dark",      "gray-shade"],
+    ["darkplus",  "gray-shade"],
+    ["pink",      "pink"],
+    ["real-dark", "gray-shade"],
+    ["onedark",   "gray-shade"],
 ];
 
 const defaultSettings = {
     showMinimap: true,
     wordWrap: false,
-    colourScheme: 'gray-shade',
-    theme: 'dark',
-    defaultFontScale: 14,
+    colourScheme: "gray-shade",
+    theme: "dark",
+    defaultFontScale: 14
 };
 
 // utilities
@@ -63,13 +65,28 @@ function sleep(ms: number) {
     return new Promise(resolve => setTimeout(resolve, ms));
 }
 
-async function promisePoolExecutor(jobs: (() => void)[], max_concurrency: number) {
+function splitProperty(line: string) {
+    return [line.substring(0, line.indexOf('=')), line.substring(line.indexOf('=') + 1)];
+}
+
+function partition<T>(array: T[], filter: (x: T) => boolean) {
+    const pass: T[] = [], fail: T[] = [];
+    for(const item of array) {
+        if(filter(item)) {
+            pass.push(item);
+        } else {
+            fail.push(item);
+        }
+    }
+    return [pass, fail];
+}
+
+async function PromisePoolExecutor(jobs: (() => void)[], max_concurrency: number) {
     async function worker(iterator: IterableIterator<[number, () => void]>) {
-        for (const [_, job] of iterator) {
+        for(const [_, job] of iterator) {
             await job();
         }
     }
-
     const iterator = jobs.entries();
     const workers = new Array(max_concurrency).fill(iterator).map(worker);
     await Promise.allSettled(workers);
@@ -77,18 +94,15 @@ async function promisePoolExecutor(jobs: (() => void)[], max_concurrency: number
 
 // end utils
 
-async function generateScreenshot(url: string, output_path: string, settings, width: number, height: number) {
+async function generate_screenshot(url: string, output_path: string, settings) {
     const browser = await puppeteer.launch({
         dumpio: true,
-        defaultViewport: {
-            width,
-            height,
-        },
+        defaultViewport
     });
     const page = await browser.newPage();
     await page.goto(godbolt);
     await page.evaluate(settings => {
-        localStorage.setItem('settings', JSON.stringify(settings));
+        localStorage.setItem("settings", JSON.stringify(settings));
     }, settings);
     await page.goto(url);
     //await sleep(2000);
@@ -96,44 +110,55 @@ async function generateScreenshot(url: string, output_path: string, settings, wi
     //await sleep(5000);
     //await page.click("#simplecook .btn.btn-primary.btn-sm.cook-do-consent");
     await page.evaluate(() => {
-        for (let element of document.querySelectorAll('.float-link.link')) {
+        for(let element of document.querySelectorAll(".float-link.link")){
             element.parentNode!.removeChild(element);
         }
     });
     await sleep(10000); // wait for things to settle
-    await page.screenshot({path: output_path});
+    await page.screenshot({ path: output_path });
 
     await browser.close();
 }
 
-const {meta, templates} = yaml.parse(await fsp.readFile(config, 'utf-8'));
-const names = templates.map((template) => template.name);
-
-// Quickly check there are no name conflicts
-if (names.length !== new Set(names).size) {
-    console.log('Error: Conflicting cleaned names');
-    process.exit(1);
-}
-const width = parseInt(meta.screenshot_dimensions.width);
-const height = parseInt(meta.screenshot_dimensions.height);
-
-if (!fss.existsSync(output_dir)) {
-    await fsp.mkdir(output_dir, {recursive: true});
-}
-const jobs: (() => void)[] = [];
-for (const {name, reference} of templates) {
-    for (const [theme, colourScheme] of themes) {
-        const path = `${output_dir}/${name}.${theme}.png`;
-        if (!fss.existsSync(path)) {
-            jobs.push(() => generateScreenshot(
-                `${godbolt}/e#${reference}`,
-                path,
-                Object.assign(Object.assign({}, defaultSettings), {theme, colourScheme}),
-                width,
-                height,
-            ));
+(async () => {
+    const [meta_directives, templates] =
+        partition(
+            fs
+            .readFileSync(config, "utf-8")
+            .split("\n")
+            .filter(l => l !== "")
+            .map(splitProperty)
+            .map(pair => [pair[0], pair[1].replace(/^https:\/\/godbolt.org\/#/, "")])
+            .map(([name, data]) => [!name.startsWith("meta.") ? name.replaceAll(/[^a-z]/gi, "") : name, data]),
+            ([name, _]) => name.startsWith("meta.")
+        );
+    if(new Set(templates.map(([line, _]) => line)).size !== templates.length) { // quickly check there are no name conflicts
+        console.log("Error: Conflicting cleaned names");
+        process.exit(1);
+    }
+    for(const [k, v] of meta_directives) {
+        if(k === "meta.screenshot_dimensions") {
+            const [w, h] = v.split("x").map(x => parseInt(x));
+            defaultViewport.width = w;
+            defaultViewport.height = h;
         }
     }
-}
-// don't launch too many chrome instances concurrently
-await promisePoolExecutor(jobs, 4);
+    if(!fs.existsSync(output_dir)) {
+        fs.mkdirSync(output_dir, { recursive: true });
+    }
+    const jobs: (() => void)[] = [];
+    for(const [name, data] of templates) {
+        for(const [theme, colourScheme] of themes) {
+            const path = `${output_dir}/${name}.${theme}.png`;
+            if(!fs.existsSync(path)) {
+                jobs.push(() => generate_screenshot(
+                    `${godbolt}/e#${data}`,
+                    path,
+                    Object.assign(Object.assign({}, defaultSettings), {theme, colourScheme})
+                ));
+            }
+        }
+    }
+    // don't launch too many chrome instances concurrently
+    await PromisePoolExecutor(jobs, 4);
+})();
diff --git a/examples/odin/default.odin b/examples/odin/default.odin
deleted file mode 100644
index 3706a9487..000000000
--- a/examples/odin/default.odin
+++ /dev/null
@@ -1,7 +0,0 @@
-package main
-
-import "core:fmt"
-
-main :: proc() {
-    fmt.println("Hello")
-}
diff --git a/examples/slang/default.slang b/examples/slang/default.slang
deleted file mode 100644
index 640ac6b5a..000000000
--- a/examples/slang/default.slang
+++ /dev/null
@@ -1,12 +0,0 @@
-// Default target is 'spirv' but need to add entry for other targets
-StructuredBuffer<float> buffer0;
-StructuredBuffer<float> buffer1;
-RWStructuredBuffer<float> result;
-
-[shader("compute")]
-[numthreads(1,1,1)]
-void computeMain(uint3 threadId : SV_DispatchThreadID)
-{
-    uint index = threadId.x;
-    result[index] = buffer0[index] + buffer1[index];
-}
\ No newline at end of file
diff --git a/lib/base-compiler.ts b/lib/base-compiler.ts
index 4381c6f77..7c9623169 100644
--- a/lib/base-compiler.ts
+++ b/lib/base-compiler.ts
@@ -30,7 +30,7 @@ import * as PromClient from 'prom-client';
 import temp from 'temp';
 import _ from 'underscore';
 
-import {splitArguments, unique} from '../shared/common-utils.js';
+import {unique} from '../shared/common-utils.js';
 import {OptRemark} from '../static/panes/opt-view.interfaces.js';
 import {PPOptions} from '../static/panes/pp-view.interfaces.js';
 import {ParsedAsmResultLine} from '../types/asmresult/asmresult.interfaces.js';
@@ -1173,7 +1173,7 @@ export class BaseCompiler {
         options = options.concat(this.optionsForBackend(backendOptions, outputFilename));
 
         if (this.compiler.options) {
-            options = options.concat(splitArguments(this.compiler.options));
+            options = options.concat(utils.splitArguments(this.compiler.options));
         }
 
         if (this.compiler.supportsOptOutput && backendOptions.produceOptInfo) {
@@ -2555,7 +2555,7 @@ export class BaseCompiler {
 
         const options: string[] = [];
         if (this.compiler.options) {
-            const compilerOptions = splitArguments(this.compiler.options);
+            const compilerOptions = utils.splitArguments(this.compiler.options);
             options.push(...removeToolchainArg(compilerOptions));
         }
         options.push(...libsAndOptions.options, ...libIncludes);
@@ -2599,13 +2599,13 @@ export class BaseCompiler {
 
     getUsedEnvironmentVariableFlags(makeExecParams: ExecutionOptionsWithEnv) {
         if (this.lang.id === 'c++') {
-            return splitArguments(makeExecParams.env.CXXFLAGS);
+            return utils.splitArguments(makeExecParams.env.CXXFLAGS);
         } else if (this.lang.id === 'fortran') {
-            return splitArguments(makeExecParams.env.FFLAGS);
+            return utils.splitArguments(makeExecParams.env.FFLAGS);
         } else if (this.lang.id === 'cuda') {
-            return splitArguments(makeExecParams.env.CUDAFLAGS);
+            return utils.splitArguments(makeExecParams.env.CUDAFLAGS);
         } else {
-            return splitArguments(makeExecParams.env.CFLAGS);
+            return utils.splitArguments(makeExecParams.env.CFLAGS);
         }
     }
 
@@ -2694,7 +2694,7 @@ export class BaseCompiler {
 
             const toolchainparam = this.getCMakeExtToolchainParam(parsedRequest.backendOptions.overrides || []);
 
-            const cmakeArgs = splitArguments(parsedRequest.backendOptions.cmakeArgs);
+            const cmakeArgs = utils.splitArguments(parsedRequest.backendOptions.cmakeArgs);
             const partArgs: string[] = [
                 toolchainparam,
                 ...this.getExtraCMakeArgs(parsedRequest),
@@ -3546,7 +3546,7 @@ but nothing was dumped. Possible causes are:
             });
         }
 
-        const compilerOptions = splitArguments(this.compiler.options);
+        const compilerOptions = utils.splitArguments(this.compiler.options);
         if (hasToolchainArg(compilerOptions)) {
             const possibleToolchains: CompilerOverrideOptions = await this.getPossibleToolchains();
 
diff --git a/lib/buildenvsetup/base.ts b/lib/buildenvsetup/base.ts
index 06e9676ab..0667ea272 100644
--- a/lib/buildenvsetup/base.ts
+++ b/lib/buildenvsetup/base.ts
@@ -26,7 +26,6 @@ import path from 'path';
 
 import _ from 'underscore';
 
-import {splitArguments} from '../../shared/common-utils.js';
 import {Arch, CacheKey, ExecutionOptionsWithEnv} from '../../types/compilation/compilation.interfaces.js';
 import {CompilerInfo} from '../../types/compiler.interfaces.js';
 import {UnprocessedExecResult} from '../../types/execution/execution.interfaces.js';
@@ -56,7 +55,7 @@ export class BuildEnvSetupBase {
         this.compiler = compilerInfo;
         this.env = env;
 
-        this.compilerOptionsArr = splitArguments(this.compiler.options);
+        this.compilerOptionsArr = utils.splitArguments(this.compiler.options);
         this.compilerArch = this.getCompilerArch();
         this.compilerTypeOrGCC = compilerInfo.compilerType || 'gcc';
         if (this.compilerTypeOrGCC === 'clang-intel') this.compilerTypeOrGCC = 'gcc';
diff --git a/lib/compilers/_all.ts b/lib/compilers/_all.ts
index 90d2ff31d..ba167e568 100644
--- a/lib/compilers/_all.ts
+++ b/lib/compilers/_all.ts
@@ -108,7 +108,6 @@ export {NvccCompiler} from './nvcc.js';
 export {NvrtcCompiler} from './nvrtc.js';
 export {NvcppCompiler} from './nvcpp.js';
 export {OCamlCompiler} from './ocaml.js';
-export {OdinCompiler} from './odin.js';
 export {OptCompiler} from './opt.js';
 export {OSACATool} from './osaca.js';
 export {PascalWinCompiler} from './pascal-win.js';
@@ -125,7 +124,6 @@ export {RustcCgGCCCompiler} from './rustc-cg-gcc.js';
 export {RustCompiler} from './rust.js';
 export {ScalaCompiler} from './scala.js';
 export {SdccCompiler} from './sdcc.js';
-export {SlangCompiler} from './slang.js';
 export {SolidityCompiler} from './solidity.js';
 export {SolidityZKsyncCompiler} from './solidity-zksync.js';
 export {SpiceCompiler} from './spice.js';
diff --git a/lib/compilers/ada.ts b/lib/compilers/ada.ts
index 8a45bd7e6..5b3c2229f 100644
--- a/lib/compilers/ada.ts
+++ b/lib/compilers/ada.ts
@@ -25,7 +25,6 @@
 
 import path from 'path';
 
-import {splitArguments} from '../../shared/common-utils.js';
 import type {ConfiguredOverrides} from '../../types/compilation/compiler-overrides.interfaces.js';
 import type {PreliminaryCompilerInfo} from '../../types/compiler.interfaces.js';
 import type {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces.js';
@@ -33,6 +32,7 @@ import {SelectedLibraryVersion} from '../../types/libraries/libraries.interfaces
 import {unwrap} from '../assert.js';
 import {BaseCompiler} from '../base-compiler.js';
 import {CompilationEnvironment} from '../compilation-env.js';
+import * as utils from '../utils.js';
 
 export class AdaCompiler extends BaseCompiler {
     static get key() {
@@ -170,7 +170,7 @@ export class AdaCompiler extends BaseCompiler {
         // in the correct list.
 
         let part = 0; // 0: gnatmake, 1: compiler, 2: linker, 3: binder
-        for (const a of backend_opts.concat(splitArguments(this.compiler.options), userOptions)) {
+        for (const a of backend_opts.concat(utils.splitArguments(this.compiler.options), userOptions)) {
             if (a === '-cargs') {
                 part = 1;
                 continue;
diff --git a/lib/compilers/argument-parsers.ts b/lib/compilers/argument-parsers.ts
index 016a8ce38..e6b55297b 100644
--- a/lib/compilers/argument-parsers.ts
+++ b/lib/compilers/argument-parsers.ts
@@ -29,7 +29,6 @@ import * as Sentry from '@sentry/node';
 import fs from 'fs-extra';
 import _ from 'underscore';
 
-import {splitArguments} from '../../shared/common-utils.js';
 import {CompilerOverrideOptions} from '../../types/compilation/compiler-overrides.interfaces.js';
 import {Argument} from '../../types/compiler-arguments.interfaces.js';
 import {BaseCompiler} from '../base-compiler.js';
@@ -1196,7 +1195,7 @@ export class GolangParser extends GCCParser {
     static override async getOptions(compiler: BaseCompiler, helpArg: string) {
         const optionFinder1 = /^\s*(--?[\d#+,<=>[\]a-z|-]* ?[\d+,<=>[\]a-z|-]*)\s+(.*)/i;
         const optionFinder2 = /^\s*(--?[\d#+,<=>[\]a-z|-]* ?[\d+,<=>[\]a-z|-]*)/i;
-        const result = await compiler.execCompilerCached(compiler.compiler.exe, splitArguments(helpArg), {
+        const result = await compiler.execCompilerCached(compiler.compiler.exe, utils.splitArguments(helpArg), {
             ...compiler.getDefaultExecOptions(),
             createAndUseTempDir: true,
         });
diff --git a/lib/compilers/dart.ts b/lib/compilers/dart.ts
index 8224f5f58..73075bc57 100644
--- a/lib/compilers/dart.ts
+++ b/lib/compilers/dart.ts
@@ -26,7 +26,6 @@ import path from 'path';
 
 import Semver from 'semver';
 
-import {splitArguments} from '../../shared/common-utils.js';
 import type {ConfiguredOverrides} from '../../types/compilation/compiler-overrides.interfaces.js';
 import type {PreliminaryCompilerInfo} from '../../types/compiler.interfaces.js';
 import type {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces.js';
@@ -60,7 +59,7 @@ export class DartCompiler extends BaseCompiler {
         let options = this.optionsForFilter(filters, outputFilename, userOptions);
 
         if (this.compiler.options) {
-            options = options.concat(splitArguments(this.compiler.options));
+            options = options.concat(utils.splitArguments(this.compiler.options));
         }
 
         const libIncludes = this.getIncludeArguments(libraries, path.dirname(inputFilename));
diff --git a/lib/compilers/dotnet.ts b/lib/compilers/dotnet.ts
index df72d8420..5b76a9a95 100644
--- a/lib/compilers/dotnet.ts
+++ b/lib/compilers/dotnet.ts
@@ -525,11 +525,6 @@ do()
         return await super.runCompiler(ilasmPath, options, inputFilename, execOptions);
     }
 
-    override getSharedLibraryPathsAsArguments() {
-        return [];
-    }
-
-    // eslint-disable-next-line max-statements
     override async runCompiler(
         compiler: string,
         options: string[],
@@ -556,19 +551,14 @@ do()
         let isCrossgen2 =
             this.compiler.group === 'dotnetcrossgen2' ||
             (this.compiler.group === 'dotnetlegacy' && compilerInfo.sdkMajorVersion === 6);
-        let codegenArch = 'x64';
 
-        while (options.length > 0) {
+        // we need to skip the last option, because the last option is filename
+        while (options.length > 1) {
             const currentOption = options.shift();
             if (!currentOption) {
                 continue;
             }
 
-            // options before the input filename are user options
-            if (currentOption.includes(path.basename(inputFilename))) {
-                break;
-            }
-
             if ((isCoreRun || isMono) && (currentOption === '-e' || currentOption === '--env')) {
                 const envVar = options.shift();
                 if (envVar) {
@@ -623,13 +613,6 @@ do()
                             }
                         }
                     }
-                    if (currentOption === '--targetarch') {
-                        const value = options.shift();
-                        if (value) {
-                            toolOptions.push(value);
-                            codegenArch = value.trim().toLowerCase();
-                        }
-                    }
                 }
             }
         }
@@ -710,7 +693,6 @@ do()
             const crossgen2Result = await this.runCrossgen2(
                 compiler,
                 compilerInfo.sdkMajorVersion,
-                codegenArch,
                 execOptions,
                 this.clrBuildDir,
                 programDllPath,
@@ -795,7 +777,7 @@ do()
         if (useEnvFile) {
             const envVarFilePath = path.join(path.dirname(outputPath), '.env');
             await fs.writeFile(envVarFilePath, envVars.join('\n'));
-            corerunOptions.unshift('--env', envVarFilePath);
+            corerunOptions.splice(0, 0, '--env', envVarFilePath);
         } else {
             for (const env of envVars) {
                 const delimiterIndex = env.indexOf('=');
@@ -869,7 +851,6 @@ do()
     async runCrossgen2(
         compiler: string,
         sdkMajorVersion: number,
-        arch: string,
         execOptions: ExecutionOptions,
         bclPath: string,
         dllPath: string,
@@ -884,11 +865,6 @@ do()
             '-o', `${AssemblyName}.r2r.dll`,
         ].concat(options);
 
-        const corelibPath = path.join(this.clrBuildDir, 'corelib', arch, 'System.Private.CoreLib.dll');
-        if (await fs.exists(corelibPath)) {
-            crossgen2Options.unshift('-r', corelibPath);
-        }
-
         if (sdkMajorVersion >= 9) {
             crossgen2Options.push('--inputbubble', '--compilebubblegenerics');
         }
diff --git a/lib/compilers/glsl.ts b/lib/compilers/glsl.ts
index 9340911d6..8c8cbea8f 100644
--- a/lib/compilers/glsl.ts
+++ b/lib/compilers/glsl.ts
@@ -82,11 +82,6 @@ export class GLSLCompiler extends BaseCompiler {
         execOptions.customCwd = path.dirname(inputFilename);
 
         const spvBin = await this.exec(compiler, options, execOptions);
-
-        // glslang prefix things with 'ERROR:' which
-        // applyParse_SourceWithLine doesn't detect the line number then.
-        // For warnings, we need to adjust its position so parseSeverity works
-        spvBin.stdout = spvBin.stdout.replaceAll('ERROR: ', '').replaceAll(/WARNING: (.+?:\d+:) /g, '$1 warning: ');
         const result = this.transformToCompilationResult(spvBin, inputFilename);
 
         if (spvBin.code !== 0 || !(await utils.fileExists(spvBinFilename))) {
diff --git a/lib/compilers/java.ts b/lib/compilers/java.ts
index 823018681..5501b9e1c 100644
--- a/lib/compilers/java.ts
+++ b/lib/compilers/java.ts
@@ -26,19 +26,12 @@ import path from 'path';
 
 import fs from 'fs-extra';
 import Semver from 'semver';
-import _ from 'underscore';
 
 import type {ParsedAsmResult, ParsedAsmResultLine} from '../../types/asmresult/asmresult.interfaces.js';
-import {
-    BypassCache,
-    CacheKey,
-    CompilationResult,
-    ExecutionOptionsWithEnv,
-} from '../../types/compilation/compilation.interfaces.js';
+import {BypassCache, CacheKey, CompilationResult} from '../../types/compilation/compilation.interfaces.js';
 import type {PreliminaryCompilerInfo} from '../../types/compiler.interfaces.js';
 import {ExecutableExecutionOptions} from '../../types/execution/execution.interfaces.js';
 import type {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces.js';
-import type {SelectedLibraryVersion} from '../../types/libraries/libraries.interfaces.js';
 import {assert, unwrap} from '../assert.js';
 import {BaseCompiler, SimpleOutputFilenameCompiler} from '../base-compiler.js';
 import {CompilationEnvironment} from '../compilation-env.js';
@@ -55,8 +48,6 @@ export class JavaCompiler extends BaseCompiler implements SimpleOutputFilenameCo
     javaRuntime: string;
     mainRegex: RegExp;
 
-    libPaths: string[];
-
     constructor(compilerInfo: PreliminaryCompilerInfo, env: CompilationEnvironment) {
         super(
             {
@@ -68,42 +59,12 @@ export class JavaCompiler extends BaseCompiler implements SimpleOutputFilenameCo
         );
         this.javaRuntime = this.compilerProps<string>(`compiler.${this.compiler.id}.runtime`);
         this.mainRegex = /public static ?(.*?) void main\(java\.lang\.String\[]\)/;
-        this.libPaths = [];
     }
 
     override getSharedLibraryPathsAsArguments() {
         return [];
     }
 
-    override async runCompiler(
-        compiler: string,
-        options: string[],
-        inputFilename: string,
-        execOptions: ExecutionOptionsWithEnv,
-        filters?: ParseFiltersAndOutputOptions,
-    ): Promise<CompilationResult> {
-        if (!execOptions) {
-            execOptions = this.getDefaultExecOptions();
-        }
-
-        if (!execOptions.customCwd) {
-            execOptions.customCwd = path.dirname(inputFilename);
-        }
-
-        // The items in 'options' before the source file are user inputs.
-        const sourceFileOptionIndex = options.findIndex(option => {
-            return option.endsWith('.java');
-        });
-        const userOptions = options.slice(0, sourceFileOptionIndex);
-        const javaOptions = _.compact([...this.getClasspathArgument(), ...userOptions, inputFilename]);
-        const result = await this.exec(compiler, javaOptions, execOptions);
-        return {
-            ...this.transformToCompilationResult(result, inputFilename),
-            languageId: this.getCompilerResultLanguageId(filters),
-            instructionSet: this.getInstructionSetFromCompilerArgs(options),
-        };
-    }
-
     override async objdump(outputFilename: string, result: any, maxSize: number) {
         const dirPath = path.dirname(outputFilename);
         const files = await fs.readdir(dirPath);
@@ -456,18 +417,4 @@ export class JavaCompiler extends BaseCompiler implements SimpleOutputFilenameCo
             textsBeforeMethod,
         };
     }
-
-    getClasspathArgument(): string[] {
-        const libString = this.libPaths.join(':');
-        return libString ? ['-cp', libString] : [''];
-    }
-
-    override getIncludeArguments(libraries: SelectedLibraryVersion[], dirPath: string): string[] {
-        this.libPaths = libraries.flatMap(selectedLib => {
-            const foundVersion = this.findLibVersion(selectedLib);
-            if (!foundVersion) return [];
-            return foundVersion.path;
-        });
-        return this.libPaths;
-    }
 }
diff --git a/lib/compilers/odin.ts b/lib/compilers/odin.ts
deleted file mode 100644
index 251fa5ff2..000000000
--- a/lib/compilers/odin.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import path from 'path';
-
-import type {PreliminaryCompilerInfo} from '../../types/compiler.interfaces.js';
-import type {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces.js';
-import {BaseCompiler} from '../base-compiler.js';
-import {CompilationEnvironment} from '../compilation-env.js';
-
-export class OdinCompiler extends BaseCompiler {
-    private clangPath?: string;
-
-    static get key() {
-        return 'odin';
-    }
-
-    constructor(info: PreliminaryCompilerInfo, env: CompilationEnvironment) {
-        super(info, env);
-        this.compiler.supportsIrView = true;
-        this.compiler.irArg = [];
-        this.compiler.supportsIntel = false;
-        this.clangPath = this.compilerProps<string>('clangPath', undefined);
-    }
-
-    override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string) {
-        if (filters.execute || filters.binary) {
-            return ['-debug', '-keep-temp-files', `-out:${this.filename(outputFilename)}`];
-        }
-        return ['-build-mode:asm', '-debug', '-keep-temp-files', `-out:${this.filename(outputFilename)}`];
-    }
-
-    override orderArguments(
-        options,
-        inputFilename,
-        libIncludes,
-        libOptions,
-        libPaths,
-        libLinks,
-        userOptions,
-        staticLibLinks,
-    ) {
-        return ['build', this.filename(inputFilename), '-file'].concat(options, userOptions);
-    }
-
-    override getDefaultExecOptions() {
-        const execOptions = super.getDefaultExecOptions();
-        if (this.clangPath) {
-            execOptions.env.ODIN_CLANG_PATH = this.clangPath;
-        }
-
-        return execOptions;
-    }
-
-    override async checkOutputFileAndDoPostProcess(asmResult, outputFilename, filters) {
-        let newOutputFilename = outputFilename;
-        if (!filters.binary && !filters.execute) newOutputFilename = outputFilename.replace(/.s$/, '.S');
-        return super.checkOutputFileAndDoPostProcess(asmResult, newOutputFilename, filters);
-    }
-
-    override getIrOutputFilename(inputFilename: string): string {
-        return this.filename(path.dirname(inputFilename) + '/output.ll');
-    }
-
-    override async postProcessAsm(result, filters?: ParseFiltersAndOutputOptions) {
-        // we dont need demangling
-        return result;
-    }
-}
diff --git a/lib/compilers/slang.ts b/lib/compilers/slang.ts
deleted file mode 100644
index 5285590b1..000000000
--- a/lib/compilers/slang.ts
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2024, Compiler Explorer Authors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//     * Redistributions of source code must retain the above copyright notice,
-//       this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in the
-//       documentation and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-
-import path from 'path';
-
-import type {ExecutionOptions} from '../../types/compilation/compilation.interfaces.js';
-import type {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces.js';
-import {BaseCompiler} from '../base-compiler.js';
-import {logger} from '../logger.js';
-import {SPIRVAsmParser} from '../parsers/asm-parser-spirv.js';
-import * as utils from '../utils.js';
-
-export class SlangCompiler extends BaseCompiler {
-    protected disassemblerPath: string;
-    protected spirvAsm: SPIRVAsmParser;
-
-    static get key() {
-        return 'slang';
-    }
-
-    constructor(info: any, env: any) {
-        super(info, env);
-
-        this.spirvAsm = new SPIRVAsmParser(this.compilerProps);
-
-        this.disassemblerPath = this.compilerProps<string>('disassemblerPath');
-    }
-
-    getTarget(options?: string[]) {
-        if (options) {
-            const index = options.indexOf('-target');
-            if (index !== -1) {
-                return options[index + 1];
-            }
-        }
-        return 'spirv'; // no target found, slang default to 'spirv'
-    }
-
-    getPrimaryOutputFilename(dirPath: string, outputFilebase: string, target: string) {
-        if (target === 'spirv') {
-            return path.join(dirPath, `${outputFilebase}.spv`);
-        } else {
-            // If there is no intermediate file needed, can use file output
-            return this.getOutputFilename(dirPath, outputFilebase);
-        }
-    }
-
-    override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string, userOptions?: string[]) {
-        const sourceDir = path.dirname(outputFilename);
-        const target = this.getTarget(userOptions);
-        const spvBinFilename = this.getPrimaryOutputFilename(sourceDir, this.outputFilebase, target);
-        return ['-o', spvBinFilename, '-gminimal']; // -g provides debug info
-    }
-
-    override getOutputFilename(dirPath: string, outputFilebase: string) {
-        return path.join(dirPath, `${outputFilebase}.spvasm`);
-    }
-
-    override async runCompiler(
-        compiler: string,
-        options: string[],
-        inputFilename: string,
-        execOptions: ExecutionOptions & {env: Record<string, string>},
-    ) {
-        const sourceDir = path.dirname(inputFilename);
-        const target = this.getTarget(options);
-        const slangOutputFilename = this.getPrimaryOutputFilename(sourceDir, this.outputFilebase, target);
-
-        if (!execOptions) {
-            execOptions = this.getDefaultExecOptions();
-        }
-        execOptions.customCwd = path.dirname(inputFilename);
-
-        const slangOutput = await this.exec(compiler, options, execOptions);
-        const result = this.transformToCompilationResult(slangOutput, inputFilename);
-
-        if (slangOutput.code !== 0 || !(await utils.fileExists(slangOutputFilename))) {
-            return result;
-        }
-
-        // While slang does have a way to dump spirv assembly, using spirv-dis will make the SPIR-V we
-        // display unified with other things that produce SPIR-V
-        if (target === 'spirv') {
-            const spvasmFilename = this.getOutputFilename(sourceDir, this.outputFilebase);
-            const disassemblerFlags = [slangOutputFilename, '-o', spvasmFilename, '--comment'];
-
-            const spvasmOutput = await this.exec(this.disassemblerPath, disassemblerFlags, execOptions);
-            if (spvasmOutput.code !== 0) {
-                logger.error('SPIR-V binary to text failed', spvasmOutput);
-            }
-
-            result.stdout = result.stdout.concat(utils.parseOutput(spvasmOutput.stdout));
-            result.stderr = result.stderr.concat(utils.parseOutput(spvasmOutput.stderr));
-            result.languageId = 'spirv';
-        }
-
-        return result;
-    }
-
-    // slangc defaults to SPIR-V as a target, but has many target it can output
-    override async processAsm(result, filters: ParseFiltersAndOutputOptions, options: string[]) {
-        if (result.asm.startsWith('; SPIR-V')) {
-            return this.spirvAsm.processAsm(result.asm, filters);
-        }
-        // If not SPIR-V, just display as plain text to be safe
-        return super.processAsm(result, filters, options);
-    }
-}
diff --git a/lib/compilers/spirv.ts b/lib/compilers/spirv.ts
index 6085b3059..d7d8006ce 100644
--- a/lib/compilers/spirv.ts
+++ b/lib/compilers/spirv.ts
@@ -24,7 +24,6 @@
 
 import path from 'path';
 
-import {splitArguments} from '../../shared/common-utils.js';
 import type {ExecutionOptionsWithEnv} from '../../types/compilation/compilation.interfaces.js';
 import type {ConfiguredOverrides} from '../../types/compilation/compiler-overrides.interfaces.js';
 import {LLVMIrBackendOptions} from '../../types/compilation/ir.interfaces.js';
@@ -70,9 +69,9 @@ export class SPIRVCompiler extends BaseCompiler {
         backendOptions = backendOptions || {};
 
         if (this.compiler.options) {
-            const compilerOptions = splitArguments(this.compiler.options).filter(
-                option => option !== '-fno-crash-diagnostics',
-            );
+            const compilerOptions = utils
+                .splitArguments(this.compiler.options)
+                .filter(option => option !== '-fno-crash-diagnostics');
 
             options = options.concat(compilerOptions);
         }
diff --git a/lib/compilers/win32.ts b/lib/compilers/win32.ts
index 14966ac63..76a5c8bf4 100644
--- a/lib/compilers/win32.ts
+++ b/lib/compilers/win32.ts
@@ -26,7 +26,6 @@ import path from 'path';
 
 import _ from 'underscore';
 
-import {splitArguments} from '../../shared/common-utils.js';
 import type {CacheKey, ExecutionOptions} from '../../types/compilation/compilation.interfaces.js';
 import type {ConfiguredOverrides} from '../../types/compilation/compiler-overrides.interfaces.js';
 import type {PreliminaryCompilerInfo} from '../../types/compiler.interfaces.js';
@@ -38,6 +37,7 @@ import {CompilationEnvironment} from '../compilation-env.js';
 import {MapFileReaderVS} from '../mapfiles/map-file-vs.js';
 import {AsmParser} from '../parsers/asm-parser.js';
 import {PELabelReconstructor} from '../pe32-support.js';
+import * as utils from '../utils.js';
 
 export class Win32Compiler extends BaseCompiler {
     static get key() {
@@ -103,7 +103,7 @@ export class Win32Compiler extends BaseCompiler {
         backendOptions = backendOptions || {};
 
         if (this.compiler.options) {
-            options = options.concat(splitArguments(this.compiler.options));
+            options = options.concat(utils.splitArguments(this.compiler.options));
         }
 
         if (this.compiler.supportsOptOutput && backendOptions.produceOptInfo) {
@@ -140,6 +140,20 @@ export class Win32Compiler extends BaseCompiler {
         );
     }
 
+    override fixIncompatibleOptions(
+        options: string[],
+        userOptions: string[],
+        overrides: ConfiguredOverrides,
+    ): [string[], ConfiguredOverrides] {
+        // If userOptions contains anything starting with /source-charset or /execution-charset, remove /utf-8 from options
+        if (
+            userOptions.some(option => option.startsWith('/source-charset') || option.startsWith('/execution-charset'))
+        ) {
+            options = options.filter(option => option !== '/utf-8');
+        }
+        return [options, overrides];
+    }
+
     override optionsForFilter(filters: ParseFiltersAndOutputOptions, outputFilename: string, userOptions?: string[]) {
         if (filters.binary) {
             const mapFilename = outputFilename + '.map';
diff --git a/lib/compilers/ylc.ts b/lib/compilers/ylc.ts
index 0ec31e783..d1e9c386b 100644
--- a/lib/compilers/ylc.ts
+++ b/lib/compilers/ylc.ts
@@ -1,11 +1,11 @@
 import path from 'path';
 
-import {splitArguments} from '../../shared/common-utils.js';
 import {ConfiguredOverrides} from '../../types/compilation/compiler-overrides.interfaces.js';
 import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces.js';
 import {SelectedLibraryVersion} from '../../types/libraries/libraries.interfaces.js';
 import {unwrap} from '../assert.js';
 import {BaseCompiler} from '../base-compiler.js';
+import * as utils from '../utils.js';
 
 import {BaseParser} from './argument-parsers.js';
 
@@ -37,7 +37,7 @@ export class YLCCompiler extends BaseCompiler {
         options = options.concat(this.optionsForBackend(backendOptions, outputFilename));
 
         if (this.compiler.options) {
-            options = options.concat(splitArguments(this.compiler.options));
+            options = options.concat(utils.splitArguments(this.compiler.options));
         }
 
         if (this.compiler.supportsOptOutput && backendOptions.produceOptInfo) {
diff --git a/lib/execution/base-execution-env.ts b/lib/execution/base-execution-env.ts
index 199756f78..663695a7b 100644
--- a/lib/execution/base-execution-env.ts
+++ b/lib/execution/base-execution-env.ts
@@ -28,7 +28,6 @@ import path from 'path';
 import fs from 'fs-extra';
 import temp from 'temp';
 
-import {splitArguments} from '../../shared/common-utils.js';
 import {
     BuildResult,
     ExecutionOptions,
@@ -183,7 +182,7 @@ export class LocalExecutionEnvironment implements IExecutionEnvironment {
         assert(this.dirPath !== 'not initialized');
 
         const execExecutableOptions: ExecutableExecutionOptions = {
-            args: typeof params.args === 'string' ? splitArguments(params.args) : params.args || [],
+            args: typeof params.args === 'string' ? utils.splitArguments(params.args) : params.args || [],
             stdin: params.stdin || '',
             ldPath: this.buildResult.preparedLdPaths || [],
             env: {},
diff --git a/lib/handlers/api.ts b/lib/handlers/api.ts
index 3c98bf12c..5835d7eef 100644
--- a/lib/handlers/api.ts
+++ b/lib/handlers/api.ts
@@ -22,6 +22,7 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 // POSSIBILITY OF SUCH DAMAGE.
 
+import bodyParser from 'body-parser';
 import express from 'express';
 import _ from 'underscore';
 
@@ -94,7 +95,7 @@ export class ApiHandler {
             .all(methodNotAllowed);
 
         const maxUploadSize = ceProps('maxUploadSize', '1mb');
-        const textParser = express.text({limit: ceProps('bodyParserLimit', maxUploadSize), type: () => true});
+        const textParser = bodyParser.text({limit: ceProps('bodyParserLimit', maxUploadSize), type: () => true});
 
         this.handle
             .route('/compiler/:compiler/compile')
diff --git a/lib/handlers/api/site-template-controller.ts b/lib/handlers/api/site-template-controller.ts
index 2cf009411..03333bd86 100644
--- a/lib/handlers/api/site-template-controller.ts
+++ b/lib/handlers/api/site-template-controller.ts
@@ -24,7 +24,6 @@
 
 import express from 'express';
 
-import {SiteTemplateResponse} from '../../../types/features/site-templates.interfaces.js';
 import {getSiteTemplates} from '../../site-templates.js';
 import {cached, cors} from '../middleware.js';
 
@@ -38,9 +37,7 @@ export class SiteTemplateController implements HttpController {
     }
 
     public async getSiteTemplates(req: express.Request, res: express.Response) {
-        const {meta, templates} = await getSiteTemplates();
-        const flattened = Object.fromEntries(templates.map(({name, reference}) => [name, reference]));
-
-        res.send({meta, templates: flattened} satisfies SiteTemplateResponse);
+        const templates = await getSiteTemplates();
+        res.send(templates);
     }
 }
diff --git a/lib/handlers/compile.ts b/lib/handlers/compile.ts
index b8342e772..086a773c6 100644
--- a/lib/handlers/compile.ts
+++ b/lib/handlers/compile.ts
@@ -35,13 +35,12 @@ import _ from 'underscore';
 // @ts-ignore
 import which from 'which';
 
-import {remove, splitArguments} from '../../shared/common-utils.js';
+import {remove} from '../../shared/common-utils.js';
 import {
     ActiveTool,
     BypassCache,
     ExecutionParams,
     FiledataPair,
-    LegacyCompatibleActiveTool,
     UnparsedExecutionParams,
 } from '../../types/compilation/compilation.interfaces.js';
 import {CompilerOverrideOptions} from '../../types/compilation/compiler-overrides.interfaces.js';
@@ -149,7 +148,7 @@ export class CompileHandler implements ICompileHandler {
         // decoding middleware.
         this.proxy.on('proxyReq', (proxyReq, req) => {
             // TODO ideally I'd work out if this is "ok" - IncomingMessage doesn't have a body, but pragmatically the
-            //  object we get here does (introduced by express.json).
+            //  object we get here does (introduced by body-parser).
             const body = (req as any).body;
             if (!body || Object.keys(body).length === 0) {
                 return;
@@ -382,7 +381,7 @@ export class CompileHandler implements ICompileHandler {
             backendOptions: Record<string, any> = {},
             filters: ParseFiltersAndOutputOptions,
             bypassCache = BypassCache.None,
-            inputTools: LegacyCompatibleActiveTool[] = [];
+            tools;
         const execReqParams: UnparsedExecutionParams = {};
         let libraries: any[] = [];
         // IF YOU MODIFY ANYTHING HERE PLEASE UPDATE THE DOCUMENTATION!
@@ -399,7 +398,7 @@ export class CompileHandler implements ICompileHandler {
             execReqParams.runtimeTools = execParams.runtimeTools;
             backendOptions = requestOptions.compilerOptions || {};
             filters = {...compiler.getDefaultFilters(), ...requestOptions.filters};
-            inputTools = requestOptions.tools || [];
+            tools = requestOptions.tools;
             libraries = requestOptions.libraries || [];
         } else if (req.body && req.body.compiler) {
             const textRequest = req.body as CompileRequestTextBody;
@@ -442,16 +441,17 @@ export class CompileHandler implements ICompileHandler {
             backendOptions.skipPopArgs = query.skipPopArgs === 'true';
         }
         const executeParameters: ExecutionParams = {
-            args: Array.isArray(execReqParams.args) ? execReqParams.args || '' : splitArguments(execReqParams.args),
+            args: Array.isArray(execReqParams.args)
+                ? execReqParams.args || ''
+                : utils.splitArguments(execReqParams.args),
             stdin: execReqParams.stdin || '',
             runtimeTools: execReqParams.runtimeTools || [],
         };
 
-        const tools: ActiveTool[] = inputTools.map(tool => {
-            // expand tools.args to an array using utils.splitArguments if it was a string
-            if (typeof tool.args === 'string') tool.args = splitArguments(tool.args);
-            return tool as ActiveTool;
-        });
+        tools = tools || [];
+        for (const tool of tools) {
+            tool.args = utils.splitArguments(tool.args);
+        }
 
         // Backwards compatibility: bypassCache used to be a boolean.
         // Convert a boolean input to an enum's underlying numeric value
@@ -459,7 +459,7 @@ export class CompileHandler implements ICompileHandler {
 
         return {
             source,
-            options: splitArguments(options),
+            options: utils.splitArguments(options),
             backendOptions,
             filters,
             bypassCache,
@@ -492,7 +492,7 @@ export class CompileHandler implements ICompileHandler {
             if (data.presplit) {
                 return data.usedOptions;
             } else {
-                return splitArguments(data.usedOptions);
+                return utils.splitArguments(data.usedOptions);
             }
         }
         return false;
diff --git a/lib/handlers/middleware.ts b/lib/handlers/middleware.ts
index ecfd3d5af..9b23f2782 100644
--- a/lib/handlers/middleware.ts
+++ b/lib/handlers/middleware.ts
@@ -27,12 +27,11 @@ import express from 'express';
 import * as props from '../properties.js';
 
 const ceProps = props.propsFor('compiler-explorer');
+const staticMaxAge = ceProps('staticMaxAgeSecs', 31536000);
 
 /** Add static headers to the response */
 export const cached: express.Handler = (_, res, next) => {
-    // Cannot elide the ceProps() call here, because this file may be imported by other files such as app.ts before the
-    // properties are loaded from config files.
-    res.set('Cache-Control', `public, max-age=${ceProps('staticMaxAgeSecs', 31536000)}, must-revalidate`);
+    res.set('Cache-Control', `public, max-age=${staticMaxAge}, must-revalidate`);
     return next();
 };
 
diff --git a/lib/handlers/noscript.ts b/lib/handlers/noscript.ts
index ca6dad9d2..94dd8931d 100644
--- a/lib/handlers/noscript.ts
+++ b/lib/handlers/noscript.ts
@@ -22,6 +22,7 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 // POSSIBILITY OF SUCH DAMAGE.
 
+import bodyParser from 'body-parser';
 import express from 'express';
 
 import {isString} from '../../shared/common-utils.js';
@@ -47,7 +48,7 @@ export class NoScriptHandler {
     readonly defaultLanguage: string;
     readonly compileHandler: CompileHandler;
 
-    formDataParser: ReturnType<typeof express.urlencoded> | undefined;
+    formDataParser: ReturnType<typeof bodyParser.urlencoded> | undefined;
 
     /* the type for config makes the most sense to define in app.ts or api.ts */
     constructor(
@@ -63,7 +64,8 @@ export class NoScriptHandler {
     }
 
     InitializeRoutes(options: {limit: string}) {
-        this.formDataParser = express.urlencoded({
+        this.formDataParser = bodyParser.urlencoded({
+            type: 'application/x-www-form-urlencoded',
             limit: options.limit,
             extended: false,
         });
diff --git a/lib/languages.ts b/lib/languages.ts
index 9dc229840..7bdff9de6 100644
--- a/lib/languages.ts
+++ b/lib/languages.ts
@@ -601,17 +601,6 @@ const definitions: Record<LanguageKey, LanguageDefinition> = {
         previewFilter: null,
         monacoDisassembly: null,
     },
-    odin: {
-        name: 'Odin',
-        monaco: 'odin',
-        extensions: ['.odin'],
-        alias: [],
-        logoUrl: 'odin.png',
-        logoUrlDark: null,
-        formatter: null,
-        previewFilter: null,
-        monacoDisassembly: null,
-    },
     openclc: {
         name: 'OpenCL C',
         monaco: 'openclc',
@@ -715,17 +704,6 @@ const definitions: Record<LanguageKey, LanguageDefinition> = {
         monacoDisassembly: null,
         digitSeparator: '_',
     },
-    slang: {
-        name: 'Slang',
-        monaco: 'slang',
-        extensions: ['.slang'],
-        alias: [],
-        logoUrl: 'slang.png',
-        logoUrlDark: null,
-        formatter: null,
-        previewFilter: null,
-        monacoDisassembly: null,
-    },
     solidity: {
         name: 'Solidity',
         monaco: 'sol',
diff --git a/lib/options-handler.ts b/lib/options-handler.ts
index 8dc5c086a..d29b520e0 100755
--- a/lib/options-handler.ts
+++ b/lib/options-handler.ts
@@ -30,7 +30,6 @@ import semverParser from 'semver';
 import _ from 'underscore';
 
 import {AppDefaultArguments} from '../app.js';
-import {splitArguments} from '../shared/common-utils.js';
 import {CompilerInfo} from '../types/compiler.interfaces.js';
 import type {LanguageKey} from '../types/languages.interfaces.js';
 import type {Source} from '../types/source.interfaces.js';
@@ -40,7 +39,7 @@ import {logger} from './logger.js';
 import type {PropertyGetter, PropertyValue} from './properties.interfaces.js';
 import {CompilerProps} from './properties.js';
 import {BaseTool, getToolTypeByKey} from './tooling/index.js';
-import {asSafeVer, getHash, splitIntoArray} from './utils.js';
+import {asSafeVer, getHash, splitArguments, splitIntoArray} from './utils.js';
 
 // TODO: Figure out if same as libraries.interfaces.ts?
 export type VersionInfo = {
diff --git a/lib/parsers/asm-parser-spirv.ts b/lib/parsers/asm-parser-spirv.ts
index 74f0d6183..e72014bc0 100644
--- a/lib/parsers/asm-parser-spirv.ts
+++ b/lib/parsers/asm-parser-spirv.ts
@@ -105,8 +105,6 @@ export class SPIRVAsmParser extends AsmParser {
         const opLine = /OpLine/;
         const opNoLine = /OpNoLine/;
         const opExtDbg = /OpExtInst\s+%void\s+%\d+\s+Debug/;
-        const opExtDbgLine = /OpExtInst.*DebugLine %\w+\s+(%\w+)\s+(%\w+)/;
-        const opExtDbgNoLine = /OpExtInst.*DebugNoLine/;
         const opModuleProcessed = /OpModuleProcessed/;
         const opString = /OpString/;
         const opSource = /OpSource/;
@@ -114,13 +112,6 @@ export class SPIRVAsmParser extends AsmParser {
         const opMemberName = /OpMemberName/;
         const opLabel = /OpLabel/;
 
-        // Need to build constants values to get line numbers from DebugInfo.
-        // It is validated these will only be int/uint so can ignore floats
-        const opConstant = /(%\w+)\s+=\s+OpConstant\s+%\w+\s+(\d+)/;
-        const constantIdToValue: Record<string, number> = {};
-        const opDebugSoruce = /(%\w+) = OpExtInst.*DebugSource %\w+\s+(%\w+)/;
-        const idToOpString: Record<string, string> = {};
-
         const labelDef = /^\s*(%\w+)\s*=\s*(?:OpFunction\s+|OpLabel)/;
 
         const unclosedString = /^[^"]+"(?:[^"\\]|\\.)*$/;
@@ -139,29 +130,7 @@ export class SPIRVAsmParser extends AsmParser {
                 continue;
             }
 
-            let match = line.match(opConstant);
-            if (match) {
-                constantIdToValue[match[1]] = parseInt(match[2]);
-            }
-            match = line.match(opDebugSoruce);
-            if (match) {
-                idToOpString[match[1]] = match[2];
-            }
-
-            // TODO - Currently don't handle if there is 'Line End' being used
-            // (most people just have 'Line Start' and 'Line End' the same)
-            match = line.match(opExtDbgLine);
-            if (match) {
-                const opStringId = idToOpString[match[1]];
-                source = {
-                    file: utils.maskRootdir(opStrings[parseInt(opStringId)]),
-                    line: constantIdToValue[match[1]],
-                    mainsource: true,
-                };
-            }
-
-            // Will only have either OpLine or DebugLine
-            match = line.match(sourceTag);
+            const match = line.match(sourceTag);
             if (match) {
                 source = {
                     file: utils.maskRootdir(opStrings[parseInt(match[1])]),
@@ -182,7 +151,7 @@ export class SPIRVAsmParser extends AsmParser {
             }
 
             // OpLabel are by definition the start of a block, so don't include in previous source
-            if (endBlock.test(line) || opNoLine.test(line) || opExtDbgNoLine.test(line) || opLabel.test(line)) {
+            if (endBlock.test(line) || opNoLine.test(line) || opLabel.test(line)) {
                 source = null;
             }
 
diff --git a/lib/site-templates.ts b/lib/site-templates.ts
index a864c89f0..56068a1af 100644
--- a/lib/site-templates.ts
+++ b/lib/site-templates.ts
@@ -25,13 +25,13 @@
 import * as fsp from 'node:fs/promises';
 import path from 'node:path';
 
-import yaml from 'yaml';
+import _ from 'underscore';
 
-import {SiteTemplateConfiguration} from '../types/features/site-templates.interfaces.js';
+import {SiteTemplatesType} from '../types/features/site-templates.interfaces.js';
 
-let siteTemplates: SiteTemplateConfiguration;
+let siteTemplates: SiteTemplatesType;
 
-export async function getSiteTemplates(): Promise<SiteTemplateConfiguration> {
+export async function getSiteTemplates(): Promise<SiteTemplatesType> {
     siteTemplates ??= await loadSiteTemplates('etc/config');
     return siteTemplates;
 }
@@ -41,7 +41,17 @@ export async function getSiteTemplates(): Promise<SiteTemplateConfiguration> {
  *
  * The configuration keys that start with "meta" are returned as metadata keys in the 0th element of the returned tuple
  */
-async function loadSiteTemplates(configDir: string): Promise<SiteTemplateConfiguration> {
-    const config = await fsp.readFile(path.join(configDir, 'site-templates.yaml'), 'utf8');
-    return yaml.parse(config);
+async function loadSiteTemplates(configDir: string): Promise<SiteTemplatesType> {
+    const config = await fsp.readFile(path.join(configDir, 'site-templates.conf'), 'utf8');
+    const properties = config
+        .split('\n')
+        .filter(l => l.length > 0)
+        .map(property => {
+            // Rison does not have equal signs in its syntax, so we do not need to account for any trailing equal signs
+            // after the first one.
+            const [name, value] = property.split('=');
+            return [name, value] as const;
+        });
+    const [meta, templates] = _.partition(properties, ([name]) => name.startsWith('meta.'));
+    return {meta: Object.fromEntries(meta), templates: Object.fromEntries(templates)};
 }
diff --git a/lib/toolchain-utils.ts b/lib/toolchain-utils.ts
index 061de8795..b0a621ba5 100644
--- a/lib/toolchain-utils.ts
+++ b/lib/toolchain-utils.ts
@@ -26,10 +26,11 @@ import path from 'path';
 
 import fs from 'fs-extra';
 
-import {splitArguments} from '../shared/common-utils.js';
 import {CompilerOverrideOptions} from '../types/compilation/compiler-overrides.interfaces.js';
 import {PreliminaryCompilerInfo} from '../types/compiler.interfaces.js';
 
+import {splitArguments} from './utils.js';
+
 export const clang_style_toolchain_flag = '--gcc-toolchain=';
 export const icc_style_toolchain_flag = '--gxx-name=';
 export const clang_style_sysroot_flag = '--sysroot=';
diff --git a/lib/tooling/clang-tidy-tool.ts b/lib/tooling/clang-tidy-tool.ts
index 5d8f9a0a4..5d674d63c 100644
--- a/lib/tooling/clang-tidy-tool.ts
+++ b/lib/tooling/clang-tidy-tool.ts
@@ -26,10 +26,10 @@ import path from 'path';
 
 import fs from 'fs-extra';
 
-import {splitArguments} from '../../shared/common-utils.js';
 import {CompilationInfo} from '../../types/compilation/compilation.interfaces.js';
 import {ToolInfo} from '../../types/tool.interfaces.js';
 import {OptionsHandlerLibrary} from '../options-handler.js';
+import * as utils from '../utils.js';
 
 import {ToolEnv} from './base-tool.interface.js';
 import {BaseTool} from './base-tool.js';
@@ -75,7 +75,7 @@ export class ClangTidyTool extends BaseTool {
         //     -> before my patchup this was done only for non-clang compilers
         //  3) options manually specified in the compiler tab (options)
         //  *) indepenent are `args` from the clang-tidy tab
-        let compileFlags = splitArguments(compilationInfo.compiler.options);
+        let compileFlags = utils.splitArguments(compilationInfo.compiler.options);
         compileFlags = compileFlags.concat(includeflags);
         compileFlags = compileFlags.concat(libOptions);
 
diff --git a/lib/tooling/compiler-dropin-tool.ts b/lib/tooling/compiler-dropin-tool.ts
index bf26d0069..0acff3118 100644
--- a/lib/tooling/compiler-dropin-tool.ts
+++ b/lib/tooling/compiler-dropin-tool.ts
@@ -22,11 +22,11 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 // POSSIBILITY OF SUCH DAMAGE.
 
-import {splitArguments} from '../../shared/common-utils.js';
 import {CompilationInfo} from '../../types/compilation/compilation.interfaces.js';
 import {ToolInfo, ToolResult} from '../../types/tool.interfaces.js';
 import {OptionsHandlerLibrary} from '../options-handler.js';
 import {getToolchainPath} from '../toolchain-utils.js';
+import * as utils from '../utils.js';
 
 import {ToolEnv} from './base-tool.interface.js';
 import {BaseTool} from './base-tool.js';
@@ -64,7 +64,9 @@ export class CompilerDropinTool extends BaseTool {
 
         const toolchainPath = this.getToolchainPath(compilationInfo);
 
-        let compilerOptions = compilationInfo.compiler.options ? splitArguments(compilationInfo.compiler.options) : [];
+        let compilerOptions = compilationInfo.compiler.options
+            ? utils.splitArguments(compilationInfo.compiler.options)
+            : [];
 
         if (toolchainPath) {
             // note: needs toolchain argument twice as the first time its sometimes ignored
diff --git a/lib/tooling/microsoft-analysis-tool.ts b/lib/tooling/microsoft-analysis-tool.ts
index ebb1c8be8..8be7a9041 100644
--- a/lib/tooling/microsoft-analysis-tool.ts
+++ b/lib/tooling/microsoft-analysis-tool.ts
@@ -24,11 +24,11 @@
 
 import path from 'path';
 
-import {splitArguments} from '../../shared/common-utils.js';
 import {ToolInfo} from '../../types/tool.interfaces.js';
 import {unwrap} from '../assert.js';
 import {logger} from '../logger.js';
 import {OptionsHandlerLibrary} from '../options-handler.js';
+import * as utils from '../utils.js';
 
 import {ToolEnv} from './base-tool.interface.js';
 import {BaseTool} from './base-tool.js';
@@ -88,7 +88,7 @@ export class MicrosoftAnalysisTool extends BaseTool {
         const libOptions = super.getLibraryOptions(compilationInfo.libraries, unwrap(supportedLibraries));
         const includeflags = super.getIncludeArguments(compilationInfo.libraries, unwrap(supportedLibraries));
 
-        let compileFlags = splitArguments(compilationInfo.compiler.options);
+        let compileFlags = utils.splitArguments(compilationInfo.compiler.options);
         compileFlags = compileFlags.concat(includeflags, libOptions);
 
         const manualCompileFlags = options.filter((option: string) => option !== sourcefile);
diff --git a/lib/tooling/pvs-studio-tool.ts b/lib/tooling/pvs-studio-tool.ts
index dac36e40c..d28107143 100644
--- a/lib/tooling/pvs-studio-tool.ts
+++ b/lib/tooling/pvs-studio-tool.ts
@@ -26,7 +26,6 @@ import path from 'path';
 
 import fs from 'fs-extra';
 
-import {splitArguments} from '../../shared/common-utils.js';
 import {CompilationInfo} from '../../types/compilation/compilation.interfaces.js';
 import {ToolInfo} from '../../types/tool.interfaces.js';
 import {assert} from '../assert.js';
@@ -61,7 +60,7 @@ export class PvsStudioTool extends BaseTool {
         const sourceDir = path.dirname(inputFilepath);
 
         // Collecting the flags of compilation
-        let compileFlags = splitArguments(compilationInfo.compiler.options);
+        let compileFlags = utils.splitArguments(compilationInfo.compiler.options);
 
         const includeflags = super.getIncludeArguments(compilationInfo.libraries, compilationInfo.compiler);
         compileFlags = compileFlags.concat(includeflags);
diff --git a/lib/tooling/sonar-tool.ts b/lib/tooling/sonar-tool.ts
index 10540ed73..94bca8091 100644
--- a/lib/tooling/sonar-tool.ts
+++ b/lib/tooling/sonar-tool.ts
@@ -24,7 +24,6 @@
 
 import path from 'path';
 
-import {splitArguments} from '../../shared/common-utils.js';
 import {CompilationInfo, ExecutionOptions} from '../../types/compilation/compilation.interfaces.js';
 import type {
     Fix,
@@ -188,7 +187,7 @@ export class SonarTool extends BaseTool {
 
         // Collecting the flags of compilation
 
-        let compileFlags: string[] = splitArguments(compilationInfo.compiler.options);
+        let compileFlags: string[] = utils.splitArguments(compilationInfo.compiler.options);
         const includeflags = super.getIncludeArguments(compilationInfo.libraries, supportedLibraries || {});
         compileFlags = compileFlags.concat(includeflags);
         const libOptions = super.getLibraryOptions(compilationInfo.libraries, supportedLibraries || {});
diff --git a/lib/utils.ts b/lib/utils.ts
index 2b630183a..25b27f489 100644
--- a/lib/utils.ts
+++ b/lib/utils.ts
@@ -31,6 +31,7 @@ import {fileURLToPath} from 'url';
 import fs from 'fs-extra';
 import {ComponentConfig, ItemConfigType} from 'golden-layout';
 import semverParser from 'semver';
+import {parse as quoteParse} from 'shell-quote';
 import _ from 'underscore';
 
 import type {CacheableValue} from '../types/cache.interfaces.js';
@@ -441,6 +442,14 @@ export function splitIntoArray(input?: string, defaultArray: string[] = []): str
     }
 }
 
+export function splitArguments(options = ''): string[] {
+    // escape hashes first, otherwise they're interpreted as comments
+    const escapedOptions = options.replaceAll('#', '\\#');
+    return _.chain(quoteParse(escapedOptions).map((x: any) => (typeof x === 'string' ? x : (x.pattern as string))))
+        .compact()
+        .value();
+}
+
 /***
  * Absolute path to the root of the application
  */
diff --git a/package-lock.json b/package-lock.json
index c242fe731..0f4b46ea3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,6 +22,7 @@
         "@sentry/node": "^7.119.2",
         "@types/semver": "^7.5.8",
         "big-integer": "^1.6.52",
+        "body-parser": "^1.20.2",
         "bootstrap": "^4.6.2",
         "buffer": "^6.0.3",
         "chart.js": "^4.4.6",
@@ -31,7 +32,7 @@
         "cross-env": "^7.0.3",
         "enhanced-ms": "^3.0.0",
         "events": "^3.3.0",
-        "express": "^4.21.2",
+        "express": "^4.21.1",
         "file-saver": "^2.0.5",
         "fs-extra": "^11.2.0",
         "golden-layout": "^1.5.9",
@@ -59,13 +60,14 @@
         "scroll-into-view-if-needed": "^3.1.0",
         "semver": "^7.6.3",
         "serve-favicon": "^2.5.0",
+        "shell-quote": "^1.8.1",
         "systemd-socket": "0.0.0",
         "tar-stream": "^3.1.7",
         "temp": "^0.9.4",
         "tom-select": "^2.3.1",
         "tree-kill": "^1.2.2",
         "triple-beam": "^1.4.1",
-        "tsx": "^4.19.2",
+        "ts-node": "^10.9.2",
         "underscore": "^1.13.7",
         "url-join": "^5.0.0",
         "whatwg-fetch": "^3.6.20",
@@ -80,6 +82,7 @@
       "devDependencies": {
         "@sentry/types": "^8.36.0",
         "@smithy/util-stream": "^3.2.1",
+        "@types/body-parser": "^1.19.5",
         "@types/bootstrap": "^5.2.10",
         "@types/chai": "^5.0.1",
         "@types/compression": "^1.7.5",
@@ -94,6 +97,7 @@
         "@types/request": "^2.48.12",
         "@types/response-time": "^2.3.8",
         "@types/serve-favicon": "^2.5.7",
+        "@types/shell-quote": "^1.7.5",
         "@types/temp": "^0.9.4",
         "@types/underscore": "^1.13.0",
         "@types/url-join": "^4.0.3",
@@ -132,6 +136,7 @@
         "sass-loader": "^16.0.3",
         "source-map-loader": "^5.0.0",
         "supertest": "^7.0.0",
+        "supervisor": "^0.12.0",
         "terser-webpack-plugin": "^5.3.10",
         "ts-loader": "^9.5.1",
         "typescript": "~5.5",
@@ -1479,6 +1484,26 @@
         "node": ">=0.1.90"
       }
     },
+    "node_modules/@cspotcode/source-map-support": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+      "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+      "dependencies": {
+        "@jridgewell/trace-mapping": "0.3.9"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.9",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+      "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+      "dependencies": {
+        "@jridgewell/resolve-uri": "^3.0.3",
+        "@jridgewell/sourcemap-codec": "^1.4.10"
+      }
+    },
     "node_modules/@cypress/request": {
       "version": "3.0.6",
       "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.6.tgz",
@@ -1871,21 +1896,6 @@
         "node": ">=12"
       }
     },
-    "node_modules/@esbuild/openbsd-arm64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz",
-      "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
     "node_modules/@esbuild/openbsd-x64": {
       "version": "0.21.5",
       "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
@@ -4168,6 +4178,26 @@
         "node": ">=10.13.0"
       }
     },
+    "node_modules/@tsconfig/node10": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
+      "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw=="
+    },
+    "node_modules/@tsconfig/node12": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+      "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="
+    },
+    "node_modules/@tsconfig/node14": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+      "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow=="
+    },
+    "node_modules/@tsconfig/node16": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
+      "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA=="
+    },
     "node_modules/@types/body-parser": {
       "version": "1.19.5",
       "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
@@ -4467,6 +4497,12 @@
         "@types/send": "*"
       }
     },
+    "node_modules/@types/shell-quote": {
+      "version": "1.7.5",
+      "resolved": "https://registry.npmjs.org/@types/shell-quote/-/shell-quote-1.7.5.tgz",
+      "integrity": "sha512-+UE8GAGRPbJVQDdxi16dgadcBfQ+KG2vgZhV1+3A1XmHbmwcdwhCUwIdy+d3pAGrbvgRoVSjeI9vOWyq376Yzw==",
+      "dev": true
+    },
     "node_modules/@types/sinon": {
       "version": "17.0.3",
       "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz",
@@ -5157,6 +5193,17 @@
         "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
       }
     },
+    "node_modules/acorn-walk": {
+      "version": "8.3.4",
+      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
+      "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+      "dependencies": {
+        "acorn": "^8.11.0"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/aggregate-error": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
@@ -5318,6 +5365,11 @@
         "node": ">=14"
       }
     },
+    "node_modules/arg": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
+    },
     "node_modules/argparse": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -6520,6 +6572,11 @@
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
       "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
     },
+    "node_modules/create-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+      "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
+    },
     "node_modules/cross-env": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
@@ -8274,9 +8331,9 @@
       }
     },
     "node_modules/express": {
-      "version": "4.21.2",
-      "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
-      "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+      "version": "4.21.1",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
+      "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
       "dependencies": {
         "accepts": "~1.3.8",
         "array-flatten": "1.1.1",
@@ -8297,7 +8354,7 @@
         "methods": "~1.1.2",
         "on-finished": "2.4.1",
         "parseurl": "~1.3.3",
-        "path-to-regexp": "0.1.12",
+        "path-to-regexp": "0.1.10",
         "proxy-addr": "~2.0.7",
         "qs": "6.13.0",
         "range-parser": "~1.2.1",
@@ -8312,10 +8369,6 @@
       },
       "engines": {
         "node": ">= 0.10.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/express"
       }
     },
     "node_modules/express/node_modules/debug": {
@@ -8786,6 +8839,7 @@
       "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": [
@@ -8896,6 +8950,7 @@
       "version": "4.8.1",
       "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz",
       "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==",
+      "dev": true,
       "dependencies": {
         "resolve-pkg-maps": "^1.0.0"
       },
@@ -10968,6 +11023,11 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/make-error": {
+      "version": "1.3.6",
+      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
+    },
     "node_modules/mdn-data": {
       "version": "2.0.30",
       "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
@@ -11855,9 +11915,9 @@
       "dev": true
     },
     "node_modules/path-to-regexp": {
-      "version": "0.1.12",
-      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
-      "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
+      "version": "0.1.10",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
+      "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w=="
     },
     "node_modules/path-type": {
       "version": "4.0.0",
@@ -13250,6 +13310,7 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
       "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+      "dev": true,
       "funding": {
         "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
       }
@@ -13755,6 +13816,14 @@
         "node": ">=8"
       }
     },
+    "node_modules/shell-quote": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
+      "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/side-channel": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
@@ -14302,6 +14371,19 @@
         "node": ">=14.18.0"
       }
     },
+    "node_modules/supervisor": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/supervisor/-/supervisor-0.12.0.tgz",
+      "integrity": "sha512-iBYeU5Or4WiiIa3+ns1DpHIiHjNNXSuYUiixKcznewwo4ImBJ8EobktaAo2csOcauhrz4SvKRTou8Z2C3W28+A==",
+      "dev": true,
+      "bin": {
+        "node-supervisor": "lib/cli-wrapper.js",
+        "supervisor": "lib/cli-wrapper.js"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
     "node_modules/supports-color": {
       "version": "8.1.1",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
@@ -14840,6 +14922,56 @@
         "node": ">= 8"
       }
     },
+    "node_modules/ts-node": {
+      "version": "10.9.2",
+      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
+      "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
+      "dependencies": {
+        "@cspotcode/source-map-support": "^0.8.0",
+        "@tsconfig/node10": "^1.0.7",
+        "@tsconfig/node12": "^1.0.7",
+        "@tsconfig/node14": "^1.0.0",
+        "@tsconfig/node16": "^1.0.2",
+        "acorn": "^8.4.1",
+        "acorn-walk": "^8.1.1",
+        "arg": "^4.1.0",
+        "create-require": "^1.1.0",
+        "diff": "^4.0.1",
+        "make-error": "^1.1.1",
+        "v8-compile-cache-lib": "^3.0.1",
+        "yn": "3.1.1"
+      },
+      "bin": {
+        "ts-node": "dist/bin.js",
+        "ts-node-cwd": "dist/bin-cwd.js",
+        "ts-node-esm": "dist/bin-esm.js",
+        "ts-node-script": "dist/bin-script.js",
+        "ts-node-transpile-only": "dist/bin-transpile.js",
+        "ts-script": "dist/bin-script-deprecated.js"
+      },
+      "peerDependencies": {
+        "@swc/core": ">=1.2.50",
+        "@swc/wasm": ">=1.2.50",
+        "@types/node": "*",
+        "typescript": ">=2.7"
+      },
+      "peerDependenciesMeta": {
+        "@swc/core": {
+          "optional": true
+        },
+        "@swc/wasm": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/ts-node/node_modules/diff": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+      "engines": {
+        "node": ">=0.3.1"
+      }
+    },
     "node_modules/tsconfig-paths": {
       "version": "3.15.0",
       "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
@@ -14869,407 +15001,6 @@
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
       "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
     },
-    "node_modules/tsx": {
-      "version": "4.19.2",
-      "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz",
-      "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==",
-      "dependencies": {
-        "esbuild": "~0.23.0",
-        "get-tsconfig": "^4.7.5"
-      },
-      "bin": {
-        "tsx": "dist/cli.mjs"
-      },
-      "engines": {
-        "node": ">=18.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.3"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/aix-ppc64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz",
-      "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "aix"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/android-arm": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz",
-      "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/android-arm64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz",
-      "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/android-x64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz",
-      "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/darwin-arm64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz",
-      "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/darwin-x64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz",
-      "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz",
-      "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/freebsd-x64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz",
-      "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/linux-arm": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz",
-      "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/linux-arm64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz",
-      "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/linux-ia32": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz",
-      "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/linux-loong64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz",
-      "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==",
-      "cpu": [
-        "loong64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/linux-mips64el": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz",
-      "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==",
-      "cpu": [
-        "mips64el"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/linux-ppc64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz",
-      "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/linux-riscv64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz",
-      "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==",
-      "cpu": [
-        "riscv64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/linux-s390x": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz",
-      "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==",
-      "cpu": [
-        "s390x"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/linux-x64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz",
-      "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/netbsd-x64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz",
-      "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/openbsd-x64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz",
-      "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/sunos-x64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz",
-      "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/win32-arm64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz",
-      "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/win32-ia32": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz",
-      "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/@esbuild/win32-x64": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz",
-      "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/tsx/node_modules/esbuild": {
-      "version": "0.23.1",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz",
-      "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==",
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "optionalDependencies": {
-        "@esbuild/aix-ppc64": "0.23.1",
-        "@esbuild/android-arm": "0.23.1",
-        "@esbuild/android-arm64": "0.23.1",
-        "@esbuild/android-x64": "0.23.1",
-        "@esbuild/darwin-arm64": "0.23.1",
-        "@esbuild/darwin-x64": "0.23.1",
-        "@esbuild/freebsd-arm64": "0.23.1",
-        "@esbuild/freebsd-x64": "0.23.1",
-        "@esbuild/linux-arm": "0.23.1",
-        "@esbuild/linux-arm64": "0.23.1",
-        "@esbuild/linux-ia32": "0.23.1",
-        "@esbuild/linux-loong64": "0.23.1",
-        "@esbuild/linux-mips64el": "0.23.1",
-        "@esbuild/linux-ppc64": "0.23.1",
-        "@esbuild/linux-riscv64": "0.23.1",
-        "@esbuild/linux-s390x": "0.23.1",
-        "@esbuild/linux-x64": "0.23.1",
-        "@esbuild/netbsd-x64": "0.23.1",
-        "@esbuild/openbsd-arm64": "0.23.1",
-        "@esbuild/openbsd-x64": "0.23.1",
-        "@esbuild/sunos-x64": "0.23.1",
-        "@esbuild/win32-arm64": "0.23.1",
-        "@esbuild/win32-ia32": "0.23.1",
-        "@esbuild/win32-x64": "0.23.1"
-      }
-    },
     "node_modules/tunnel-agent": {
       "version": "0.6.0",
       "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -15408,7 +15139,6 @@
       "version": "5.5.4",
       "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
       "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
-      "dev": true,
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
@@ -15567,6 +15297,11 @@
         "uuid": "dist/bin/uuid"
       }
     },
+    "node_modules/v8-compile-cache-lib": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+      "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="
+    },
     "node_modules/validate-npm-package-license": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -16322,6 +16057,14 @@
         "fd-slicer": "~1.1.0"
       }
     },
+    "node_modules/yn": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/yocto-queue": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/package.json b/package.json
index 5ef0ee61f..a44f542fb 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
     "@sentry/node": "^7.119.2",
     "@types/semver": "^7.5.8",
     "big-integer": "^1.6.52",
+    "body-parser": "^1.20.2",
     "bootstrap": "^4.6.2",
     "buffer": "^6.0.3",
     "chart.js": "^4.4.6",
@@ -40,7 +41,7 @@
     "cross-env": "^7.0.3",
     "enhanced-ms": "^3.0.0",
     "events": "^3.3.0",
-    "express": "^4.21.2",
+    "express": "^4.21.1",
     "file-saver": "^2.0.5",
     "fs-extra": "^11.2.0",
     "golden-layout": "^1.5.9",
@@ -68,13 +69,14 @@
     "scroll-into-view-if-needed": "^3.1.0",
     "semver": "^7.6.3",
     "serve-favicon": "^2.5.0",
+    "shell-quote": "^1.8.1",
     "systemd-socket": "0.0.0",
     "tar-stream": "^3.1.7",
     "temp": "^0.9.4",
     "tom-select": "^2.3.1",
     "tree-kill": "^1.2.2",
     "triple-beam": "^1.4.1",
-    "tsx": "^4.19.2",
+    "ts-node": "^10.9.2",
     "underscore": "^1.13.7",
     "url-join": "^5.0.0",
     "whatwg-fetch": "^3.6.20",
@@ -89,6 +91,7 @@
   "devDependencies": {
     "@sentry/types": "^8.36.0",
     "@smithy/util-stream": "^3.2.1",
+    "@types/body-parser": "^1.19.5",
     "@types/bootstrap": "^5.2.10",
     "@types/chai": "^5.0.1",
     "@types/compression": "^1.7.5",
@@ -103,6 +106,7 @@
     "@types/request": "^2.48.12",
     "@types/response-time": "^2.3.8",
     "@types/serve-favicon": "^2.5.7",
+    "@types/shell-quote": "^1.7.5",
     "@types/temp": "^0.9.4",
     "@types/underscore": "^1.13.0",
     "@types/url-join": "^4.0.3",
@@ -141,6 +145,7 @@
     "sass-loader": "^16.0.3",
     "source-map-loader": "^5.0.0",
     "supertest": "^7.0.0",
+    "supervisor": "^0.12.0",
     "terser-webpack-plugin": "^5.3.10",
     "ts-loader": "^9.5.1",
     "typescript": "~5.5",
@@ -162,10 +167,10 @@
     "test-min": "vitest run --exclude test/filter-tests.ts",
     "fix": "npm run lint && npm run format && npm run ts-check",
     "check": "npm run ts-check && npm run lint-check && npm run test-min -- --reporter min",
-    "dev": "cross-env NODE_ENV=DEV node --no-warnings=ExperimentalWarning --import=tsx app.ts",
-    "debugger": "cross-env NODE_ENV=DEV node --import=tsx --inspect-brk app.ts",
-    "debug": "cross-env NODE_ENV=DEV node --no-warnings=ExperimentalWarning --import=tsx app.ts --debug",
-    "start": "npm run webpack && cross-env NODE_ENV=LOCAL node --no-warnings=ExperimentalWarning --import=tsx app.ts",
+    "dev": "cross-env NODE_ENV=DEV node --no-warnings=ExperimentalWarning --loader ts-node/esm app.ts",
+    "debugger": "cross-env NODE_ENV=DEV node --loader ts-node/esm --inspect-brk app.ts",
+    "debug": "cross-env NODE_ENV=DEV node --no-warnings=ExperimentalWarning --loader ts-node/esm app.ts --debug",
+    "start": "npm run webpack && cross-env NODE_ENV=LOCAL node --no-warnings=ExperimentalWarning --loader ts-node/esm app.ts",
     "sentry": "npx -p @sentry/cli sentry-cli",
     "update-browserslist": "npx browserslist@latest -- --update-db",
     "prepare": "husky",
@@ -173,7 +178,7 @@
     "format-files": "prettier --write --ignore-unknown",
     "ts-compile": "tsc",
     "ts-check": "tsc -p ./tsconfig.backend.json --noEmit && tsc -p ./tsconfig.frontend.json --noEmit && tsc -p ./tsconfig.tests.json --noEmit",
-    "webpack": "node --no-warnings=ExperimentalWarning --import=tsx ./node_modules/webpack-cli/bin/cli.js --node-env=production --config webpack.config.esm.ts"
+    "webpack": "node --no-warnings=ExperimentalWarning --loader ts-node/esm ./node_modules/webpack-cli/bin/cli.js --node-env=production --config webpack.config.esm.ts"
   },
   "license": "BSD-2-Clause"
 }
diff --git a/shared/common-utils.ts b/shared/common-utils.ts
index fa52892f0..f4654575a 100644
--- a/shared/common-utils.ts
+++ b/shared/common-utils.ts
@@ -48,7 +48,6 @@ export function intersection<V>(a: V[], b: V[]): V[] {
 export function remove<U, V extends U>(arr: U[], v: V) {
     return arr.filter(item => item !== v) as Exclude<U, V extends null | undefined ? V : never>[];
 }
-
 // https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBAMwK4DsDGMCWEVysAWwgDdgAeAVQBo4A1OUGYFAEwGc4KA+ACgEMoUAFycA2gF0axEbQCUcAN4AoOKrzAYSKLgFQAdAkwAbJlB6YmBOAF4ucC4TgBCa9bjF5fDgFEQaI0gs5NR0DCBMrBwoSEZGcAA+cKhBhijALHAA-KEiaaRQXBIA3EoAvkpKQf4CwHBoOGzwuiI8jVCYKADmCXDRsbLFFfUojXAgNupEpPyCNH1GsiUA9EtqcAB6mUMN8ACeE-hTwDNQNABECBAQZ4tKK2ubFUA
 
 // For Array.prototype.sort
@@ -74,7 +73,6 @@ const EscapeMap = {
     '`': '&#x60;',
 };
 const EscapeRE = new RegExp(`(?:${Object.keys(EscapeMap).join('|')})`, 'g');
-
 export function escapeHTML(text: string) {
     return text.replace(EscapeRE, str => EscapeMap[str as keyof typeof EscapeMap]);
 }
@@ -101,111 +99,3 @@ function splitIntoChunks(s: string, chunkSize: number): string[] {
 export function addDigitSeparator(n: string, digitSeparator: string, chunkSize: number): string {
     return splitIntoChunks(n, chunkSize).join(digitSeparator);
 }
-
-class ArgumentParser {
-    private rest: string;
-    private position: number;
-    private inDoubleQuotes: boolean;
-    private readonly results: string[];
-
-    constructor(str: string) {
-        this.rest = str.trim();
-        this.position = 0;
-        this.inDoubleQuotes = false;
-        this.results = [];
-    }
-
-    private addResult(result: string) {
-        if (this.results[this.position] === undefined) {
-            this.results[this.position] = result;
-        } else {
-            this.results[this.position] += result;
-        }
-    }
-
-    private handleEscapeCharacter() {
-        if (this.rest.length < 2) {
-            this.addResult('\\');
-        } else {
-            if (this.rest.charAt(1) !== '\n') {
-                this.addResult(this.rest.charAt(1));
-            }
-        }
-        this.rest = this.rest.slice(2);
-    }
-
-    private handleSingleQuotes() {
-        let quotePos = this.rest.indexOf("'", 1);
-        if (quotePos === -1) quotePos = this.rest.length;
-        this.addResult(this.rest.slice(1, quotePos));
-        this.rest = this.rest.slice(quotePos + 1);
-    }
-
-    private handleDoubleQuotes() {
-        const match = /["\\]/.exec(this.rest);
-        const matchEnd = match ? match.index : this.rest.length;
-
-        this.addResult(this.rest.slice(0, matchEnd));
-
-        if (match && match[0] === '\\') {
-            this.rest = this.rest.slice(matchEnd);
-            this.handleEscapeCharacter();
-        } else {
-            this.rest = this.rest.slice(matchEnd + 1);
-            this.inDoubleQuotes = false;
-        }
-    }
-
-    private handleWhitespace() {
-        const wsMatch = /^\s+/.exec(this.rest);
-        if (wsMatch) {
-            this.rest = this.rest.slice(wsMatch[0].length);
-            ++this.position;
-        }
-    }
-
-    private handleNonDoubleQuote(nextMatch: RegExpExecArray) {
-        this.addResult(this.rest.slice(0, nextMatch.index));
-        this.rest = this.rest.slice(nextMatch.index);
-
-        switch (nextMatch[0]) {
-            case '\\':
-                this.handleEscapeCharacter();
-                break;
-            case "'":
-                this.handleSingleQuotes();
-                break;
-            case '"':
-                this.rest = this.rest.slice(1);
-                this.inDoubleQuotes = true;
-                break;
-            default:
-                break;
-        }
-    }
-
-    public exec(): string[] {
-        while (this.rest) {
-            if (this.inDoubleQuotes) {
-                this.handleDoubleQuotes();
-                continue;
-            }
-
-            this.handleWhitespace();
-
-            const nextMatch = /[\s'"\\]/.exec(this.rest);
-            if (!nextMatch) {
-                this.addResult(this.rest);
-                this.rest = '';
-                continue;
-            }
-
-            this.handleNonDoubleQuote(nextMatch);
-        }
-        return this.results;
-    }
-}
-
-export function splitArguments(str = ''): string[] {
-    return new ArgumentParser(str).exec();
-}
diff --git a/static/modes/_all.ts b/static/modes/_all.ts
index 6e8a641be..2c6171582 100644
--- a/static/modes/_all.ts
+++ b/static/modes/_all.ts
@@ -57,10 +57,8 @@ import './modula2-mode';
 import './nc-mode';
 import './nim-mode';
 import './ocaml-mode';
-import './odin-mode';
 import './openclc-mode';
 import './ptx-mode';
-import './slang-mode';
 import './spice-mode';
 import './spirv-mode';
 import './tablegen-mode';
diff --git a/static/modes/cppfront-mode.ts b/static/modes/cppfront-mode.ts
index 606e89527..50f65dad4 100644
--- a/static/modes/cppfront-mode.ts
+++ b/static/modes/cppfront-mode.ts
@@ -234,33 +234,25 @@ function definition(): monaco.languages.IMonarchLanguage {
 
         cppfront.at_cpp2_unqualified_id_template_type_keyword = /(?:finally|cpp1_ref|cpp1_rvalue_ref)\b/;
         cppfront.at_cpp2_unqualified_id_template_expression_keyword = /(?:new|unchecked_(?:narrow|cast))\b/;
-        cppfront.at_cpp2_unqualified_id_type_function_keyword =
-            /(?:type_of|static_assert|unchecked_(?:(?:cmp_)(?:less|greater)(?:_eq)?|div|dereference|subscript))\b(?=\s*\()/;
+        cppfront.at_cpp2_unqualified_id_type_function_keyword = /(?:type_of|static_assert)\b(?=\s*\()/;
         cppfront.at_cpp2_unqualified_id_keywords = /(unique|shared)(\.)(new(?=<))/;
         cppfront.at_cpp2_unqualified_id_keyword =
             /@at_cpp2_unqualified_id_template_type_keyword|@at_cpp2_unqualified_id_template_expression_keyword|@at_cpp2_unqualified_id_type_function_keyword|@at_cpp2_unqualified_id_keywords/;
         cppfront.tokenizer.parse_cpp2_unqualified_id_keywords = [
             [
                 /@at_cpp2_unqualified_id_keywords/,
-                [
-                    'keyword',
-                    'delimiter',
-                    {token: 'keyword.$3', switchTo: 'parse_cpp2_single_type_template_argument_list'},
-                ],
+                ['keyword', 'delimiter', {token: 'keyword.$3', switchTo: 'parse_cpp2_template_argument_list'}],
             ],
             [
                 /@at_cpp2_unqualified_id_template_type_keyword(?=<)/,
-                {token: 'keyword.type', switchTo: 'parse_cpp2_single_type_template_argument_list'},
+                {token: 'keyword.type', switchTo: 'parse_cpp2_template_argument_list'},
             ],
             [
                 /@at_cpp2_unqualified_id_template_expression_keyword(?=<)/,
                 {
                     cases: {
-                        '$S2==expression': {
-                            token: 'keyword',
-                            switchTo: 'parse_cpp2_single_type_template_argument_list',
-                        },
-                        '@': {token: 'invalid', switchTo: 'parse_cpp2_single_type_template_argument_list'},
+                        '$S2==expression': {token: 'keyword', switchTo: 'parse_cpp2_template_argument_list'},
+                        '@': {token: 'invalid', switchTo: 'parse_cpp2_template_argument_list'},
                     },
                 },
             ],
@@ -345,9 +337,6 @@ function definition(): monaco.languages.IMonarchLanguage {
         cppfront.tokenizer.parse_cpp2_template_argument_list = [
             [/</, {token: '@rematch', switchTo: 'parse_cpp2_balanced_angles.parse_cpp2_template_argument_seq.$S2'}],
         ];
-        cppfront.tokenizer.parse_cpp2_single_type_template_argument_list = [
-            [/</, {token: '@rematch', switchTo: 'parse_cpp2_balanced_angles.parse_cpp2_type_id'}],
-        ];
 
         cppfront.at_cpp2_id_expression = /::|@at_cpp2_identifier/;
         cppfront.at_cpp2_non_operator_id_expression = /::|@at_cpp2_non_operator_identifier/;
@@ -667,7 +656,7 @@ function definition(): monaco.languages.IMonarchLanguage {
 
     function setupDeclarationParsers() {
         cppfront.at_cpp2_builtin_meta_function =
-            /(?:ordered|weakly_ordered|partially_ordered|copyable|basic_value|value|weakly_ordered_value|partially_ordered_value|struct|hashable|interface|polymorphic_base|enum|flag_enum|union|noisy|regex|cpp1_rule_of_zero|print)\b/;
+            /(?:ordered|weakly_ordered|partially_ordered|copyable|basic_value|value|weakly_ordered_value|partially_ordered_value|struct|hashable|interface|polymorphic_base|enum|flag_enum|union|regex|cpp1_rule_of_zero|print)\b/;
         cppfront.tokenizer.parse_cpp2_meta_functions_list = [
             [/[^@]/, '@rematch', '@pop'],
             [
@@ -824,7 +813,6 @@ function definition(): monaco.languages.IMonarchLanguage {
         cppfront.tokenizer.parse_cpp2_declaration_head = [
             {include: '@whitespace'},
             [/@at_cpp2_access_specifier/, 'keyword'],
-            [/guard(?=@at_cpp2_non_operator_identifier?\s*@at_cpp2_unnamed_declaration_head)/, 'keyword'],
             [/@at_cpp2_identifier/, '@rematch', 'parse_cpp2_identifier.$S2'],
             [/\.\.\./, 'delimiter.ellipsis'],
             [
@@ -860,7 +848,7 @@ function definition(): monaco.languages.IMonarchLanguage {
             },
         ],
         [/{/, 'delimiter.curly', 'root.cpp1'],
-        [/}/, 'delimiter.curly', 'root'],
+        [/}/, 'delimiter.curly', '@pop'],
     );
 
     return cppfront;
diff --git a/static/modes/odin-mode.ts b/static/modes/odin-mode.ts
deleted file mode 100644
index 46a2d6610..000000000
--- a/static/modes/odin-mode.ts
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (c) 2024, Compiler Explorer Authors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//     * Redistributions of source code must retain the above copyright notice,
-//       this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in the
-//       documentation and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-import * as monaco from 'monaco-editor';
-
-function definition(): monaco.languages.IMonarchLanguage {
-    // Odin language definition
-    return {
-        defaultToken: 'invalid',
-
-        keywords: [
-            'import',
-            'export',
-            'foreign',
-            'package',
-            'if',
-            'else',
-            'when',
-            'for',
-            'in',
-            'defer',
-            'switch',
-            'return',
-            'const',
-            'fallthrough',
-            'break',
-            'continue',
-            'case',
-            'vector',
-            'static',
-            'dynamic',
-            'using',
-            'do',
-            'inline',
-            'no_inline',
-            'asm',
-            'yield',
-            'await',
-            'distinct',
-            'context',
-            'nil',
-            'true',
-            'false',
-            'type',
-            'var',
-            'macro',
-            'struct',
-            'enum',
-            'union',
-            'set',
-            'typeid',
-            'cast',
-            'transmute',
-            'auto_cast',
-            'proc',
-        ],
-
-        typeKeywords: [
-            'bool',
-            'byte',
-            'b8',
-            'b16',
-            'b32',
-            'b64',
-            'int',
-            'i8',
-            'i16',
-            'i32',
-            'i64',
-            'i128',
-            'uint',
-            'u8',
-            'u16',
-            'u32',
-            'u64',
-            'u128',
-            'uintptr',
-            'i16le',
-            'i32le',
-            'i64le',
-            'i128le',
-            'u16le',
-            'u32le',
-            'u64le',
-            'u128le',
-            'i16be',
-            'i32be',
-            'i64be',
-            'i128be',
-            'u16be',
-            'u32be',
-            'u64be',
-            'u128be',
-            'f16',
-            'f32',
-            'f64',
-            'f16le',
-            'f32le',
-            'f64le',
-            'f16be',
-            'f32be',
-            'f64be',
-            'complex32',
-            'complex64',
-            'complex128',
-            'quaternion64',
-            'quaternion128',
-            'quaternion256',
-            'rune',
-            'string',
-            'cstring',
-            'rawptr',
-            'any',
-            'bit_set',
-            'bit_field',
-            'map',
-        ],
-
-        operators: [
-            '@',
-            '|',
-            '!',
-            ':',
-            '+',
-            '-',
-            '->',
-            '*',
-            '/',
-            '<',
-            '<<',
-            '>',
-            '>>',
-            '~',
-            '|=',
-            '!=',
-            ':=',
-            '+=',
-            '-=',
-            '->=',
-            '*=',
-            '/=',
-            '<=',
-            '<<=',
-            '>=',
-            '>>=',
-            '~=',
-            '=',
-            ':',
-            '::',
-            '..',
-        ],
-
-        // we include these common regular expressions
-        symbols: /[=><!~?:&|+\-*/^%]+/,
-        escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
-
-        // The main tokenizer for our languages
-        tokenizer: {
-            root: [
-                // identifiers and keywords
-                [
-                    /[a-z_$][\w$]*/,
-                    {cases: {'@typeKeywords': 'keyword', '@keywords': 'keyword', '@default': 'identifier'}},
-                ],
-                [/---$/, {cases: {'@typeKeywords': 'keyword', '@keywords': 'keyword', '@default': 'identifier'}}],
-
-                // whitespace
-                {include: '@whitespace'},
-
-                // delimiters and operators
-                [/[{}()[\]]/, '@brackets'],
-                [/[<>](?!@symbols)/, '@brackets'],
-
-                [/@symbols/, {cases: {'@operators': 'type', '@default': ''}}],
-
-                // # annotations.
-                [/#\s*[a-zA-Z_$][\w$]*/, {token: 'annotation', log: 'annotation token: $0'}],
-                [/@\(\s*[a-zA-Z_=$][\w=$]*\)/, {token: 'annotation', log: 'annotation token: $0'}],
-
-                // numbers
-                [/\d*\.\d+([eE][-+]?\d+)?/, 'number.float'],
-                [/0[xX][0-9a-fA-F]+/, 'number.hex'],
-                [/\d+/, 'number'],
-
-                // delimiter: after number because of .\d floats
-                [/[;,.]/, 'delimiter'],
-
-                // strings
-                [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string
-                [/"/, {token: 'string.quote', bracket: '@open', next: '@string'}],
-
-                [/'[^\\']'/, 'string'],
-                [/(')(@escapes)(')/, ['string', 'string.escape', 'string']],
-                [/'/, 'string.invalid'],
-            ],
-
-            comment: [
-                [/[^/*]+/, 'comment'],
-                [/\/\*/, 'comment', '@push'], // nested comment
-                ['\\*/', 'comment', '@pop'],
-                [/[/*]/, 'comment'],
-            ],
-
-            string: [
-                [/[^\\"]+/, 'string'],
-                [/@escapes/, 'string.escape'],
-                [/\\./, 'string.escape.invalid'],
-                [/"/, {token: 'string.quote', bracket: '@close', next: '@pop'}],
-            ],
-
-            whitespace: [
-                [/[ \t\r\n]+/, 'white'],
-                [/\/\*/, 'comment', '@comment'],
-                [/\/\/.*$/, 'comment'],
-            ],
-        },
-    };
-}
-
-monaco.languages.register({id: 'odin'});
-monaco.languages.setMonarchTokensProvider('odin', definition());
-
-export {};
diff --git a/static/modes/slang-mode.ts b/static/modes/slang-mode.ts
deleted file mode 100644
index 02b607af5..000000000
--- a/static/modes/slang-mode.ts
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright (c) 2024, Compiler Explorer Authors
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//     * Redistributions of source code must retain the above copyright notice,
-//       this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in the
-//       documentation and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-
-import $ from 'jquery';
-
-import * as monaco from 'monaco-editor';
-// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore  "Could not find a declaration file"
-import * as cpp from 'monaco-editor/esm/vs/basic-languages/cpp/cpp';
-
-function definition(): monaco.languages.IMonarchLanguage {
-    const slang = $.extend(true, {}, cpp.language);
-
-    function addKeywords(keywords: string[]) {
-        for (let i = 0; i < keywords.length; ++i) {
-            slang.keywords.push(keywords[i]);
-        }
-    }
-
-    function vectorMatrixTypes(basename: string) {
-        const types: string[] = [];
-        for (let i = 1; i !== 5; ++i) {
-            for (let j = 1; j !== 5; ++j) {
-                types.push(`${basename}${i}x${j}`);
-            }
-            types.push(`${basename}${i}`);
-        }
-        return types;
-    }
-
-    addKeywords(vectorMatrixTypes('bool'));
-    addKeywords(vectorMatrixTypes('uint'));
-    addKeywords(vectorMatrixTypes('float'));
-    addKeywords(vectorMatrixTypes('int'));
-
-    function resource(name: string) {
-        return [name, `RW${name}`];
-    }
-
-    addKeywords(resource('Buffer'));
-    addKeywords(resource('Texture1D'));
-    addKeywords(resource('Texture1DArray'));
-    addKeywords(resource('Texture2D'));
-    addKeywords(resource('Texture2DArray'));
-    addKeywords(resource('Texture3D'));
-    addKeywords(resource('TextureCube'));
-    addKeywords(resource('TextureCubeArray'));
-    addKeywords(resource('Texture2DMS'));
-    addKeywords(resource('Texture2DMSArray'));
-    addKeywords(resource('ByteAddressBuffer'));
-    addKeywords(resource('StructuredBuffer'));
-    addKeywords(resource('ConstantBuffer'));
-
-    addKeywords([
-        // Additional resource types
-        'SamplerState',
-        'SamplerComparisonState',
-        'AppendStructuredBuffer',
-        'ConsumeStructuredBuffer',
-        'ParameterBlock',
-        'Ptr',
-        'GLSLShaderStorageBuffer',
-        'Atomic',
-        'WTexture2D',
-
-        // non-C style statement words
-        'throws',
-        'in',
-        'out',
-        'inout',
-        'vector',
-        'matrix',
-        'uint',
-        'ref',
-        '__subscript',
-        '__init',
-        'get',
-        'set',
-        'typealias',
-        'uniform',
-        'groupshared',
-        'extension',
-        'associatedtype',
-        'This',
-        '__generic',
-        '__exported',
-        'import',
-        'discard',
-        'defer',
-        'cbuffer',
-        'tbuffer',
-        'func',
-        'is',
-        'as',
-        'none',
-        'functype',
-        'alignof',
-        '__target_switch',
-        '__intrinsic_asm',
-        'each',
-        'expand',
-        'let',
-        'var',
-        'no_diff',
-        'dynamic_uniform',
-        'fwd_diff',
-        'bwd_diff',
-        'module',
-        'implementing',
-        '__include',
-        '__dispatch_kernel',
-        'row_major',
-        'column_major',
-        'nointerpolation',
-        'snorm',
-        'unorm',
-        'globallycoherent',
-        'layout',
-        'numthreads',
-
-        // Intrinsic functions
-        'abort',
-        'abs',
-        'acos',
-        'all',
-        'any',
-        'asin',
-        'asint',
-        'asuint',
-        'atan',
-        'atan2',
-        'ceil',
-        'clamp',
-        'clip',
-        'cos',
-        'cosh',
-        'countbits',
-        'cross',
-        'ddx',
-        'ddx_coarse',
-        'ddx_fine',
-        'ddy',
-        'ddy_coarse',
-        'ddy_fine',
-        'degrees',
-        'determinant',
-        'distance',
-        'dot',
-        'dst',
-        'errorf',
-        'exp',
-        'exp2',
-        'f16tof32',
-        'f32tof16',
-        'faceforward',
-        'firstbithigh',
-        'firstbitlow',
-        'floor',
-        'fma',
-        'fmod',
-        'frac',
-        'frexp',
-        'fwidth',
-        'isfinite',
-        'isinf',
-        'isnan',
-        'ldexp',
-        'length',
-        'lerp',
-        'lit',
-        'log',
-        'log10',
-        'log2',
-        'mad',
-        'max',
-        'min',
-        'modf',
-        'msad4',
-        'mul',
-        'noise',
-        'normalize',
-        'pow',
-        'radians',
-        'rcp',
-        'reflect',
-        'refract',
-        'reversebits',
-        'round',
-        'rsqrt',
-        'saturate',
-        'sign',
-        'sin',
-        'sincos',
-        'sinh',
-        'smoothstep',
-        'sqrt',
-        'step',
-        'tan',
-        'tanh',
-        'transpose',
-        'trunc',
-
-        // vulkan semantic names
-        'vk',
-        'binding',
-        'shader',
-        'spirv_asm',
-
-        // HLSL semantic names
-        'register',
-        'packoffset',
-        'read',
-        'write',
-        'SV_ClipDistance',
-        'SV_CullDistance',
-        'SV_Coverage',
-        'SV_Depth',
-        'SV_DepthGreaterEqual',
-        'SV_DepthLessEqual',
-        'SV_DispatchThreadID',
-        'SV_DomainLocation',
-        'SV_GroupID',
-        'SV_GroupIndex',
-        'SV_GroupThreadID',
-        'SV_GSInstanceID',
-        'SV_InnerCoverage',
-        'SV_InsideTessFactor',
-        'SV_InstanceID',
-        'SV_IsFrontFace',
-        'SV_OutputControlPointID',
-        'SV_Position',
-        'SV_PointSize',
-        'SV_PrimitiveID',
-        'SV_RenderTargetArrayIndex',
-        'SV_SampleIndex',
-        'SV_StencilRef',
-        'SV_Target',
-        'SV_TessFactor',
-        'SV_VertexID',
-        'SV_ViewID',
-        'SV_ViewportArrayIndex',
-        'SV_ShadingRate',
-    ]);
-
-    return slang;
-}
-
-monaco.languages.register({id: 'slang'});
-monaco.languages.setMonarchTokensProvider('slang', definition());
-
-export {};
diff --git a/static/panes/compiler.ts b/static/panes/compiler.ts
index fecc495c3..cf984b3e0 100644
--- a/static/panes/compiler.ts
+++ b/static/panes/compiler.ts
@@ -78,7 +78,7 @@ import {CompilerShared} from '../compiler-shared.js';
 import {SentryCapture} from '../sentry.js';
 import {LLVMIrBackendOptions} from '../compilation/ir.interfaces.js';
 import {InstructionSet} from '../instructionsets.js';
-import {splitArguments, escapeHTML} from '../../shared/common-utils.js';
+import {escapeHTML} from '../../shared/common-utils.js';
 import {CompilerVersionInfo, setCompilerVersionPopoverForPane} from '../widgets/compiler-version-info.js';
 import {ClangirBackendOptions} from '../compilation/clangir.interfaces.js';
 import {LanguageKey} from '../languages.interfaces.js';
@@ -1205,7 +1205,7 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
             if (content.componentState.id === this.id) {
                 tools.push({
                     id: content.componentState.toolId,
-                    args: splitArguments(content.componentState.args),
+                    args: content.componentState.args,
                     stdin: content.componentState.stdin,
                 });
             }
@@ -1225,7 +1225,7 @@ export class Compiler extends MonacoPane<monaco.editor.IStandaloneCodeEditor, Co
         if (newToolSettings) {
             tools.push({
                 id: newToolSettings.toolId,
-                args: splitArguments(newToolSettings.args),
+                args: newToolSettings.args ? newToolSettings.args.split('\n') : [],
                 stdin: newToolSettings.stdin ?? '',
             });
         }
diff --git a/static/widgets/site-templates-widget.ts b/static/widgets/site-templates-widget.ts
index 17dcc8ec2..86a51e070 100644
--- a/static/widgets/site-templates-widget.ts
+++ b/static/widgets/site-templates-widget.ts
@@ -24,7 +24,7 @@
 
 import $ from 'jquery';
 
-import {SiteTemplateResponse, UserSiteTemplate} from '../../types/features/site-templates.interfaces.js';
+import {SiteTemplatesType, UserSiteTemplate} from '../../types/features/site-templates.interfaces.js';
 import {assert, unwrap, unwrapString} from '../assert.js';
 import {Settings} from '../settings.js';
 import * as url from '../url.js';
@@ -38,7 +38,7 @@ class SiteTemplatesWidget {
     private readonly img: HTMLImageElement;
     private readonly siteTemplateScreenshots: any;
     private readonly alertSystem: Alert;
-    private templatesConfig: null | SiteTemplateResponse = null;
+    private templatesConfig: null | SiteTemplatesType = null;
     private populated = false;
     constructor(
         siteTemplateScreenshots: any,
@@ -77,7 +77,7 @@ class SiteTemplatesWidget {
     }
     async getTemplates() {
         if (this.templatesConfig === null) {
-            this.templatesConfig = await new Promise<SiteTemplateResponse>((resolve, reject) => {
+            this.templatesConfig = await new Promise<SiteTemplatesType>((resolve, reject) => {
                 $.getJSON(window.location.origin + window.httpRoot + 'api/siteTemplates', resolve);
             });
         }
@@ -104,7 +104,7 @@ class SiteTemplatesWidget {
     async setDefaultPreview() {
         const templatesConfig = await this.getTemplates(); // by the time this is called it will be cached
         const first = Object.entries(templatesConfig.templates)[0][0]; // preview the first entry
-        this.img.src = this.getAsset(first);
+        this.img.src = this.getAsset(first.replace(/[^a-z]/gi, ''));
     }
     populateUserTemplates() {
         const userTemplates: Record<string, UserSiteTemplate> = JSON.parse(localStorage.get('userSiteTemplates', '{}'));
@@ -139,7 +139,9 @@ class SiteTemplatesWidget {
             // Note: Trusting the server-provided data attribute
             siteTemplatesList.append(
                 `<li>` +
-                    `<div class="title" data-data="${data}" data-name="${name}">${escapeHTML(name)}</div>` +
+                    `<div class="title" data-data="${data}" data-name="${name.replace(/[^a-z]/gi, '')}">${escapeHTML(
+                        name,
+                    )}</div>` +
                     `</li>`,
             );
         }
diff --git a/types/compilation/compilation.interfaces.ts b/types/compilation/compilation.interfaces.ts
index 5afde6e75..9a30ce038 100644
--- a/types/compilation/compilation.interfaces.ts
+++ b/types/compilation/compilation.interfaces.ts
@@ -49,9 +49,6 @@ export type ActiveTool = {
     stdin: string;
 };
 
-// This is a legacy type that allows a single string to be passed as args but is otherwise identical to ActiveTool:
-export type LegacyCompatibleActiveTool = Exclude<ActiveTool, 'args'> & {args: string | string[]};
-
 export type UnparsedExecutionParams = {
     args?: string | string[];
     stdin?: string;
diff --git a/types/features/site-templates.interfaces.ts b/types/features/site-templates.interfaces.ts
index a58264b47..4f8b51023 100644
--- a/types/features/site-templates.interfaces.ts
+++ b/types/features/site-templates.interfaces.ts
@@ -23,21 +23,10 @@
 // POSSIBILITY OF SUCH DAMAGE.
 
 export type SiteTemplatesMetadata = {
-    screenshot_dimensions: {
-        width: number;
-        height: number;
-    };
+    screenshot_dimensions?: string;
 };
 
-export type SiteTemplateConfiguration = {
-    meta: SiteTemplatesMetadata;
-    templates: {
-        name: string;
-        reference: string;
-    }[];
-};
-
-export type SiteTemplateResponse = {
+export type SiteTemplatesType = {
     meta: SiteTemplatesMetadata;
     templates: Record<string, string>;
 };
diff --git a/types/languages.interfaces.ts b/types/languages.interfaces.ts
index d98084846..2ad7b675d 100644
--- a/types/languages.interfaces.ts
+++ b/types/languages.interfaces.ts
@@ -73,7 +73,6 @@ export type LanguageKey =
     | 'modula2'
     | 'nim'
     | 'ocaml'
-    | 'odin'
     | 'objc'
     | 'objc++'
     | 'openclc'
@@ -84,7 +83,6 @@ export type LanguageKey =
     | 'ruby'
     | 'rust'
     | 'scala'
-    | 'slang'
     | 'solidity'
     | 'spice'
     | 'spirv'
diff --git a/views/popups/library-selection.pug b/views/popups/library-selection.pug
index e765fda84..604c746b6 100644
--- a/views/popups/library-selection.pug
+++ b/views/popups/library-selection.pug
@@ -20,10 +20,9 @@
                 .col-lg.libs-how-to-use
                   | To add a library, search for one you want and select the version in the dropdown. Or if you have
                   | favorited it before, just click the library name in the Favorites section. Libraries are
-                  | installed using the #[a(href="https://conan.io/" target="_blank") conan.io] package manager.
-                  |
-                  em Please note that Windows-based compilers currently do not support libraries. See
-                  |  #[a(href="https://github.com/compiler-explorer/compiler-explorer/issues/7194" target="_blank") this Github issue].
+                  | installed |using the #[a(href="https://conan.io/", target="_blank") conan.io] package manager,
+                  | except for Microsoft compilers, where #[a(href="https://vcpkg.io/", target="_blank") vcpkg] is
+                  | used.
               .row
                 .col-lg &nbsp;
               .row


Test patch:
diff --git a/.github/workflows/test-and-deploy.yml b/.github/workflows/test-and-deploy.yml
index 620d1bbb2..86df023c1 100644
--- a/.github/workflows/test-and-deploy.yml
+++ b/.github/workflows/test-and-deploy.yml
@@ -37,12 +37,10 @@ jobs:
         uses: actions/checkout@v4
         with:
           fetch-depth: 0
-      # We use 18.19.0 because it is the first backport to support --import
-      # https://raw.githubusercontent.com/nodejs/node/main/doc/changelogs/CHANGELOG_V18.md
-      - name: Use Node.js 18.19.0
+      - name: Use Node.js 18.14.1
         uses: actions/setup-node@v4
         with:
-          node-version: 18.19.0
+          node-version: 18.14.1
           check-latest: false
           cache: npm
       - name: Install prerequisites
diff --git a/lib/compilers/fake-for-test.ts b/lib/compilers/fake-for-test.ts
index 528e4fc1d..699e010d6 100644
--- a/lib/compilers/fake-for-test.ts
+++ b/lib/compilers/fake-for-test.ts
@@ -98,7 +98,6 @@ export class FakeCompiler {
                 backendOptions: backendOptions,
                 filters: filters,
                 files: files,
-                tools: tools,
             },
         };
 
diff --git a/test/base-compiler-tests.ts b/test/base-compiler-tests.ts
index 39aa320f2..be1010017 100644
--- a/test/base-compiler-tests.ts
+++ b/test/base-compiler-tests.ts
@@ -31,7 +31,7 @@ import {ClangCompiler} from '../lib/compilers/clang.js';
 import {RustCompiler} from '../lib/compilers/rust.js';
 import {Win32Compiler} from '../lib/compilers/win32.js';
 import * as props from '../lib/properties.js';
-import {splitArguments} from '../shared/common-utils.js';
+import {splitArguments} from '../lib/utils.js';
 import {CompilerOverrideType, ConfiguredOverrides} from '../types/compilation/compiler-overrides.interfaces.js';
 import {CompilerInfo} from '../types/compiler.interfaces.js';
 
diff --git a/test/common-utils-tests.ts b/test/common-utils-tests.ts
index 1c21da901..3b581fa83 100644
--- a/test/common-utils-tests.ts
+++ b/test/common-utils-tests.ts
@@ -24,7 +24,7 @@
 
 import {describe, expect, it} from 'vitest';
 
-import {addDigitSeparator, escapeHTML, splitArguments} from '../shared/common-utils.js';
+import {addDigitSeparator, escapeHTML} from '../shared/common-utils.js';
 
 describe('HTML Escape Test Cases', () => {
     it('should prevent basic injection', () => {
@@ -57,113 +57,3 @@ describe('digit separator', () => {
         expect(addDigitSeparator('-123456789', '_', 3)).toEqual('-123_456_789');
     });
 });
-
-describe('argument splitting', () => {
-    it('should handle empty strings', () => {
-        expect(splitArguments('')).toEqual([]);
-    });
-    it('should handle purely whitespace strings', () => {
-        expect(splitArguments('    ')).toEqual([]);
-    });
-    it('should handle normal things', () => {
-        expect(splitArguments('-hello --world etc --std=c++20')).toEqual(['-hello', '--world', 'etc', '--std=c++20']);
-    });
-
-    it('should handle hash chars', () => {
-        expect(splitArguments('-Wno#warnings -Wno-#pragma-messages')).toEqual([
-            '-Wno#warnings',
-            '-Wno-#pragma-messages',
-        ]);
-    });
-
-    it('should handle doublequoted args', () => {
-        expect(splitArguments('--hello "-world etc"')).toEqual(['--hello', '-world etc']);
-    });
-
-    it('should handle singlequoted args', () => {
-        expect(splitArguments("--hello '-world etc'")).toEqual(['--hello', '-world etc']);
-    });
-
-    it('should handle mismatched doublequoted args', () => {
-        expect(splitArguments('--hello "-world etc')).toEqual(['--hello', '-world etc']);
-    });
-
-    it('should handle mismatched singlequoted args', () => {
-        expect(splitArguments("--hello '-world etc")).toEqual(['--hello', '-world etc']);
-    });
-
-    it('should handle hashes at the beginning of words', () => {
-        expect(splitArguments('hello #veryfancy etc')).toEqual(['hello', '#veryfancy', 'etc']);
-    });
-
-    it('should handle empty arguments', () => {
-        expect(splitArguments('nothing "" is lost \'\'')).toEqual(['nothing', '', 'is', 'lost', '']);
-    });
-
-    it('should handle weird characters', () => {
-        expect(splitArguments('hello | moose | \\n < yay & \n\t\nmoo')).toEqual([
-            'hello',
-            '|',
-            'moose',
-            '|',
-            'n',
-            '<',
-            'yay',
-            '&',
-            'moo',
-        ]);
-    });
-
-    it('should handle escaped backslashes', () => {
-        expect(splitArguments('hello \\\\ moose')).toEqual(['hello', '\\', 'moose']);
-    });
-
-    it('should handle mismatched backslashes', () => {
-        expect(splitArguments('hello \\')).toEqual(['hello', '\\']);
-        expect(splitArguments('hello world\\')).toEqual(['hello', 'world\\']);
-    });
-    it('should handle mismatched backslashes in quotes', () => {
-        expect(splitArguments('hello "\\')).toEqual(['hello', '\\']);
-    });
-
-    it('should handle escaped quotes', () => {
-        expect(splitArguments('hi \\"mum\\"')).toEqual(['hi', '"mum"']);
-        expect(splitArguments('hi "\\"mum\\""')).toEqual(['hi', '"mum"']);
-        expect(splitArguments("hi \\'mum\\'")).toEqual(['hi', "'mum'"]);
-    });
-
-    it('should do something sane in the face of escaped quotes in quotes', () => {
-        // Not really valid input, bash sees this as a bunch of abutting single-quotes, unterminated.
-        // But this makes as much sense as anything and so I've added it to lock in the behaviour.
-        expect(splitArguments("hi '\\'mum\\''")).toEqual(['hi', "\\mum'"]);
-    });
-
-    it('should handle abutting quotes', () => {
-        expect(splitArguments('well "hello""there"')).toEqual(['well', 'hellothere']);
-        expect(splitArguments('well "hello"\'there\'')).toEqual(['well', 'hellothere']);
-    });
-
-    it('should ignore escaped hashes etc', () => {
-        expect(splitArguments('hello \\#veryfancy etc')).toEqual(['hello', '#veryfancy', 'etc']);
-    });
-
-    it('should handle multiple spaces', () => {
-        expect(splitArguments('hello    world')).toEqual(['hello', 'world']);
-    });
-
-    it('should handle escaped spaces', () => {
-        expect(splitArguments('hello\\ there')).toEqual(['hello there']);
-    });
-
-    it('should handle mixed quotes and spaces', () => {
-        expect(splitArguments('"hello \'world\' there"')).toEqual(["hello 'world' there"]);
-    });
-
-    it('should handle quotes containing spaces', () => {
-        expect(splitArguments('hello "   " world')).toEqual(['hello', '   ', 'world']);
-    });
-
-    it('should handle multiple escapes in quotes', () => {
-        expect(splitArguments('"hello \\"world\\" \\\\"')).toEqual(['hello "world" \\']);
-    });
-});
diff --git a/test/handlers/api-tests.ts b/test/handlers/api-tests.ts
index 157c36b58..c9adbc649 100644
--- a/test/handlers/api-tests.ts
+++ b/test/handlers/api-tests.ts
@@ -22,6 +22,7 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 // POSSIBILITY OF SUCH DAMAGE.
 
+import bodyParser from 'body-parser';
 import express from 'express';
 import request from 'supertest';
 import {beforeAll, describe, expect, it} from 'vitest';
@@ -96,7 +97,7 @@ describe('API handling', () => {
             'default',
             {ceProps: (key, def) => def} as CompilationEnvironment,
         );
-        app.use(express.json());
+        app.use(bodyParser.json());
         app.use('/api', apiHandler.handle);
         apiHandler.setCompilers(compilers);
         apiHandler.setLanguages(languages);
diff --git a/test/handlers/compile-tests.ts b/test/handlers/compile-tests.ts
index fb016d112..703b62ef5 100644
--- a/test/handlers/compile-tests.ts
+++ b/test/handlers/compile-tests.ts
@@ -22,13 +22,14 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 // POSSIBILITY OF SUCH DAMAGE.
 
-import express, {Express} from 'express';
+import bodyParser from 'body-parser';
+import express from 'express';
 import request from 'supertest';
 import {beforeAll, describe, expect, it} from 'vitest';
 
 import {CompileHandler, SetTestMode} from '../../lib/handlers/compile.js';
 import {fakeProps} from '../../lib/properties.js';
-import {ActiveTool, BypassCache, LegacyCompatibleActiveTool} from '../../types/compilation/compilation.interfaces.js';
+import {BypassCache} from '../../types/compilation/compilation.interfaces.js';
 import {makeCompilationEnvironment} from '../utils.js';
 
 SetTestMode();
@@ -40,17 +41,17 @@ const languages = {
 };
 
 describe('Compiler tests', () => {
-    let app: Express, compileHandler;
+    let app, compileHandler;
 
     beforeAll(() => {
         const compilationEnvironment = makeCompilationEnvironment({languages});
         compileHandler = new CompileHandler(compilationEnvironment, fakeProps({}));
 
-        const textParser = express.text({type: () => true});
-        const formParser = express.urlencoded({extended: false});
+        const textParser = bodyParser.text({type: () => true});
+        const formParser = bodyParser.urlencoded({extended: false});
 
         app = express();
-        app.use(express.json());
+        app.use(bodyParser.json());
 
         app.post('/noscript/compile', formParser, compileHandler.handle.bind(compileHandler));
         app.post('/:compiler/compile', textParser, compileHandler.handle.bind(compileHandler));
@@ -226,7 +227,6 @@ describe('Compiler tests', () => {
                         filters: {},
                         options: [],
                         source: 'I am a program',
-                        tools: [],
                     },
                     stderr: [{text: 'Something from stderr'}],
                     stdout: [{text: 'Something from stdout'}],
@@ -245,31 +245,6 @@ describe('Compiler tests', () => {
             expect(res.body.input.filters).toEqual({a: true, b: true, c: true});
         });
 
-        it('parses tools with array args', async () => {
-            await setFakeResult();
-            const res = await makeFakeJson('I am a program', {
-                tools: [{id: 'tool', args: ['one', 'two', 'and three'], stdin: ''} as ActiveTool],
-            })
-                .expect('Content-Type', /json/)
-                .expect(200);
-            expect(res.body.input.tools).toEqual([{id: 'tool', args: ['one', 'two', 'and three'], stdin: ''}]);
-        });
-        it('parses tools with string args', async () => {
-            await setFakeResult();
-            const res = await makeFakeJson('I am a program', {
-                tools: [{id: 'tool', args: 'one two "and three" and string', stdin: ''} as LegacyCompatibleActiveTool],
-            })
-                .expect('Content-Type', /json/)
-                .expect(200);
-            expect(res.body.input.tools).toEqual([
-                {
-                    id: 'tool',
-                    args: ['one', 'two', 'and three', 'and', 'string'],
-                    stdin: '',
-                },
-            ]);
-        });
-
         it('parses extra files', async () => {
             await setFakeResult();
             const res = await makeFakeWithExtraFilesJson(
diff --git a/test/handlers/site-templates-tests.ts b/test/handlers/site-templates-tests.ts
index e5bb9c4eb..c1875add4 100644
--- a/test/handlers/site-templates-tests.ts
+++ b/test/handlers/site-templates-tests.ts
@@ -16,8 +16,7 @@ describe('Site Templates Backend', () => {
     it('should load site templates properly', async () => {
         const templates = await getSiteTemplates();
         // not super comprehensive
-        expect(templates.meta.screenshot_dimensions).toHaveProperty('width');
-        expect(templates.meta.screenshot_dimensions).toHaveProperty('height');
+        expect(templates.meta).toHaveProperty('meta.screenshot_dimensions');
         expect(Object.entries(templates.templates).length).toBeTruthy();
     });
 
diff --git a/test/utils-tests.ts b/test/utils-tests.ts
index d47cfbd8e..89ce583ec 100644
--- a/test/utils-tests.ts
+++ b/test/utils-tests.ts
@@ -535,3 +535,39 @@ describe('safe semver', () => {
         expect(utils.asSafeVer('123.456.789 TEXT')).toEqual('123.456.789');
     });
 });
+
+describe('argument splitting', () => {
+    it('should handle normal things', () => {
+        expect(utils.splitArguments('-hello --world etc --std=c++20')).toEqual([
+            '-hello',
+            '--world',
+            'etc',
+            '--std=c++20',
+        ]);
+    });
+
+    it('should handle hash chars', () => {
+        expect(utils.splitArguments('-Wno#warnings -Wno-#pragma-messages')).toEqual([
+            '-Wno#warnings',
+            '-Wno-#pragma-messages',
+        ]);
+    });
+
+    it('should handle doublequoted args', () => {
+        expect(utils.splitArguments('--hello "-world etc"')).toEqual(['--hello', '-world etc']);
+    });
+
+    it('should handle singlequoted args', () => {
+        expect(utils.splitArguments("--hello '-world etc'")).toEqual(['--hello', '-world etc']);
+    });
+
+    it('should handle cheekyness part 1', () => {
+        /* eslint-disable no-useless-escape */
+        expect(utils.splitArguments('hello #veryfancy etc')).toEqual(['hello', '#veryfancy', 'etc']);
+        /* eslint-enable no-useless-escape */
+    });
+
+    it('should handle cheekyness part 2', () => {
+        expect(utils.splitArguments('hello \\#veryfancy etc')).toEqual(['hello', '\\']);
+    });
+});