This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Benjamin Admin 21a844cb8a fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.

This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).

Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:51:32 +01:00

299 lines
9.1 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>{{{ PRODUCT_NAME }}}</title>
<!-- PWA Meta Tags -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="theme-color" content="#1a1a2e">
<!-- Favicon -->
<link rel="shortcut icon" href="TemplateData/favicon.ico">
<link rel="apple-touch-icon" href="TemplateData/icon-192.png">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
overflow: hidden;
background: #1a1a2e;
}
#unity-container {
position: absolute;
width: 100%;
height: 100%;
}
#unity-canvas {
width: 100%;
height: 100%;
background: #1a1a2e;
}
#unity-loading-bar {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 80%;
max-width: 400px;
}
#unity-logo {
text-align: center;
margin-bottom: 20px;
}
#unity-logo img {
max-width: 200px;
}
#unity-title {
color: #fff;
font-family: 'Segoe UI', Arial, sans-serif;
font-size: 24px;
text-align: center;
margin-bottom: 20px;
}
#unity-progress-bar-empty {
width: 100%;
height: 18px;
background: #333;
border-radius: 9px;
overflow: hidden;
}
#unity-progress-bar-full {
width: 0%;
height: 100%;
background: linear-gradient(90deg, #4CAF50, #8BC34A);
transition: width 0.3s ease;
}
#unity-loading-text {
color: #aaa;
font-family: 'Segoe UI', Arial, sans-serif;
font-size: 14px;
text-align: center;
margin-top: 10px;
}
#unity-warning {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background: #fff;
padding: 20px;
border-radius: 10px;
text-align: center;
display: none;
}
#unity-footer {
position: absolute;
bottom: 10px;
width: 100%;
text-align: center;
}
#unity-fullscreen-button {
background: transparent;
border: none;
cursor: pointer;
padding: 10px;
}
#unity-fullscreen-button img {
width: 38px;
height: 38px;
opacity: 0.7;
transition: opacity 0.3s;
}
#unity-fullscreen-button:hover img {
opacity: 1;
}
.hidden {
display: none !important;
}
/* Mobile Optimierungen */
@media (max-width: 768px) {
#unity-title {
font-size: 18px;
}
#unity-loading-bar {
width: 90%;
}
}
</style>
</head>
<body>
<div id="unity-container">
<!-- Loading Screen -->
<div id="unity-loading-bar">
<div id="unity-logo">
<img src="TemplateData/logo.png" alt="Breakpilot Drive">
</div>
<div id="unity-title">{{{ PRODUCT_NAME }}}</div>
<div id="unity-progress-bar-empty">
<div id="unity-progress-bar-full"></div>
</div>
<div id="unity-loading-text">Lade...</div>
</div>
<!-- Game Canvas -->
<canvas id="unity-canvas" tabindex="-1"></canvas>
<!-- Warning Message -->
<div id="unity-warning"></div>
<!-- Footer -->
<div id="unity-footer">
<button id="unity-fullscreen-button" title="Vollbild">
<img src="TemplateData/fullscreen-button.png" alt="Vollbild">
</button>
</div>
</div>
<script>
var container = document.querySelector("#unity-container");
var canvas = document.querySelector("#unity-canvas");
var loadingBar = document.querySelector("#unity-loading-bar");
var progressBarFull = document.querySelector("#unity-progress-bar-full");
var loadingText = document.querySelector("#unity-loading-text");
var fullscreenButton = document.querySelector("#unity-fullscreen-button");
var warningBanner = document.querySelector("#unity-warning");
// Zeigt Warnungen/Fehler an
function unityShowBanner(msg, type) {
function updateBannerVisibility() {
warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
}
var div = document.createElement('div');
div.innerHTML = msg;
warningBanner.appendChild(div);
if (type == 'error') div.style = 'color: #ff0000;';
else if (type == 'warning') div.style = 'color: #ff9900;';
setTimeout(function() {
warningBanner.removeChild(div);
updateBannerVisibility();
}, 5000);
updateBannerVisibility();
}
// Build-Konfiguration
var buildUrl = "Build";
var loaderUrl = buildUrl + "/{{{ LOADER_FILENAME }}}";
var config = {
dataUrl: buildUrl + "/{{{ DATA_FILENAME }}}",
frameworkUrl: buildUrl + "/{{{ FRAMEWORK_FILENAME }}}",
#if USE_WASM
codeUrl: buildUrl + "/{{{ CODE_FILENAME }}}",
#endif
#if MEMORY_FILENAME
memoryUrl: buildUrl + "/{{{ MEMORY_FILENAME }}}",
#endif
#if SYMBOLS_FILENAME
symbolsUrl: buildUrl + "/{{{ SYMBOLS_FILENAME }}}",
#endif
streamingAssetsUrl: "StreamingAssets",
companyName: "{{{ COMPANY_NAME }}}",
productName: "{{{ PRODUCT_NAME }}}",
productVersion: "{{{ PRODUCT_VERSION }}}",
showBanner: unityShowBanner,
};
// Mobile Check
if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
var meta = document.createElement('meta');
meta.name = 'viewport';
meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes';
document.getElementsByTagName('head')[0].appendChild(meta);
container.className = "unity-mobile";
}
// Canvas-Groesse anpassen
canvas.style.width = "100%";
canvas.style.height = "100%";
// Loader-Script laden
var script = document.createElement("script");
script.src = loaderUrl;
script.onload = () => {
createUnityInstance(canvas, config, (progress) => {
// Progress-Bar aktualisieren
var percent = Math.round(progress * 100);
progressBarFull.style.width = percent + "%";
loadingText.textContent = "Lade... " + percent + "%";
}).then((unityInstance) => {
// Loading fertig
loadingBar.classList.add("hidden");
// Fullscreen-Button
fullscreenButton.onclick = () => {
unityInstance.SetFullscreen(1);
};
// Unity-Instanz global verfuegbar machen
window.unityInstance = unityInstance;
}).catch((message) => {
alert(message);
});
};
document.body.appendChild(script);
// Text-to-Speech Funktionen (fuer Unity)
window.SpeakWebGL = function(text) {
if ('speechSynthesis' in window) {
window.speechSynthesis.cancel();
var utterance = new SpeechSynthesisUtterance(text);
utterance.lang = 'de-DE';
utterance.rate = 0.9;
var voices = window.speechSynthesis.getVoices();
var germanVoice = voices.find(v => v.lang.startsWith('de'));
if (germanVoice) utterance.voice = germanVoice;
window.speechSynthesis.speak(utterance);
}
};
window.SpeakDelayedWebGL = function(text, delay) {
setTimeout(function() {
window.SpeakWebGL(text);
}, delay * 1000);
};
window.StopSpeakingWebGL = function() {
if ('speechSynthesis' in window) {
window.speechSynthesis.cancel();
}
};
// Voice-Liste laden (manche Browser laden sie async)
if ('speechSynthesis' in window) {
window.speechSynthesis.onvoiceschanged = function() {
console.log('Voices geladen:', window.speechSynthesis.getVoices().length);
};
}
</script>
</body>
</html>