Der 18. Waldwächter betritt den Wald: BashPanda lehrt Bash als Kampfkunst! ✨ Neue Features: 🐼 BashPanda Waldwächter: - Kung Fu Meister Persönlichkeit - Lehrt Bash durch Kampfkunst-Metaphern - Integriert in waldwaechter.sh Library - Crew Memory: Kennt alle anderen Waldwächter 🥋 6 Gürtel-Missionen (Progressive Bash-Meisterschaft): - 🖤 Schwarzer Gürtel: echo, Variablen, read, ANSI codes - 💖 Pinker Gürtel: if/then, while/for, Arrays, Arithmetik - 💙 Blauer Gürtel: sed, case, bc, Textverarbeitung - 💚 Grüner Gürtel: grep, regex, Pattern Matching - 💛 Gelber Gürtel: Funktionen, source, Parameter - 🤍 Weisser Gürtel: Background jobs, Prozesse, Parallelität 📝 Interaktives Quiz-System: - Browser-based Gürtelprüfung (crumbblocks) - 30 Fragen (5 pro Gürtel) - Farbcodiert nach Gürtel - Auto-Export via Clipboard - Terminal-Auswertung mit Zertifikaten 🎓 Zertifikate-System: - Automatische Generierung bei 80%+ - Gespeichert in logs/zertifikate/ - BashPanda's Segen & Weisheiten 📚 Dokumentation: - CLAUDE.md komplett aktualisiert - BashPanda als 18. Waldwächter dokumentiert - Vollständige Dojo-Architektur beschrieben "Der Weg des Codes ist wie der Weg der Kampfkunst: Geduld, Präzision, Wiederholung." - BashPanda 🐼🎋 Crumbforest wächst! 🌲 Der Wurzelbau geht weiter! 🌳 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
632 lines
22 KiB
HTML
632 lines
22 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>🐼 BashPanda Gürtelprüfung 🥋</title>
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
font-family: 'Courier New', monospace;
|
|
background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
|
|
color: #e0e0e0;
|
|
padding: 20px;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.container {
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.header {
|
|
text-align: center;
|
|
padding: 30px 20px;
|
|
background: rgba(0,0,0,0.3);
|
|
border-radius: 15px;
|
|
margin-bottom: 30px;
|
|
border: 2px solid #4a4a4a;
|
|
}
|
|
|
|
.header h1 {
|
|
font-size: 2.5em;
|
|
margin-bottom: 10px;
|
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
|
}
|
|
|
|
.header .subtitle {
|
|
font-size: 1.2em;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.belt-selector {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
gap: 15px;
|
|
margin-bottom: 30px;
|
|
}
|
|
|
|
.belt-btn {
|
|
padding: 20px;
|
|
border: 3px solid;
|
|
border-radius: 10px;
|
|
cursor: pointer;
|
|
text-align: center;
|
|
font-size: 1.1em;
|
|
font-weight: bold;
|
|
transition: all 0.3s;
|
|
background: rgba(0,0,0,0.3);
|
|
}
|
|
|
|
.belt-btn:hover {
|
|
transform: translateY(-5px);
|
|
box-shadow: 0 5px 15px rgba(0,0,0,0.5);
|
|
}
|
|
|
|
.belt-btn.active {
|
|
box-shadow: 0 0 20px currentColor;
|
|
background: rgba(255,255,255,0.1);
|
|
}
|
|
|
|
.black { border-color: #000; color: #fff; }
|
|
.pink { border-color: #ff69b4; color: #ff69b4; }
|
|
.blue { border-color: #4169e1; color: #4169e1; }
|
|
.green { border-color: #32cd32; color: #32cd32; }
|
|
.yellow { border-color: #ffd700; color: #ffd700; }
|
|
.white { border-color: #f0f0f0; color: #f0f0f0; }
|
|
|
|
.quiz-container {
|
|
background: rgba(0,0,0,0.3);
|
|
border-radius: 15px;
|
|
padding: 30px;
|
|
border: 2px solid #4a4a4a;
|
|
display: none;
|
|
}
|
|
|
|
.quiz-container.active {
|
|
display: block;
|
|
}
|
|
|
|
.question {
|
|
margin-bottom: 30px;
|
|
}
|
|
|
|
.question-text {
|
|
font-size: 1.3em;
|
|
margin-bottom: 20px;
|
|
padding: 15px;
|
|
background: rgba(255,255,255,0.05);
|
|
border-left: 4px solid;
|
|
border-radius: 5px;
|
|
}
|
|
|
|
.options {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.option {
|
|
padding: 15px 20px;
|
|
border: 2px solid #4a4a4a;
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
background: rgba(0,0,0,0.2);
|
|
}
|
|
|
|
.option:hover {
|
|
background: rgba(255,255,255,0.1);
|
|
border-color: #6a6a6a;
|
|
}
|
|
|
|
.option.selected {
|
|
border-color: #ffd700;
|
|
background: rgba(255, 215, 0, 0.2);
|
|
}
|
|
|
|
.option.correct {
|
|
border-color: #32cd32;
|
|
background: rgba(50, 205, 50, 0.2);
|
|
}
|
|
|
|
.option.wrong {
|
|
border-color: #ff4444;
|
|
background: rgba(255, 68, 68, 0.2);
|
|
}
|
|
|
|
.controls {
|
|
display: flex;
|
|
gap: 15px;
|
|
margin-top: 30px;
|
|
}
|
|
|
|
.btn {
|
|
flex: 1;
|
|
padding: 15px 30px;
|
|
border: 2px solid #4a4a4a;
|
|
border-radius: 8px;
|
|
background: rgba(0,0,0,0.3);
|
|
color: #e0e0e0;
|
|
font-size: 1.1em;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.btn:hover {
|
|
background: rgba(255,255,255,0.1);
|
|
border-color: #6a6a6a;
|
|
}
|
|
|
|
.btn:disabled {
|
|
opacity: 0.3;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.btn-primary {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
border-color: #764ba2;
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
|
|
}
|
|
|
|
.results {
|
|
display: none;
|
|
text-align: center;
|
|
padding: 40px;
|
|
background: rgba(0,0,0,0.3);
|
|
border-radius: 15px;
|
|
border: 2px solid #4a4a4a;
|
|
}
|
|
|
|
.results.show {
|
|
display: block;
|
|
}
|
|
|
|
.results h2 {
|
|
font-size: 2.5em;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.results .score {
|
|
font-size: 3em;
|
|
font-weight: bold;
|
|
margin: 30px 0;
|
|
}
|
|
|
|
.results .verdict {
|
|
font-size: 1.5em;
|
|
margin: 20px 0;
|
|
padding: 20px;
|
|
border-radius: 10px;
|
|
background: rgba(255,255,255,0.05);
|
|
}
|
|
|
|
.export-info {
|
|
margin-top: 30px;
|
|
padding: 20px;
|
|
background: rgba(255, 215, 0, 0.1);
|
|
border: 2px solid #ffd700;
|
|
border-radius: 10px;
|
|
}
|
|
|
|
.progress {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin-bottom: 20px;
|
|
padding: 10px;
|
|
background: rgba(0,0,0,0.2);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.5; }
|
|
}
|
|
|
|
.pulse {
|
|
animation: pulse 2s infinite;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="header">
|
|
<h1>🐼 BashPanda Gürtelprüfung 🥋</h1>
|
|
<div class="subtitle">"Beweise dein Wissen, junger Schüler"</div>
|
|
</div>
|
|
|
|
<div class="belt-selector" id="beltSelector">
|
|
<div class="belt-btn black" data-belt="schwarz">🖤<br>Schwarz</div>
|
|
<div class="belt-btn pink" data-belt="pink">💖<br>Pink</div>
|
|
<div class="belt-btn blue" data-belt="blau">💙<br>Blau</div>
|
|
<div class="belt-btn green" data-belt="gruen">💚<br>Grün</div>
|
|
<div class="belt-btn yellow" data-belt="gelb">💛<br>Gelb</div>
|
|
<div class="belt-btn white" data-belt="weiss">🤍<br>Weiss</div>
|
|
</div>
|
|
|
|
<div class="quiz-container" id="quizContainer">
|
|
<div class="progress" id="progress"></div>
|
|
<div id="questionContainer"></div>
|
|
<div class="controls">
|
|
<button class="btn" id="prevBtn" disabled>⬅️ Zurück</button>
|
|
<button class="btn btn-primary" id="nextBtn">Weiter ➡️</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="results" id="results"></div>
|
|
</div>
|
|
|
|
<script>
|
|
const quizData = {
|
|
schwarz: [
|
|
{
|
|
question: "Was gibt 'echo $HOME' aus?",
|
|
options: ["Dein Home-Verzeichnis", "Die Umgebungsvariable HOME", "Beide Antworten sind richtig", "Einen Fehler"],
|
|
correct: 2,
|
|
color: "#fff"
|
|
},
|
|
{
|
|
question: "Wie erstellt man eine Variable?",
|
|
options: ["name = value", "name=value", "$name=value", "set name=value"],
|
|
correct: 1,
|
|
color: "#fff"
|
|
},
|
|
{
|
|
question: "Was macht 'read -p \"Name: \" name'?",
|
|
options: ["Liest eine Datei", "Zeigt 'Name:' und speichert Eingabe in $name", "Gibt $name aus", "Nichts"],
|
|
correct: 1,
|
|
color: "#fff"
|
|
},
|
|
{
|
|
question: "Welcher ANSI Code macht Text fett?",
|
|
options: ["\\e[0m", "\\e[1m", "\\e[4m", "\\e[32m"],
|
|
correct: 1,
|
|
color: "#fff"
|
|
},
|
|
{
|
|
question: "Was ist der Unterschied zwischen ' und \" in echo?",
|
|
options: ["Keiner", "' ignoriert Variablen, \" ersetzt sie", "\" ignoriert Variablen", "Beide ersetzen Variablen"],
|
|
correct: 1,
|
|
color: "#fff"
|
|
}
|
|
],
|
|
pink: [
|
|
{
|
|
question: "Was prüft [ $a -eq $b ]?",
|
|
options: ["String-Gleichheit", "Zahlen-Gleichheit", "Größer als", "Kleiner als"],
|
|
correct: 1,
|
|
color: "#ff69b4"
|
|
},
|
|
{
|
|
question: "Wie greift man auf das 3. Array-Element zu?",
|
|
options: ["${arr[3]}", "${arr[2]}", "$arr[2]", "arr[3]"],
|
|
correct: 1,
|
|
color: "#ff69b4"
|
|
},
|
|
{
|
|
question: "Was macht 'while [ $i -le 5 ]; do ... done'?",
|
|
options: ["Läuft 4 mal", "Läuft 5 mal", "Läuft 6 mal", "Endlosschleife"],
|
|
correct: 1,
|
|
color: "#ff69b4"
|
|
},
|
|
{
|
|
question: "Wie zählt man Arrays hoch?",
|
|
options: ["i++", "i=$((i + 1))", "let i++", "Alle sind richtig"],
|
|
correct: 1,
|
|
color: "#ff69b4"
|
|
},
|
|
{
|
|
question: "Was gibt ${#arr[@]} zurück?",
|
|
options: ["Erstes Element", "Letztes Element", "Anzahl Elemente", "Fehler"],
|
|
correct: 2,
|
|
color: "#ff69b4"
|
|
}
|
|
],
|
|
blau: [
|
|
{
|
|
question: "Was macht 'sed s/alt/neu/'?",
|
|
options: ["Löscht 'alt'", "Ersetzt erstes 'alt' mit 'neu'", "Ersetzt alle 'alt' mit 'neu'", "Sucht nach 'alt'"],
|
|
correct: 1,
|
|
color: "#4169e1"
|
|
},
|
|
{
|
|
question: "Wofür nutzt man 'case' statt if/then?",
|
|
options: ["Für Schleifen", "Für mehrere if-Alternativen", "Für Arrays", "Für Funktionen"],
|
|
correct: 1,
|
|
color: "#4169e1"
|
|
},
|
|
{
|
|
question: "Wie rechnet man mit Fließkommazahlen?",
|
|
options: ["$(( ))", "bc", "let", "expr"],
|
|
correct: 1,
|
|
color: "#4169e1"
|
|
},
|
|
{
|
|
question: "Was bedeutet das * in case?",
|
|
options: ["Multiplikation", "Wildcard (alles)", "Default-Fall", "Fehler"],
|
|
correct: 2,
|
|
color: "#4169e1"
|
|
},
|
|
{
|
|
question: "Wie nutzt man bc für Division?",
|
|
options: ["bc 10/3", "echo '10/3' | bc", "10/3 | bc", "bc(10/3)"],
|
|
correct: 1,
|
|
color: "#4169e1"
|
|
}
|
|
],
|
|
gruen: [
|
|
{
|
|
question: "Was macht grep -i?",
|
|
options: ["Zeigt Zeilennummern", "Ignoriert Groß-/Kleinschreibung", "Invertiert Suche", "Rekursiv suchen"],
|
|
correct: 1,
|
|
color: "#32cd32"
|
|
},
|
|
{
|
|
question: "Was bedeutet ^ in Regex?",
|
|
options: ["Zeilenanfang", "Zeilenende", "Beliebiges Zeichen", "Wiederholung"],
|
|
correct: 0,
|
|
color: "#32cd32"
|
|
},
|
|
{
|
|
question: "Was matched [0-9]+ in Regex?",
|
|
options: ["Genau eine Ziffer", "Eine oder mehr Ziffern", "Null oder mehr Ziffern", "Keine Ziffer"],
|
|
correct: 1,
|
|
color: "#32cd32"
|
|
},
|
|
{
|
|
question: "Wie sucht man rekursiv in allen Dateien?",
|
|
options: ["grep muster *", "grep -r muster .", "grep -i muster", "grep -n muster"],
|
|
correct: 1,
|
|
color: "#32cd32"
|
|
},
|
|
{
|
|
question: "Was matched .* in Regex?",
|
|
options: ["Nichts", "Punkt und Stern", "Beliebige Zeichen (0+)", "Ein Zeichen"],
|
|
correct: 2,
|
|
color: "#32cd32"
|
|
}
|
|
],
|
|
gelb: [
|
|
{
|
|
question: "Wie definiert man eine Funktion?",
|
|
options: ["func name() {}", "function name() {}", "def name() {}", "Beide 1 und 2"],
|
|
correct: 3,
|
|
color: "#ffd700"
|
|
},
|
|
{
|
|
question: "Was ist $1 in einer Funktion?",
|
|
options: ["Erster Buchstabe", "Erster Parameter", "Exit-Code", "PID"],
|
|
correct: 1,
|
|
color: "#ffd700"
|
|
},
|
|
{
|
|
question: "Was macht 'source datei.sh'?",
|
|
options: ["Führt Datei aus", "Lädt Funktionen in aktuelle Shell", "Kopiert Datei", "Löscht Datei"],
|
|
correct: 1,
|
|
color: "#ffd700"
|
|
},
|
|
{
|
|
question: "Was macht 'return 42' in einer Funktion?",
|
|
options: ["Gibt 42 aus", "Beendet Skript", "Verlässt Funktion mit Code 42", "Fehler"],
|
|
correct: 2,
|
|
color: "#ffd700"
|
|
},
|
|
{
|
|
question: "Was ist $@ in einer Funktion?",
|
|
options: ["Erster Parameter", "Alle Parameter", "Anzahl Parameter", "Funktionsname"],
|
|
correct: 1,
|
|
color: "#ffd700"
|
|
}
|
|
],
|
|
weiss: [
|
|
{
|
|
question: "Was macht & am Ende eines Befehls?",
|
|
options: ["Beendet ihn", "Startet im Hintergrund", "Wiederholt ihn", "Nichts"],
|
|
correct: 1,
|
|
color: "#f0f0f0"
|
|
},
|
|
{
|
|
question: "Was ist $! ?",
|
|
options: ["Exit-Code", "PID des letzten Background-Jobs", "Anzahl Parameter", "Home-Verzeichnis"],
|
|
correct: 1,
|
|
color: "#f0f0f0"
|
|
},
|
|
{
|
|
question: "Was macht 'wait'?",
|
|
options: ["Wartet 1 Sekunde", "Wartet auf Eingabe", "Wartet auf Background-Jobs", "Pausiert Skript"],
|
|
correct: 2,
|
|
color: "#f0f0f0"
|
|
},
|
|
{
|
|
question: "Wie zeigt man alle Background-Jobs?",
|
|
options: ["ps", "jobs", "bg", "fg"],
|
|
correct: 1,
|
|
color: "#f0f0f0"
|
|
},
|
|
{
|
|
question: "Was macht 'fg %1'?",
|
|
options: ["Beendet Job 1", "Bringt Job 1 in Vordergrund", "Startet Job 1", "Pausiert Job 1"],
|
|
correct: 1,
|
|
color: "#f0f0f0"
|
|
}
|
|
]
|
|
};
|
|
|
|
let currentBelt = null;
|
|
let currentQuestion = 0;
|
|
let answers = [];
|
|
let score = 0;
|
|
|
|
// Belt Selection
|
|
document.getElementById('beltSelector').addEventListener('click', (e) => {
|
|
const btn = e.target.closest('.belt-btn');
|
|
if (!btn) return;
|
|
|
|
document.querySelectorAll('.belt-btn').forEach(b => b.classList.remove('active'));
|
|
btn.classList.add('active');
|
|
|
|
currentBelt = btn.dataset.belt;
|
|
currentQuestion = 0;
|
|
answers = [];
|
|
score = 0;
|
|
|
|
document.getElementById('quizContainer').classList.add('active');
|
|
document.getElementById('results').classList.remove('show');
|
|
|
|
showQuestion();
|
|
});
|
|
|
|
function showQuestion() {
|
|
if (!currentBelt) return;
|
|
|
|
const questions = quizData[currentBelt];
|
|
const q = questions[currentQuestion];
|
|
|
|
document.getElementById('progress').innerHTML = `
|
|
<span>Frage ${currentQuestion + 1} von ${questions.length}</span>
|
|
<span>🐼 BashPanda beobachtet</span>
|
|
`;
|
|
|
|
const questionHTML = `
|
|
<div class="question">
|
|
<div class="question-text" style="border-color: ${q.color}">
|
|
${currentQuestion + 1}. ${q.question}
|
|
</div>
|
|
<div class="options">
|
|
${q.options.map((opt, idx) => `
|
|
<div class="option" data-index="${idx}">
|
|
${String.fromCharCode(65 + idx)}. ${opt}
|
|
</div>
|
|
`).join('')}
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
document.getElementById('questionContainer').innerHTML = questionHTML;
|
|
|
|
// Restore previous answer if exists
|
|
if (answers[currentQuestion] !== undefined) {
|
|
const selected = document.querySelector(`[data-index="${answers[currentQuestion]}"]`);
|
|
if (selected) selected.classList.add('selected');
|
|
}
|
|
|
|
// Option selection
|
|
document.querySelectorAll('.option').forEach(opt => {
|
|
opt.addEventListener('click', () => {
|
|
document.querySelectorAll('.option').forEach(o => o.classList.remove('selected'));
|
|
opt.classList.add('selected');
|
|
answers[currentQuestion] = parseInt(opt.dataset.index);
|
|
document.getElementById('nextBtn').disabled = false;
|
|
});
|
|
});
|
|
|
|
updateButtons();
|
|
}
|
|
|
|
function updateButtons() {
|
|
document.getElementById('prevBtn').disabled = currentQuestion === 0;
|
|
document.getElementById('nextBtn').disabled = answers[currentQuestion] === undefined;
|
|
|
|
const questions = quizData[currentBelt];
|
|
if (currentQuestion === questions.length - 1) {
|
|
document.getElementById('nextBtn').textContent = '🎯 Auswerten';
|
|
} else {
|
|
document.getElementById('nextBtn').textContent = 'Weiter ➡️';
|
|
}
|
|
}
|
|
|
|
document.getElementById('prevBtn').addEventListener('click', () => {
|
|
if (currentQuestion > 0) {
|
|
currentQuestion--;
|
|
showQuestion();
|
|
}
|
|
});
|
|
|
|
document.getElementById('nextBtn').addEventListener('click', () => {
|
|
const questions = quizData[currentBelt];
|
|
|
|
if (currentQuestion < questions.length - 1) {
|
|
currentQuestion++;
|
|
showQuestion();
|
|
} else {
|
|
showResults();
|
|
}
|
|
});
|
|
|
|
function showResults() {
|
|
const questions = quizData[currentBelt];
|
|
score = 0;
|
|
|
|
answers.forEach((ans, idx) => {
|
|
if (ans === questions[idx].correct) {
|
|
score++;
|
|
}
|
|
});
|
|
|
|
const percentage = (score / questions.length * 100).toFixed(0);
|
|
let verdict, color, emoji;
|
|
|
|
if (percentage >= 80) {
|
|
verdict = "🎉 BESTANDEN! 🎉<br>Der Gürtel gehört dir!";
|
|
color = "#32cd32";
|
|
emoji = "✅";
|
|
} else if (percentage >= 60) {
|
|
verdict = "Fast geschafft!<br>Übe noch ein wenig.";
|
|
color = "#ffd700";
|
|
emoji = "⚠️";
|
|
} else {
|
|
verdict = "Noch nicht bereit.<br>Lerne weiter, junger Schüler.";
|
|
color = "#ff4444";
|
|
emoji = "❌";
|
|
}
|
|
|
|
const resultData = {
|
|
belt: currentBelt,
|
|
score: score,
|
|
total: questions.length,
|
|
percentage: percentage,
|
|
passed: percentage >= 80,
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
|
|
document.getElementById('results').innerHTML = `
|
|
<h2>${emoji} Gürtelprüfung: ${currentBelt.toUpperCase()}</h2>
|
|
<div class="score" style="color: ${color}">
|
|
${score} / ${questions.length}
|
|
</div>
|
|
<div style="font-size: 2em; margin: 20px 0;">
|
|
${percentage}%
|
|
</div>
|
|
<div class="verdict" style="border-color: ${color}">
|
|
${verdict}
|
|
</div>
|
|
<div class="export-info">
|
|
<p><strong>📋 Ergebnis exportiert!</strong></p>
|
|
<p>Die Ergebnisse wurden in die Zwischenablage kopiert.</p>
|
|
<p>Füge sie im Terminal ein für die Auswertung!</p>
|
|
<br>
|
|
<button class="btn btn-primary" onclick="location.reload()">🔄 Neue Prüfung</button>
|
|
</div>
|
|
`;
|
|
|
|
document.getElementById('quizContainer').classList.remove('active');
|
|
document.getElementById('results').classList.add('show');
|
|
|
|
// Copy to clipboard
|
|
const exportText = JSON.stringify(resultData, null, 2);
|
|
navigator.clipboard.writeText(exportText).then(() => {
|
|
console.log('Ergebnisse in Zwischenablage kopiert!');
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|