feat(ux): responsive kurs-sidebar und kapitel-drawer für alle 13 kurse & web-ide

- Dynamic Sidebar mit window.COURSES_MANIFEST für 13 Kurse (216 Kapitel)
- Kurswechsler Dropdown mit Direktnavigation
- Fortschrittsanzeige mit Solved-Checkmarks (✓) aus localStorage
- Responsive Off-Canvas Drawer mit Floating Action Button (☰ Kapitel) & Backdrop auf Mobile/Tablets
- Web-IDE Topbar Drawer-Button (☰ Kapitel) für unterbrechungsfreien Vollbild-Editor
- Saubere Bereinigung redundanter statischer Legacy-Sidebars
This commit is contained in:
Alex Mueller 2026-09-12 13:49:46 +02:00
parent 893590317b
commit 2571cb8847
220 changed files with 3047 additions and 6140 deletions

383
assets/course_sidebar.js Normal file
View file

@ -0,0 +1,383 @@
/**
* 🧭 DYNAMIC COURSE SIDEBAR & RESPONSIVE DRAWER SYSTEM 🧭
* =======================================================
* IT-Praxisportal – Vollständig responsive Kurs-Sidebar für alle 13 Kurse & Web-IDE.
*/
(function () {
'use strict';
function getRootPrefix() {
const scripts = document.querySelectorAll('script[src*="course_sidebar.js"]');
if (scripts.length > 0) {
const src = scripts[scripts.length - 1].getAttribute('src');
const idx = src.indexOf('assets/course_sidebar.js');
if (idx !== -1) {
return src.substring(0, idx);
}
}
const p = window.location.pathname;
if (p.includes('/courses/')) return '../../../';
if (p.includes('/lehrpfad_')) return '../../';
return '';
}
function detectContext() {
const isWorkspace = window.location.pathname.endsWith('workspace.html') || !!document.querySelector('.workspace-topbar');
const urlParams = new URLSearchParams(window.location.search);
if (isWorkspace) {
return {
isWorkspace: true,
courseId: urlParams.get('course') || 'python',
trackId: urlParams.get('track') || '',
chapterFolder: urlParams.get('chapter') || ''
};
}
const path = window.location.pathname;
const courseMatch = path.match(/courses\/([^\/]+)\/([^\/]+)/);
if (courseMatch) {
return {
isWorkspace: false,
courseId: courseMatch[1],
chapterFolder: courseMatch[2],
trackId: ''
};
}
const pythonMatch = path.match(/(lehrpfad_[^\/]+)\/([^\/]+)/);
if (pythonMatch) {
return {
isWorkspace: false,
courseId: 'python',
trackId: pythonMatch[1],
chapterFolder: pythonMatch[2]
};
}
return {
isWorkspace: false,
courseId: 'python',
chapterFolder: '',
trackId: ''
};
}
function getSolvedChapters() {
const solved = new Set();
try {
const stateStr = localStorage.getItem('python_gamification_state');
if (stateStr) {
const s = JSON.parse(stateStr);
if (Array.isArray(s.geloeste_kapitel)) {
s.geloeste_kapitel.forEach(id => solved.add(id));
}
}
const progStr = localStorage.getItem('python_gamification_progress');
if (progStr) {
const p = JSON.parse(progStr);
if (Array.isArray(p.geloeste_kapitel)) {
p.geloeste_kapitel.forEach(id => solved.add(id));
}
}
} catch (e) {
console.warn('Lernfortschritt konnte nicht geladen werden:', e);
}
return solved;
}
function initSidebar() {
const rootPrefix = getRootPrefix();
if (!window.COURSES_MANIFEST) {
const manifestScript = document.createElement('script');
manifestScript.src = `${rootPrefix}assets/courses_manifest.js`;
manifestScript.onload = () => buildSidebar();
manifestScript.onerror = () => console.error('Konnte courses_manifest.js nicht laden.');
document.head.appendChild(manifestScript);
} else {
buildSidebar();
}
}
function buildSidebar() {
if (!window.COURSES_MANIFEST) return;
// Alte legacy sidebars entfernen falls vorhanden
document.querySelectorAll('.app-sidebar, .sidebar-mobile-toggle, .sidebar-overlay').forEach(el => el.remove());
const existingSidebar = document.getElementById('courseSidebar');
if (existingSidebar) existingSidebar.remove();
const existingBackdrop = document.getElementById('courseSidebarBackdrop');
if (existingBackdrop) existingBackdrop.remove();
const existingMobileBtn = document.getElementById('courseSidebarMobileToggle');
if (existingMobileBtn) existingMobileBtn.remove();
const rootPrefix = getRootPrefix();
const context = detectContext();
const manifest = window.COURSES_MANIFEST;
const currentCourse = manifest[context.courseId] || manifest['python'];
if (!currentCourse) return;
const solvedSet = getSolvedChapters();
if (!context.chapterFolder && currentCourse.tracks && currentCourse.tracks[0] && currentCourse.tracks[0].chapters && currentCourse.tracks[0].chapters[0]) {
context.chapterFolder = currentCourse.tracks[0].chapters[0].folder;
if (!currentTrackId) currentTrackId = currentCourse.tracks[0].id;
}
// Zähle Kapitel & gelöste Aufgaben für den aktiven Kurs
let totalChapters = 0;
let solvedCount = 0;
let currentTrackId = context.trackId || '';
(currentCourse.tracks || []).forEach(tr => {
(tr.chapters || []).forEach(ch => {
totalChapters++;
const isSolved = solvedSet.has(ch.folder) ||
solvedSet.has(`${context.courseId}/${ch.folder}`) ||
solvedSet.has(`${tr.id}/${ch.folder}`);
if (isSolved) solvedCount++;
if (ch.folder === context.chapterFolder && !currentTrackId) {
currentTrackId = tr.id;
}
});
});
const percent = totalChapters > 0 ? Math.round((solvedCount / totalChapters) * 100) : 0;
if (context.isWorkspace) {
document.body.classList.add('workspace-page');
} else {
document.body.classList.add('has-course-sidebar');
}
// Erstelle Sidebar Container
const sidebar = document.createElement('aside');
sidebar.className = 'course-sidebar';
sidebar.id = 'courseSidebar';
// Header mit Branding, Close-Button & Dropdown
let courseOptionsHtml = '';
const courseKeys = Object.keys(manifest);
courseKeys.forEach(cid => {
const c = manifest[cid];
const selected = cid === context.courseId ? 'selected' : '';
const icon = c.icon || '📚';
courseOptionsHtml += `<option value="${cid}" ${selected}>${icon} ${c.title}</option>`;
});
// Navigation Tracks & Chapters generieren
let navHtml = '';
(currentCourse.tracks || []).forEach((tr) => {
navHtml += `<div class="course-sidebar-track-group">`;
navHtml += `<div class="course-sidebar-track-title">${tr.title}</div>`;
navHtml += `<div style="display: flex; flex-direction: column; gap: 2px;">`;
(tr.chapters || []).forEach((ch) => {
const isActive = (ch.folder === context.chapterFolder);
const isSolved = solvedSet.has(ch.folder) ||
solvedSet.has(`${context.courseId}/${ch.folder}`) ||
solvedSet.has(`${tr.id}/${ch.folder}`);
let linkUrl = '';
if (context.isWorkspace) {
linkUrl = `${rootPrefix}workspace.html?course=${context.courseId}&track=${tr.id}&chapter=${ch.folder}`;
} else {
if (context.courseId === 'python') {
linkUrl = `${rootPrefix}${tr.id}/${ch.folder}/index.html`;
} else {
linkUrl = `${rootPrefix}courses/${context.courseId}/${ch.folder}/index.html`;
}
}
let statusIconHtml = '';
if (isSolved) {
statusIconHtml = `<span class="course-sidebar-status-icon status-icon-solved" title="Gelöst">✓</span>`;
} else if (isActive) {
statusIconHtml = `<span class="course-sidebar-status-icon status-icon-open" title="Aktuell in Bearbeitung">●</span>`;
} else {
statusIconHtml = `<span class="course-sidebar-status-icon status-icon-open"></span>`;
}
navHtml += `
<a href="${linkUrl}" class="course-sidebar-link ${isActive ? 'active' : ''}" ${isActive ? 'id="activeSidebarChapter"' : ''} title="${ch.title}">
${statusIconHtml}
<span class="course-sidebar-title-text">${ch.title}</span>
</a>
`;
});
navHtml += `</div></div>`;
});
// Footer Action (Theorie lesen vs. Web-IDE)
let footerActionHtml = '';
if (context.isWorkspace) {
let theoryUrl = '';
if (context.courseId === 'python') {
theoryUrl = `${rootPrefix}${currentTrackId || 'lehrpfad_1_grundlagen'}/${context.chapterFolder}/index.html`;
} else {
theoryUrl = `${rootPrefix}courses/${context.courseId}/${context.chapterFolder}/index.html`;
}
footerActionHtml = `
<a href="${theoryUrl}" title="Zurück zur ausführlichen Theorie-Lektion" style="display: inline-flex; align-items: center; gap: 5px; color: #38bdf8; font-weight: 700;">
<span>📖</span> <span>Theorie lesen</span>
</a>
`;
} else {
const ideUrl = `${rootPrefix}workspace.html?course=${context.courseId}&track=${currentTrackId}&chapter=${context.chapterFolder}`;
footerActionHtml = `
<a href="${ideUrl}" title="Aufgabe in der interaktiven Web-IDE bearbeiten" style="display: inline-flex; align-items: center; gap: 5px; color: #10b981; font-weight: 700;">
<span>💻</span> <span>Web-IDE</span>
</a>
`;
}
sidebar.innerHTML = `
<div class="course-sidebar-header">
<div class="course-sidebar-brand-row">
<a href="${rootPrefix}index.html" class="course-sidebar-brand" title="Zur IT-Praxisportal Startseite">
<div class="course-sidebar-logo">🎓</div>
<div>
<div class="course-sidebar-title">IT-Praxisportal</div>
<div style="font-size: 0.65rem; color: #64748b; font-weight: 800; text-transform: uppercase; letter-spacing: 0.8px;">PRO LERNPFAD</div>
</div>
</a>
<button type="button" class="course-sidebar-close-btn" id="courseSidebarClose" aria-label="Sidebar schließen" title="Schließen">✕</button>
</div>
<label for="courseSidebarSelect" style="display: block; font-size: 0.68rem; font-weight: 700; color: #94a3b8; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 5px;">Aktiver Kurs</label>
<select class="course-sidebar-select" id="courseSidebarSelect">
${courseOptionsHtml}
</select>
<div class="course-sidebar-progress-container">
<div class="course-sidebar-progress-text">
<span>Kursfortschritt</span>
<span id="course-sidebar-progress-stat">${solvedCount} / ${totalChapters} (${percent}%)</span>
</div>
<div class="course-sidebar-progress-bar-bg">
<div class="course-sidebar-progress-bar-fill" style="width: ${percent}%;"></div>
</div>
</div>
</div>
<nav class="course-sidebar-nav" id="courseSidebarNav">
${navHtml}
</nav>
<div class="course-sidebar-footer">
${footerActionHtml}
<a href="${rootPrefix}index.html" style="display: inline-flex; align-items: center; gap: 4px;" title="Zur Startseite">
<span>🏠</span> <span>Dashboard</span>
</a>
</div>
`;
document.body.appendChild(sidebar);
// Backdrop erstellen
const backdrop = document.createElement('div');
backdrop.className = 'course-sidebar-backdrop';
backdrop.id = 'courseSidebarBackdrop';
document.body.appendChild(backdrop);
// Kurswechsler Event Listener
const selectEl = document.getElementById('courseSidebarSelect');
if (selectEl) {
selectEl.addEventListener('change', (e) => {
const newCourseId = e.target.value;
if (newCourseId === context.courseId) return;
const targetCourse = manifest[newCourseId];
if (!targetCourse || !targetCourse.tracks || !targetCourse.tracks.length) return;
const targetTrack = targetCourse.tracks[0];
const targetChapter = targetTrack.chapters && targetTrack.chapters.length ? targetTrack.chapters[0].folder : '';
if (context.isWorkspace) {
window.location.href = `${rootPrefix}workspace.html?course=${newCourseId}&track=${targetTrack.id}&chapter=${targetChapter}`;
} else {
if (newCourseId === 'python') {
window.location.href = `${rootPrefix}${targetTrack.id}/${targetChapter}/index.html`;
} else {
window.location.href = `${rootPrefix}courses/${newCourseId}/${targetChapter}/index.html`;
}
}
});
}
// Toggle-Funktionen für Drawer
function openSidebar() {
sidebar.classList.add('open');
backdrop.classList.add('active');
}
function closeSidebar() {
sidebar.classList.remove('open');
backdrop.classList.remove('active');
}
const closeBtn = document.getElementById('courseSidebarClose');
if (closeBtn) closeBtn.addEventListener('click', closeSidebar);
backdrop.addEventListener('click', closeSidebar);
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') closeSidebar();
});
// Mobil-Toggle Button für Leseansicht
if (!context.isWorkspace) {
const mobileBtn = document.createElement('button');
mobileBtn.type = 'button';
mobileBtn.className = 'course-sidebar-mobile-btn';
mobileBtn.id = 'courseSidebarMobileToggle';
mobileBtn.setAttribute('aria-label', 'Module und Kapitel öffnen');
mobileBtn.innerHTML = `<span>☰</span> <span>Kapitel (${solvedCount}/${totalChapters})</span>`;
mobileBtn.addEventListener('click', () => {
if (sidebar.classList.contains('open')) {
closeSidebar();
} else {
openSidebar();
}
});
document.body.appendChild(mobileBtn);
}
// Workspace: Topbar "☰ Kapitel" Button einbinden
if (context.isWorkspace) {
const topbarTitle = document.querySelector('.workspace-title');
if (topbarTitle && !document.getElementById('btn-toggle-chapter-drawer')) {
const toggleBtn = document.createElement('button');
toggleBtn.type = 'button';
toggleBtn.id = 'btn-toggle-chapter-drawer';
toggleBtn.className = 'btn btn-secondary';
toggleBtn.style.cssText = 'font-size: 0.8rem; padding: 4px 10px; margin-right: 10px; display: inline-flex; align-items: center; gap: 6px; border: 1px solid rgba(255,255,255,0.18); background: rgba(255,255,255,0.08); color: #f8fafc; font-weight: 700; cursor: pointer; border-radius: 6px;';
toggleBtn.innerHTML = '<span>☰</span> <span>Kapitel</span>';
toggleBtn.title = 'Kapitel-Drawer aufklappen';
toggleBtn.addEventListener('click', () => {
if (sidebar.classList.contains('open')) {
closeSidebar();
} else {
openSidebar();
}
});
topbarTitle.insertBefore(toggleBtn, topbarTitle.firstChild);
}
}
// Aktives Kapitel automatisch mittig in der Sidebar sichtbar scrollen
setTimeout(() => {
const activeItem = document.getElementById('activeSidebarChapter');
if (activeItem) {
activeItem.scrollIntoView({ block: 'center', behavior: 'smooth' });
}
}, 150);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initSidebar);
} else {
initSidebar();
}
})();

1844
assets/courses_manifest.js Normal file

File diff suppressed because it is too large Load diff

View file

@ -1419,3 +1419,344 @@ pre code {
display: none; display: none;
} }
} }
/* ==========================================================================
🧭 DYNAMIC COURSE SIDEBAR & RESPONSIVE DRAWER SYSTEM
========================================================================== */
body.has-course-sidebar {
margin-left: 280px !important;
transition: margin-left 0.25s ease;
position: relative;
min-height: 100vh;
}
@media (max-width: 1024px) {
body.has-course-sidebar {
margin-left: 0 !important;
padding-top: 0 !important;
}
}
/* Sidebar Container */
.course-sidebar {
position: fixed;
top: 0;
left: 0;
bottom: 0;
width: 280px;
background: #090d16;
border-right: 1px solid rgba(255, 255, 255, 0.08);
display: flex;
flex-direction: column;
z-index: 1050;
overflow: hidden;
transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
@media (max-width: 1024px) {
.course-sidebar {
transform: translateX(-100%);
box-shadow: 0 0 35px rgba(0, 0, 0, 0.85);
}
.course-sidebar.open {
transform: translateX(0);
}
}
/* Sidebar Header */
.course-sidebar-header {
padding: 16px 16px 14px 16px;
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
background: #0d1322;
flex-shrink: 0;
}
.course-sidebar-brand-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
}
.course-sidebar-brand {
display: flex;
align-items: center;
gap: 10px;
text-decoration: none;
color: white;
}
.course-sidebar-logo {
width: 32px;
height: 32px;
border-radius: 8px;
background: rgba(56, 189, 248, 0.15);
border: 1px solid rgba(56, 189, 248, 0.4);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.1rem;
}
.course-sidebar-title {
font-size: 0.95rem;
font-weight: 800;
color: #f8fafc;
line-height: 1.2;
}
.course-sidebar-close-btn {
display: none;
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(255, 255, 255, 0.12);
color: #94a3b8;
width: 28px;
height: 28px;
border-radius: 6px;
align-items: center;
justify-content: center;
font-size: 0.9rem;
cursor: pointer;
line-height: 1;
transition: all 0.15s ease;
}
.course-sidebar-close-btn:hover {
background: rgba(255, 255, 255, 0.15);
color: #ffffff;
border-color: rgba(255, 255, 255, 0.3);
}
@media (max-width: 1024px) {
.course-sidebar-close-btn {
display: inline-flex;
}
}
.course-sidebar-select {
width: 100%;
background: #080c14;
color: #f1f5f9;
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 6px;
padding: 7px 9px;
font-size: 0.8rem;
font-weight: 600;
outline: none;
cursor: pointer;
transition: border-color 0.15s ease;
}
.course-sidebar-select:focus {
border-color: #38bdf8;
}
/* Progress bar inside sidebar */
.course-sidebar-progress-container {
margin-top: 12px;
}
.course-sidebar-progress-text {
display: flex;
justify-content: space-between;
font-size: 0.72rem;
font-weight: 700;
color: #94a3b8;
margin-bottom: 5px;
}
.course-sidebar-progress-bar-bg {
width: 100%;
height: 6px;
background: rgba(255, 255, 255, 0.08);
border-radius: 99px;
overflow: hidden;
}
.course-sidebar-progress-bar-fill {
height: 100%;
background: linear-gradient(90deg, #10b981, #0284c7);
border-radius: 99px;
transition: width 0.3s ease;
}
/* Navigation list */
.course-sidebar-nav {
flex: 1;
overflow-y: auto;
padding: 12px 10px;
}
.course-sidebar-nav::-webkit-scrollbar {
width: 5px;
}
.course-sidebar-nav::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.15);
border-radius: 99px;
}
.course-sidebar-track-title {
font-size: 0.68rem;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.6px;
color: #64748b;
padding: 12px 10px 4px 10px;
}
.course-sidebar-link {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 10px;
border-radius: 6px;
color: #94a3b8;
text-decoration: none;
font-size: 0.82rem;
font-weight: 600;
line-height: 1.3;
transition: all 0.15s ease;
margin-bottom: 2px;
border: 1px solid transparent;
}
.course-sidebar-link:hover {
background: rgba(255, 255, 255, 0.05);
color: #f8fafc;
}
.course-sidebar-link.active {
background: rgba(56, 189, 248, 0.12);
color: #38bdf8;
border-color: rgba(56, 189, 248, 0.3);
font-weight: 700;
}
.course-sidebar-title-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
.course-sidebar-status-icon {
font-size: 0.72rem;
width: 18px;
height: 18px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.status-icon-solved {
background: #059669;
color: white;
font-weight: 800;
}
.status-icon-open {
border: 1.5px solid #475569;
color: transparent;
}
.course-sidebar-link.active .status-icon-open {
border-color: #38bdf8;
background: rgba(56, 189, 248, 0.3);
color: #38bdf8;
}
/* Sidebar Footer */
.course-sidebar-footer {
padding: 12px 16px;
background: #080c14;
border-top: 1px solid rgba(255, 255, 255, 0.08);
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
}
.course-sidebar-footer a {
color: #94a3b8;
font-size: 0.78rem;
text-decoration: none;
font-weight: 600;
transition: color 0.15s ease;
}
.course-sidebar-footer a:hover {
color: #38bdf8;
}
/* Mobile Toggle Button */
.course-sidebar-mobile-btn {
display: none;
position: fixed;
bottom: 22px;
left: 20px;
z-index: 1030;
background: #0f172a;
color: white;
border: 1px solid rgba(56, 189, 248, 0.5);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.55), 0 0 12px rgba(56, 189, 248, 0.25);
padding: 10px 18px;
border-radius: 99px;
font-size: 0.85rem;
font-weight: 700;
cursor: pointer;
align-items: center;
gap: 8px;
backdrop-filter: blur(8px);
transition: transform 0.15s ease, background-color 0.15s ease;
}
.course-sidebar-mobile-btn:active {
transform: scale(0.96);
}
@media (max-width: 1024px) {
.course-sidebar-mobile-btn {
display: inline-flex;
}
}
.course-sidebar-backdrop {
display: none;
position: fixed;
inset: 0;
background: rgba(15, 23, 42, 0.75);
backdrop-filter: blur(4px);
z-index: 1040;
}
.course-sidebar-backdrop.active {
display: block;
}
/* Workspace Specific Drawer Overrides */
body.workspace-page.has-course-sidebar {
margin-left: 0 !important;
}
.workspace-page .course-sidebar {
transform: translateX(-100%);
box-shadow: 0 0 35px rgba(0, 0, 0, 0.85);
z-index: 9999;
}
.workspace-page .course-sidebar.open {
transform: translateX(0);
}
.workspace-page .course-sidebar-close-btn {
display: inline-flex;
}
.workspace-page .course-sidebar-backdrop {
z-index: 9998;
}

View file

@ -150,5 +150,7 @@ rm -rf /tmp/build_cache/ # Rekursives Löschen ohne Bestätig
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -152,5 +152,7 @@ EOF</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -151,5 +151,7 @@ FREE_RAM=$(( TOTAL_RAM - USED_RAM ))</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -153,5 +153,7 @@ fi</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -157,5 +157,7 @@ esac</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -145,5 +145,7 @@ echo "Alle Keys: ${!PORT_MAP[@]}"</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -130,5 +130,7 @@ cat pods.json | jq -r '.items[] | "\(.metadata.name),\(.status.phase)"'</code></
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -147,5 +147,7 @@ set +x # Schaltet Tracing wieder aus</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -130,5 +130,7 @@ wait # Blockiert, bis ALLE Subshells im Hintergrund fertig sind</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -137,5 +137,7 @@ echo "Ergebnis: $antwort" # 30</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -126,5 +126,7 @@ rsync -avz --delete --exclude="*.log" /var/app/ deploy@backup-server:/var/app/</
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -124,5 +124,7 @@ WantedBy=multi-user.target</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -120,5 +120,7 @@ status=$(docker inspect --format='{{.State.Health.Status}}' my-postgres)
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -121,5 +121,7 @@ echo "::error file=config.json,line=5::Invalid JSON format"</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -132,5 +132,7 @@ teardown() {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -118,5 +118,7 @@
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -165,5 +165,7 @@ snprintf(buffer, sizeof(buffer), "Sensor #%03d: %.2f C", sensor_id, temp);
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -150,5 +150,7 @@ swap(&x, &y); // x ist jetzt 10, y ist jetzt 5!</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -151,5 +151,7 @@ buffer = NULL; // WICHTIG: Verhindert versehentlichen Zugriff nach Freigabe!</co
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=cpp&chapter=04_structs_und_header_dateien" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=cpp&chapter=04_structs_und_header_dateien" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=cpp&chapter=05_einstieg_cpp_und_namespaces" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=cpp&chapter=05_einstieg_cpp_und_namespaces" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=cpp&chapter=06_klassen_konstruktoren_und_raii" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=cpp&chapter=06_klassen_konstruktoren_und_raii" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=cpp&chapter=07_vererbung_und_virtuelle_methoden" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=cpp&chapter=07_vererbung_und_virtuelle_methoden" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=cpp&chapter=08_operator_overloading" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=cpp&chapter=08_operator_overloading" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -192,5 +192,7 @@ struct TypeFormatter&lt;bool&gt; {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -185,5 +185,7 @@ SafeFile open_safe_file(const char* filename, const char* mode) {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -165,5 +165,7 @@ int main() {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -166,5 +166,7 @@ int main() {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=cpp&chapter=13_multithreading_mit_std_thread" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=cpp&chapter=13_multithreading_mit_std_thread" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=cpp&chapter=14_dateiverarbeitung_und_streams" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=cpp&chapter=14_dateiverarbeitung_und_streams" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=cpp&chapter=15_googletest_gtest_unittesting" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=cpp&chapter=15_googletest_gtest_unittesting" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=cpp&chapter=16_master_abschlussprojekt_high_performance_engine" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=cpp&chapter=16_master_abschlussprojekt_high_performance_engine" class="bg-cyan-500 hover:bg-cyan-600 text-slate-950 font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -3,4 +3,6 @@
<link rel="icon" type="image/svg+xml" href="../../../assets/favicon.svg"> <link rel="icon" type="image/svg+xml" href="../../../assets/favicon.svg">
<meta charset="UTF-8"><title>C# 01</title><link rel="stylesheet" href="../../../assets/style.css"></head> <meta charset="UTF-8"><title>C# 01</title><link rel="stylesheet" href="../../../assets/style.css"></head>
<body class="bg-slate-900 text-slate-100 p-6"><h1 class="text-2xl font-bold text-purple-400 mb-4">C# 01: Syntax & Top-Level Statements</h1> <body class="bg-slate-900 text-slate-100 p-6"><h1 class="text-2xl font-bold text-purple-400 mb-4">C# 01: Syntax & Top-Level Statements</h1>
<a href="../../../workspace.html?course=csharp&chapter=01_syntax_datentypen_und_top_level_statements" class="bg-purple-600 text-white px-4 py-2 rounded">💻 In Web-IDE öffnen →</a></body></html> <a href="../../../workspace.html?course=csharp&chapter=01_syntax_datentypen_und_top_level_statements" class="bg-purple-600 text-white px-4 py-2 rounded">💻 In Web-IDE öffnen →</a> <script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body></html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=csharp&chapter=02_kontrollfluss_und_pattern_matching" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=csharp&chapter=02_kontrollfluss_und_pattern_matching" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=csharp&chapter=03_arrays_listen_und_collections" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=csharp&chapter=03_arrays_listen_und_collections" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=csharp&chapter=04_methoden_parameter_und_tuples" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=csharp&chapter=04_methoden_parameter_und_tuples" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=csharp&chapter=05_klassen_objekte_und_primary_constructors" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=csharp&chapter=05_klassen_objekte_und_primary_constructors" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=csharp&chapter=06_records_und_immutability" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=csharp&chapter=06_records_und_immutability" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=csharp&chapter=07_vererbung_polymorphismus_und_abstract" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=csharp&chapter=07_vererbung_polymorphismus_und_abstract" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=csharp&chapter=08_interfaces_und_dependency_injection" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=csharp&chapter=08_interfaces_und_dependency_injection" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -177,5 +177,7 @@ public class InMemoryRepository&lt;TEntity, TId&gt;
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -163,5 +163,7 @@ var revenueByCategory = orders
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -152,5 +152,7 @@ catch (OperationCanceledException)
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -173,5 +173,7 @@ catch (BankDomainException ex)
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=csharp&chapter=13_json_serialisierung_und_dateien" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=csharp&chapter=13_json_serialisierung_und_dateien" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=csharp&chapter=14_events_delegates_und_lambdas" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=csharp&chapter=14_events_delegates_und_lambdas" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=csharp&chapter=15_xunit_automatisiertes_unit_testing" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=csharp&chapter=15_xunit_automatisiertes_unit_testing" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -19,5 +19,7 @@
<a href="../../../workspace.html?course=csharp&chapter=16_master_abschlussprojekt_enterprise_order_engine" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a> <a href="../../../workspace.html?course=csharp&chapter=16_master_abschlussprojekt_enterprise_order_engine" class="bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-2 rounded shadow transition">💻 In Web-IDE öffnen →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -148,5 +148,7 @@ durchschnitt := float64(summe) / float64(anzahl) // Ergibt 37.5 (float64)</code>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -103,5 +103,7 @@ delete(ports, "ssh")</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -123,5 +123,7 @@ default:
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -115,5 +115,7 @@ fmt.Println(c1()) // 12</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -137,5 +137,7 @@ fmt.Println(admin.Info()) // Ruft User.Info() auf</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -108,5 +108,7 @@ func Describe(val any) string {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -104,5 +104,7 @@ func (e *APIError) Error() string {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -93,5 +93,7 @@ defer fmt.Println("3. Dritter Defer")
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -194,5 +194,7 @@ func main() {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -169,5 +169,7 @@ func Consume(in &lt;-chan int) {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -182,5 +182,7 @@ func main() {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -182,5 +182,7 @@ func GetTotalRequests() int64 {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -182,5 +182,7 @@ func main() {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -173,5 +173,7 @@ func AuthMiddleware(secretKey string) func(http.Handler) http.Handler {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -173,5 +173,7 @@ func TestAdd(t *testing.T) {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -153,5 +153,7 @@
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -165,5 +165,7 @@
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -154,5 +154,7 @@
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -139,5 +139,7 @@
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -157,5 +157,7 @@
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -107,5 +107,7 @@ tr:nth-child(odd) { background-color: #ffffff; }</code></pre>
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -153,5 +153,7 @@
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -127,5 +127,7 @@
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -143,5 +143,7 @@ p { font-size: 1rem; font-weight: 400; line-height: 1.65; } /* 16px, Lesefre
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -193,5 +193,7 @@
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -137,5 +137,7 @@
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -113,5 +113,7 @@ h1.hero-title {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -175,5 +175,7 @@
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -130,5 +130,7 @@
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -132,5 +132,7 @@ body {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -129,5 +129,7 @@ dialog::backdrop {
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -114,5 +114,7 @@
</main> </main>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -297,5 +297,7 @@ Qualitative Kriterien: 1. Know-how-Aufbau und Datensicherheit im eigenen Haus; 2
<a href="../02_lf2_arbeitsplaetze_ausstatten/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a> <a href="../02_lf2_arbeitsplaetze_ausstatten/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -414,5 +414,7 @@ Burn-In-Risiko: IPS hat kein Burn-In; bei OLED besteht bei statischen Office-Ele
<a href="../03_lf3_clients_in_netzwerke_einbinden/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a> <a href="../03_lf3_clients_in_netzwerke_einbinden/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -505,5 +505,7 @@ RRSIG (Resource Record Signature): Enthält die kryptografische Signatur über e
<a href="../04_lf4_schutzbedarfsanalyse_und_cybersicherheit/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a> <a href="../04_lf4_schutzbedarfsanalyse_und_cybersicherheit/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -470,5 +470,7 @@ Drei Säulen: 1. Identitätsbasierte Zugriffskontrolle (starke MFA, Kontextprüf
<a href="../05_lf5_software_zur_datenverwaltung/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a> <a href="../05_lf5_software_zur_datenverwaltung/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -457,5 +457,7 @@ Syntax-Erklärung:
<a href="../06_lf6_cyber_physische_systeme_iot/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a> <a href="../06_lf6_cyber_physische_systeme_iot/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -199,5 +199,7 @@ Modbus TCP: Basiert auf Standard-Ethernet und TCP/IP (Standard-Port 502). Adress
<a href="../07_lf7_instandhaltung_und_fehlerdiagnose/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a> <a href="../07_lf7_instandhaltung_und_fehlerdiagnose/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -187,5 +187,7 @@ CAT-Einstufung (Überspannungskategorien): CAT II gilt für Geräte an normalen
<a href="../08_lf8_datenfluesse_und_schnittstellen/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a> <a href="../08_lf8_datenfluesse_und_schnittstellen/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -194,5 +194,7 @@ Webhook (Push-Prinzip): Der Client registriert eine Empfänger-URL beim Server.
<a href="../12_ap1_probepruefung_simulation/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a> <a href="../12_ap1_probepruefung_simulation/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -28,5 +28,7 @@
<a href="#" onclick="window.scrollTo({top: 0, behavior: 'smooth'}); return false;" class="text-sky-400 hover:underline">↑ Nach oben</a> <a href="#" onclick="window.scrollTo({top: 0, behavior: 'smooth'}); return false;" class="text-sky-400 hover:underline">↑ Nach oben</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -39,5 +39,7 @@ ORDER BY anzahl_bestellungen DESC;</pre>
<a href="#" onclick="window.scrollTo({top: 0, behavior: 'smooth'}); return false;" class="text-sky-400 hover:underline">↑ Nach oben</a> <a href="#" onclick="window.scrollTo({top: 0, behavior: 'smooth'}); return false;" class="text-sky-400 hover:underline">↑ Nach oben</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -28,5 +28,7 @@
<a href="#" onclick="window.scrollTo({top: 0, behavior: 'smooth'}); return false;" class="text-sky-400 hover:underline">↑ Nach oben</a> <a href="#" onclick="window.scrollTo({top: 0, behavior: 'smooth'}); return false;" class="text-sky-400 hover:underline">↑ Nach oben</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -186,5 +186,7 @@ AUSGABE alarm, versuche</pre>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -388,5 +388,7 @@ Roaming: WireGuard bindet Sitzungen an kryptografische Schlüssel und öffentlic
<a href="../02_lf10_serverdienste_und_automation/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a> <a href="../02_lf10_serverdienste_und_automation/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -254,5 +254,7 @@ Dynamic ARP Inspection (DAI): Verhindert ARP-Spoofing/Poisoning. Der Switch fän
<a href="../03_lf11_speicher_und_hochverfuegbarkeit/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a> <a href="../03_lf11_speicher_und_hochverfuegbarkeit/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -279,5 +279,7 @@ Asynchrone Replikation: Der Schreibbefehl wird der Anwendung sofort nach dem Sch
<a href="../04_lf12_virtualisierung_und_cloud/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a> <a href="../04_lf12_virtualisierung_und_cloud/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -255,5 +255,7 @@ Metriktypen:
<a href="../05_wiso_arbeitsrecht_und_wirtschaft/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a> <a href="../05_wiso_arbeitsrecht_und_wirtschaft/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

View file

@ -498,5 +498,7 @@ Zeichnung: Prokurist zeichnet mit "per procura" / "ppa. Vorname Nachname"; Handl
<a href="../06_betriebliche_projektarbeit_guide/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a> <a href="../06_betriebliche_projektarbeit_guide/index.html" class="ihk-btn ihk-btn-primary font-semibold">Nächstes Modul →</a>
</div> </div>
</div> </div>
<script src="../../../assets/courses_manifest.js"></script>
<script src="../../../assets/course_sidebar.js"></script>
</body> </body>
</html> </html>

Some files were not shown because too many files have changed in this diff Show more