Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c419c9ed1
|
||
|
|
a955a7636a
|
||
|
|
c978842812
|
||
|
|
61468d2d3a
|
||
|
|
a3c3e259b4
|
||
|
|
ac39f2b746
|
||
|
|
19ca5ad3e0
|
||
|
|
aea96edd09
|
||
|
|
a000cdbc8d
|
||
|
|
1d29a9f03c
|
||
|
|
24d7e5f660 | ||
|
|
a941b81d37
|
||
|
|
7bbfa74f1b | ||
|
|
7d0173f40e | ||
|
|
2680a745cf | ||
|
|
79aaa14c29 | ||
|
|
ec800d28ae | ||
|
|
80786cb040 | ||
|
|
67857b9bfd | ||
|
|
cedda338df | ||
|
|
bfe7f3576a | ||
|
|
6b21b45e01 | ||
|
|
aeaeed6867 | ||
|
|
72b7d51af9 | ||
|
|
bd5d7f0028 | ||
|
|
b6334035fc | ||
|
|
7626852ac1 | ||
|
|
754ff9436c | ||
|
|
0367f07166 | ||
|
|
c45ddc779c | ||
|
|
5b7170e5f4 | ||
|
|
cbebc1a6f7 | ||
|
|
8ed7796968 | ||
|
|
5d4d167cbd | ||
|
|
6c8688c9f6 | ||
|
|
54ba08cdbc | ||
|
|
777e0ffddb | ||
|
|
76f7ff3a46 | ||
|
|
b3c0994b7e | ||
|
|
fb361a2854 | ||
|
|
a2934f1327 | ||
|
|
558d0e5ecd | ||
|
|
6aba40e128 | ||
|
|
f6d9992a2c | ||
|
|
3e7fdf5dfc | ||
|
|
85ff73774c | ||
|
|
e5e7d80050 | ||
|
|
8c2f388c7f | ||
|
|
1bbe41b6fc | ||
|
|
fde51856ce | ||
|
|
8935f31091 | ||
|
|
81156284ac | ||
|
|
7dd46de5d9 | ||
|
|
7d8e9f596c | ||
|
|
ef0a55db77 | ||
|
|
ceb5f89320 | ||
|
|
a18afde2db | ||
|
|
38563e2142 | ||
|
|
aeb0adada9 | ||
|
|
e58dacd98c | ||
|
|
edc9225ccf | ||
|
|
5b94593d94 | ||
|
|
3bd6d7b459 | ||
|
|
c57db78c52 | ||
|
|
c1277cc737 | ||
|
|
fd8b107643 | ||
|
|
3a2e1a8d15 | ||
|
|
ac89d69365 | ||
|
|
552949811e | ||
|
|
030bb322a2 | ||
|
|
9631a1c45b | ||
|
|
4245ea2567 | ||
|
|
51146d3dfc | ||
|
|
fda4aca4c7 | ||
|
|
aff352fa91 | ||
|
|
ea7e905c61 | ||
|
|
512fbd9d3d | ||
|
|
f9185d25e0 | ||
|
|
4f3b680951 | ||
|
|
a2b1c0484a | ||
|
|
1480d31a54 | ||
|
|
514896db33 | ||
|
|
b21e2394d5 | ||
|
|
7da018d92c | ||
|
|
9e12447528 | ||
|
|
7e4d4a8a4b | ||
|
|
3fa1e1b1dc | ||
|
|
a8343c9937 | ||
|
|
b951341376 | ||
|
|
0fab5005df | ||
|
|
2755d4dee0 | ||
|
|
a3131851f0 | ||
|
|
7e878c27ef | ||
|
|
93e8ced463 | ||
|
|
58e0457165 | ||
|
|
d77b0f20c7 | ||
|
|
f7f4872c11 | ||
|
|
5f6369ad85 | ||
|
|
31790930de | ||
|
|
4fa64a6abd | ||
|
|
5c970053ee | ||
|
|
d19aa98f79 | ||
|
|
ccceac83e4 | ||
|
|
8f9934413a | ||
|
|
32c14ac412 | ||
|
|
2179f6caed | ||
|
|
b45a528faf | ||
|
|
64e67b7034 | ||
|
|
fc3f3a73f5 | ||
|
|
ee4d5435ed | ||
|
|
111d13420a | ||
|
|
3db80be669 | ||
|
|
8690e69e47 | ||
|
|
3f4be26dcb |
No files matched your search
@@ -2,6 +2,7 @@
|
|||||||
build/
|
build/
|
||||||
*.pdf
|
*.pdf
|
||||||
*.html
|
*.html
|
||||||
|
!slides/*/assets/demos/**/*.html
|
||||||
.dev-index/
|
.dev-index/
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
@@ -32,3 +33,4 @@ hdm-internettechnik-slides/
|
|||||||
# Temporary files
|
# Temporary files
|
||||||
*.tmp
|
*.tmp
|
||||||
*.bak
|
*.bak
|
||||||
|
.idea
|
||||||
@@ -0,0 +1,197 @@
|
|||||||
|
# AGENTS.md - Agent Guidelines for HdM Slides
|
||||||
|
|
||||||
|
This file contains comprehensive guidelines for agentic coding agents working on the HdM Slides project.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
This project builds presentation decks for Marp, supporting multiple courses:
|
||||||
|
- **223015b** - Dateiformate, Schnittstellen, Speichermedien (6 Kapitel)
|
||||||
|
- **223015c** - Internettechnologien (3 Kapitel)
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### Build Commands
|
||||||
|
```bash
|
||||||
|
# Development
|
||||||
|
make dev # Start single dev server on port 3000
|
||||||
|
npm run dev # Alternative command for development server
|
||||||
|
|
||||||
|
# Build
|
||||||
|
make build # Build all courses (HTML + PDF)
|
||||||
|
make build-b # Build 223015b only
|
||||||
|
make build-c # Build 223015c only
|
||||||
|
make html # HTML only builds
|
||||||
|
make pdf # PDF only builds
|
||||||
|
|
||||||
|
# Klausur Folien
|
||||||
|
make klausur # Extract klausurfolien for all courses
|
||||||
|
make klausur-b # Extract klausurfolien for 223015b
|
||||||
|
make klausur-c # Extract klausurfolien for 223015c
|
||||||
|
|
||||||
|
# Deployment
|
||||||
|
make deploy # Deploy all courses (requires explicit permission)
|
||||||
|
make deploy-b # Deploy 223015b only
|
||||||
|
make deploy-c # Deploy 223015c only
|
||||||
|
|
||||||
|
# Utilities
|
||||||
|
make qr URL=... # Generate QR code
|
||||||
|
make optimize-images COURSE=223015b # Resize images
|
||||||
|
make clean # Remove generated files
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
No specific test framework is used. To validate changes:
|
||||||
|
1. Start dev server: `make dev`
|
||||||
|
2. Open http://localhost:3000/223015b/ or /223015c/
|
||||||
|
3. Verify slides render correctly
|
||||||
|
4. Run `make build` to ensure no build errors
|
||||||
|
5. Check generated files in `build/` directory
|
||||||
|
|
||||||
|
## Code Style Guidelines
|
||||||
|
|
||||||
|
### File Structure
|
||||||
|
- Slides in `slides/<course>/` following naming pattern `NN-topic.md`
|
||||||
|
- Assets in `slides/<course>/assets/`
|
||||||
|
- Always reference images as `./assets/filename.png`
|
||||||
|
- Scripts in `scripts/`
|
||||||
|
- Themes in `themes/`
|
||||||
|
- Generated output in `build/` (gitignored)
|
||||||
|
|
||||||
|
### Naming Conventions
|
||||||
|
- Slide files: `NN-topic.md` (e.g., `01-grundlagen.md`, `02-bilder.md`)
|
||||||
|
- Images: `snake_case.jpg` or `kebab-case.jpg`
|
||||||
|
- Klausur files: `klausurfolien.md` (auto-generated)
|
||||||
|
- Function names in scripts: `snake_case`
|
||||||
|
- Variable names in scripts: `snake_case`
|
||||||
|
|
||||||
|
### Markdown Style
|
||||||
|
- Use ATX-style headers (`# ## ###`)
|
||||||
|
- YAML frontmatter for slide metadata at top of each file
|
||||||
|
- Never include a final `---` (creates empty slide)
|
||||||
|
- Use `<!-- _class: klausur -->` for exam-relevant slides
|
||||||
|
- Use relative paths for assets: `./assets/image.png`
|
||||||
|
|
||||||
|
### Script Style
|
||||||
|
- Use `#!/usr/bin/env bash` shebang
|
||||||
|
- Use `set -e` for error handling
|
||||||
|
- Use `2>/dev/null || true` for optional operations
|
||||||
|
- Define variables in UPPER_CASE at script top
|
||||||
|
- Use colors for terminal output: `\033[0;32m` etc.
|
||||||
|
|
||||||
|
### Git Workflow
|
||||||
|
- Commit messages: ALWAYS lowercase
|
||||||
|
- NEVER add co-authoring lines or generated footers
|
||||||
|
- Follow semantic naming: "add-...", "fix-...", "update-..."
|
||||||
|
- Commit changes to scripts, Makefile, documentation separately from slide content
|
||||||
|
|
||||||
|
## Agent Restrictions
|
||||||
|
|
||||||
|
### Security
|
||||||
|
- NEVER run commands outside `/home/mwc/Coding/hdm` folder
|
||||||
|
- NEVER run build/deploy commands without explicit user request
|
||||||
|
- NEVER run deploy commands (make deploy, scp, etc.) without explicit permission
|
||||||
|
|
||||||
|
### File Protection
|
||||||
|
Slide files in `slides/*/*.md` are main content files:
|
||||||
|
- **ALLOWED**: Adding slides, adjusting content, fixing typos, enhancing sections
|
||||||
|
- **FORBIDDEN** (without permission): Deleting slides, removing sections, bulk deletions
|
||||||
|
- Before ANY deletion: ALWAYS ask user for confirmation
|
||||||
|
|
||||||
|
### Klausur Handling
|
||||||
|
- Klausur files (`klausurfolien.md`) are auto-generated
|
||||||
|
- NEVER edit klausurfolien.md files directly
|
||||||
|
- To update klausurfolien: edit source slides with `<!-- _class: klausur -->` markers
|
||||||
|
- Run `make klausur` to regenerate
|
||||||
|
|
||||||
|
## Development Patterns
|
||||||
|
|
||||||
|
### Adding New Slides
|
||||||
|
1. Create new file following `NN-topic.md` pattern
|
||||||
|
2. Copy frontmatter from existing slides in the same course
|
||||||
|
3. Update Makefile `_KAPITEL` variable if needed
|
||||||
|
4. Test with `make dev`
|
||||||
|
|
||||||
|
### Modifying Existing Slides
|
||||||
|
1. Edit the appropriate markdown file in `slides/<course>/`
|
||||||
|
2. Maintain consistent styling with course theme
|
||||||
|
3. Preserve image paths as `./assets/...`
|
||||||
|
4. Test changes with dev server
|
||||||
|
|
||||||
|
### Working with Assets
|
||||||
|
1. Place images in `slides/<course>/assets/`
|
||||||
|
2. Use descriptive names: `diagram-network.jpg`, `example-code.png`
|
||||||
|
3. Optimize with `make optimize-images COURSE=223015b`
|
||||||
|
4. Reference as `./assets/filename.ext`
|
||||||
|
|
||||||
|
### Course-Specific Configuration
|
||||||
|
Each course has specific settings in Makefile:
|
||||||
|
- Course name and title
|
||||||
|
- Kapitel list (slide files)
|
||||||
|
- Deploy path
|
||||||
|
- Theme colors (in generate-index.sh)
|
||||||
|
|
||||||
|
## Common Tasks
|
||||||
|
|
||||||
|
### Debugging Build Issues
|
||||||
|
1. Check Makefile syntax: `make -n build`
|
||||||
|
2. Verify Marp CLI installation: `npx @marp-team/marp-cli --version`
|
||||||
|
3. Check file permissions: `ls -la slides/`
|
||||||
|
4. Validate markdown syntax with dev server
|
||||||
|
|
||||||
|
### Updating Course Structure
|
||||||
|
1. Update `_KAPITEL` variables in Makefile
|
||||||
|
2. Ensure slide files follow naming convention
|
||||||
|
3. Update course-specific themes if needed
|
||||||
|
4. Test both dev and build processes
|
||||||
|
|
||||||
|
### Working with Themes
|
||||||
|
- Custom theme in `themes/custom-theme.css`
|
||||||
|
- Course themes defined in individual slide frontmatter
|
||||||
|
- Use consistent color schemes per course
|
||||||
|
- Test theme changes across all slides
|
||||||
|
|
||||||
|
## Deployment Process
|
||||||
|
|
||||||
|
Deployment to production server requires explicit permission:
|
||||||
|
1. Build process: `make build` (HTML + PDF)
|
||||||
|
2. Index generation: automatically handled
|
||||||
|
3. Deploy to remote server via SCP
|
||||||
|
4. Root index deployment
|
||||||
|
|
||||||
|
**IMPORTANT**: Never run deployment commands without explicit user permission.
|
||||||
|
|
||||||
|
## Tools and Dependencies
|
||||||
|
|
||||||
|
### Core Dependencies
|
||||||
|
- Marp CLI for slide rendering
|
||||||
|
- Bash scripts for automation
|
||||||
|
- Make for build orchestration
|
||||||
|
- Git for version control
|
||||||
|
|
||||||
|
### Optional Tools
|
||||||
|
- qrencode for QR generation (via nix)
|
||||||
|
- ImageMagick for image optimization
|
||||||
|
- Python 3 for simple HTTP server (legacy)
|
||||||
|
|
||||||
|
## Testing Strategy
|
||||||
|
|
||||||
|
Since there's no formal test suite:
|
||||||
|
1. Manual testing with dev server
|
||||||
|
2. Build process validation
|
||||||
|
3. Slide rendering checks
|
||||||
|
4. Asset path verification
|
||||||
|
5. Cross-browser compatibility checks (important)
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
- **Port conflicts**: Use `make dev-kill` to clean up processes
|
||||||
|
- **Build failures**: Check file permissions and Marp CLI installation
|
||||||
|
- **Asset loading**: Verify relative paths and file existence
|
||||||
|
- **Deploy issues**: Check SSH keys and remote permissions
|
||||||
|
|
||||||
|
### Getting Help
|
||||||
|
1. Check this AGENTS.md file first
|
||||||
|
2. Review Makefile targets and scripts
|
||||||
|
3. Test changes incrementally
|
||||||
|
4. Maintain backup of working configurations
|
||||||
@@ -4,18 +4,19 @@ This project builds presentation decks for Marp, supporting multiple courses.
|
|||||||
|
|
||||||
## Courses
|
## Courses
|
||||||
|
|
||||||
- **223015b** - Dateiformate, Schnittstellen, Speichermedien (6 Termine)
|
- **223015b** - Dateiformate, Schnittstellen, Speichermedien (6 Kapitel)
|
||||||
- **223015c** - Internettechnologien (3 Termine)
|
- **223015c** - Internettechnologien (3 Kapitel)
|
||||||
|
|
||||||
## Agent Restrictions
|
## Agent Restrictions
|
||||||
|
|
||||||
- Agent NEVER runs commands outside this folder
|
- Agent NEVER runs commands outside this folder
|
||||||
- Agent NEVER runs build/deploy commands without explicit user request
|
- Agent NEVER runs build/deploy commands without explicit user request
|
||||||
- Agent NEVER runs deploy commands (make deploy, scp, etc.) without explicit user permission
|
- Agent NEVER runs deploy commands (make deploy, scp, etc.) without explicit user permission
|
||||||
|
- Agent NEVER runs `git checkout --` or `git restore` on files with uncommitted work. To undo specific changes, use targeted Edit operations instead.
|
||||||
|
|
||||||
## Critical File Protection
|
## Critical File Protection
|
||||||
|
|
||||||
Slide files in `courses/*/slides/*.md` are main content files:
|
Slide files in `slides/*/*.md` are main content files:
|
||||||
- ALLOWED: Adding slides, adjusting content, fixing typos, enhancing sections
|
- ALLOWED: Adding slides, adjusting content, fixing typos, enhancing sections
|
||||||
- FORBIDDEN (without permission): Deleting slides, removing sections, bulk deletions
|
- FORBIDDEN (without permission): Deleting slides, removing sections, bulk deletions
|
||||||
- Before ANY deletion: ALWAYS ask user for confirmation
|
- Before ANY deletion: ALWAYS ask user for confirmation
|
||||||
@@ -23,9 +24,9 @@ Slide files in `courses/*/slides/*.md` are main content files:
|
|||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
courses/
|
slides/
|
||||||
├── 223015b/slides/ # Dateiformate course
|
├── 223015b/ # Dateiformate course
|
||||||
└── 223015c/slides/ # Internettechnik course
|
└── 223015c/ # Internettechnik course
|
||||||
scripts/ # Shared scripts
|
scripts/ # Shared scripts
|
||||||
themes/ # Custom Marp themes
|
themes/ # Custom Marp themes
|
||||||
build/ # Generated output (gitignored)
|
build/ # Generated output (gitignored)
|
||||||
@@ -34,34 +35,33 @@ build/ # Generated output (gitignored)
|
|||||||
## Build Commands
|
## Build Commands
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make dev-b # Dev server 223015b (port 1312)
|
make dev # Marp live server all courses (port 1312, HMR)
|
||||||
make dev-c # Dev server 223015c (port 1313)
|
make dev-b # Marp live server 223015b (port 1313, HMR)
|
||||||
|
make dev-c # Marp live server 223015c (port 1314, HMR)
|
||||||
make build # Build all courses
|
make build # Build all courses
|
||||||
make build-b # Build 223015b only
|
make build-b # Build 223015b only
|
||||||
make build-c # Build 223015c only
|
make build-c # Build 223015c only
|
||||||
make html # HTML only
|
make html # HTML only
|
||||||
make pdf # PDF only
|
make pdf # PDF only
|
||||||
|
make klausur # Extract klausur slides → slides/*/klausur.md
|
||||||
make deploy # Deploy all (ASK FIRST!)
|
make deploy # Deploy all (ASK FIRST!)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Nix Flake Commands
|
## Nix Flake Commands
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
nix develop # Dev shell with all tools
|
nix develop # Dev shell with all tools (node 22, npm, make)
|
||||||
nix run .#qr -- "https://example.com" # Generate QR code
|
|
||||||
nix run .#qr-slides -- 223015b # QR for course
|
|
||||||
nix run .#optimize-img -- <path> # Optimize images
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Code Style Guidelines
|
## Code Style Guidelines
|
||||||
|
|
||||||
### File Structure
|
### File Structure
|
||||||
- Slides in `courses/<course>/slides/`
|
- Slides in `slides/<course>/`
|
||||||
- Assets in `courses/<course>/slides/assets/`
|
- Assets in `slides/<course>/assets/`
|
||||||
- Always reference images as `./assets/filename.png`
|
- Always reference images as `./assets/filename.png`
|
||||||
|
|
||||||
### Naming Conventions
|
### Naming Conventions
|
||||||
- Slide files: `YYYY-MM-DD-termin-N-topic.md`
|
- Slide files: `NN-topic.md` (e.g., `01-grundlagen.md`)
|
||||||
- Images: `snake_case.jpg` or `kebab-case.jpg`
|
- Images: `snake_case.jpg` or `kebab-case.jpg`
|
||||||
|
|
||||||
### Markdown Style
|
### Markdown Style
|
||||||
|
|||||||
@@ -1,25 +1,19 @@
|
|||||||
# HdM Slides - Unified Makefile
|
# HdM Slides - Unified Makefile
|
||||||
# Supports multiple courses: 223015b (Dateiformate) and 223015c (Internettechnik)
|
# Supports multiple courses: 223015b (Dateiformate) and 223015c (Internettechnik)
|
||||||
|
|
||||||
.PHONY: help dev dev-b dev-c build build-b build-c pdf html clean install deploy qr optimize-images
|
.PHONY: help dev dev-b dev-c build build-b build-c pdf html klausur clean install deploy qr optimize-images
|
||||||
|
|
||||||
# Course configuration
|
# Course configuration
|
||||||
COURSES = 223015b 223015c
|
COURSES = 223015b 223015c
|
||||||
COURSE_DIR = courses
|
SLIDES_DIR = slides
|
||||||
|
|
||||||
# Port configuration (index starts at BASE_PORT, courses increment from there)
|
|
||||||
BASE_PORT = 1310
|
|
||||||
INDEX_PORT = $(BASE_PORT)
|
|
||||||
|
|
||||||
# Course-specific settings
|
# Course-specific settings
|
||||||
223015b_NAME = Dateiformate, Schnittstellen, Speichermedien
|
223015b_NAME = Dateiformate, Schnittstellen, Speichermedien
|
||||||
223015b_PORT = 1311
|
223015b_KAPITEL = 00-intro 01-grundlagen-text-audio 02-bild-audio-video 03-speichermedien-schnittstellen 04-distribution-apis-zukunft 05-vertiefung-offene-fragen klausurfolien klausurfragen
|
||||||
223015b_TERMINS = 2025-12-19-termin-0-intro 2025-12-19-termin-1-grundlagen-text-audio 2026-01-09-termin-2-bild-audio-video 2026-01-23-termin-3-speichermedien-schnittstellen 2026-01-30-termin-4-distribution-apis-zukunft 2026-xx-xx-termin-5-vertiefung-offene-fragen
|
|
||||||
223015b_DEPLOY_PATH = /home/tengo/html/hdm/223015b
|
223015b_DEPLOY_PATH = /home/tengo/html/hdm/223015b
|
||||||
|
|
||||||
223015c_NAME = Internettechnologien
|
223015c_NAME = Internettechnologien
|
||||||
223015c_PORT = 1312
|
223015c_KAPITEL = 01-geschichte-grundlagen-html 02-netzwerke-protokolle-css 03-interaktivitaet-javascript klausurfolien klausurfragen
|
||||||
223015c_TERMINS = 2025-12-20-termin-1-geschichte-grundlagen-html 2026-01-10-termin-2-netzwerke-protokolle-css 2026-01-24-termin-3-interaktivitaet-javascript
|
|
||||||
223015c_DEPLOY_PATH = /home/tengo/html/hdm/223015c
|
223015c_DEPLOY_PATH = /home/tengo/html/hdm/223015c
|
||||||
|
|
||||||
DEPLOY_HOST = tengo@tuttle.uberspace.de
|
DEPLOY_HOST = tengo@tuttle.uberspace.de
|
||||||
@@ -33,9 +27,9 @@ help:
|
|||||||
@echo " 223015c - Internettechnologien"
|
@echo " 223015c - Internettechnologien"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Development:"
|
@echo "Development:"
|
||||||
@echo " make dev - Both servers + index (ports 1311, 1312, 1313)"
|
@echo " make dev - Marp live server all courses (port 1312, HMR)"
|
||||||
@echo " make dev-b - Dev server for 223015b (port 1312)"
|
@echo " make dev-b - Marp live server 223015b (port 1313, HMR)"
|
||||||
@echo " make dev-c - Dev server for 223015c (port 1313)"
|
@echo " make dev-c - Marp live server 223015c (port 1314, HMR)"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Build:"
|
@echo "Build:"
|
||||||
@echo " make build - Build all courses"
|
@echo " make build - Build all courses"
|
||||||
@@ -43,6 +37,7 @@ help:
|
|||||||
@echo " make build-c - Build 223015c only"
|
@echo " make build-c - Build 223015c only"
|
||||||
@echo " make pdf - Export all to PDF"
|
@echo " make pdf - Export all to PDF"
|
||||||
@echo " make html - Export all to HTML"
|
@echo " make html - Export all to HTML"
|
||||||
|
@echo " make klausur - Extract klausurfolien slides"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Tools:"
|
@echo "Tools:"
|
||||||
@echo " make qr URL=... - Generate QR code for URL"
|
@echo " make qr URL=... - Generate QR code for URL"
|
||||||
@@ -62,36 +57,32 @@ build/.exists:
|
|||||||
@mkdir -p build/223015b build/223015c
|
@mkdir -p build/223015b build/223015c
|
||||||
@touch $@
|
@touch $@
|
||||||
|
|
||||||
# Development servers
|
# Development server (Marp live server with HMR)
|
||||||
dev:
|
dev:
|
||||||
@./scripts/dev-server.sh
|
@./scripts/dev-server.sh
|
||||||
|
|
||||||
dev-kill:
|
|
||||||
@-pkill -f "python3 -m http.server" 2>/dev/null || true
|
|
||||||
@-pkill -f "marp-cli.*--server" 2>/dev/null || true
|
|
||||||
@sleep 0.5
|
|
||||||
|
|
||||||
dev-b:
|
dev-b:
|
||||||
@echo "Starting 223015b dev server on port $(223015b_PORT)..."
|
@./scripts/dev-server.sh 223015b 1313
|
||||||
@echo "Open: http://localhost:$(223015b_PORT)"
|
|
||||||
PORT=$(223015b_PORT) npx @marp-team/marp-cli --server $(COURSE_DIR)/223015b/slides/
|
|
||||||
|
|
||||||
dev-c:
|
dev-c:
|
||||||
@echo "Starting 223015c dev server on port $(223015c_PORT)..."
|
@./scripts/dev-server.sh 223015c 1314
|
||||||
@echo "Open: http://localhost:$(223015c_PORT)"
|
|
||||||
PORT=$(223015c_PORT) npx @marp-team/marp-cli --server $(COURSE_DIR)/223015c/slides/
|
dev-kill:
|
||||||
|
@-fuser -k 1312/tcp 2>/dev/null || true
|
||||||
|
@-fuser -k 1313/tcp 2>/dev/null || true
|
||||||
|
@-fuser -k 1314/tcp 2>/dev/null || true
|
||||||
|
|
||||||
# Build functions
|
# Build functions
|
||||||
define build_course
|
define build_course
|
||||||
@echo "Building $(1)..."
|
@echo "Building $(1)..."
|
||||||
@mkdir -p build/$(1)
|
@mkdir -p build/$(1)
|
||||||
@cp -r $(COURSE_DIR)/$(1)/slides/assets build/$(1)/ 2>/dev/null || true
|
@cp -r $(SLIDES_DIR)/$(1)/assets build/$(1)/ 2>/dev/null || true
|
||||||
@cp -r $(COURSE_DIR)/$(1)/slides/materials build/$(1)/ 2>/dev/null || true
|
@cp -r $(SLIDES_DIR)/$(1)/materials build/$(1)/ 2>/dev/null || true
|
||||||
@for f in $($(1)_TERMINS); do \
|
@for f in $($(1)_KAPITEL); do \
|
||||||
if [ -f "$(COURSE_DIR)/$(1)/slides/$$f.md" ]; then \
|
if [ -f "$(SLIDES_DIR)/$(1)/$$f.md" ]; then \
|
||||||
echo " Building $$f..."; \
|
echo " Building $$f..."; \
|
||||||
npx @marp-team/marp-cli $(COURSE_DIR)/$(1)/slides/$$f.md -o build/$(1)/$$f.html; \
|
npx @marp-team/marp-cli $(SLIDES_DIR)/$(1)/$$f.md -o build/$(1)/$$f.html; \
|
||||||
npx @marp-team/marp-cli $(COURSE_DIR)/$(1)/slides/$$f.md --pdf --allow-local-files -o build/$(1)/$$f.pdf; \
|
npx @marp-team/marp-cli $(SLIDES_DIR)/$(1)/$$f.md --pdf --allow-local-files -o build/$(1)/$$f.pdf; \
|
||||||
fi \
|
fi \
|
||||||
done
|
done
|
||||||
@./scripts/generate-index.sh $(1) build/$(1)
|
@./scripts/generate-index.sh $(1) build/$(1)
|
||||||
@@ -110,12 +101,12 @@ build: build-b build-c
|
|||||||
define html_course
|
define html_course
|
||||||
@echo "Building HTML for $(1)..."
|
@echo "Building HTML for $(1)..."
|
||||||
@mkdir -p build/$(1)
|
@mkdir -p build/$(1)
|
||||||
@cp -r $(COURSE_DIR)/$(1)/slides/assets build/$(1)/ 2>/dev/null || true
|
@cp -r $(SLIDES_DIR)/$(1)/assets build/$(1)/ 2>/dev/null || true
|
||||||
@cp -r $(COURSE_DIR)/$(1)/slides/materials build/$(1)/ 2>/dev/null || true
|
@cp -r $(SLIDES_DIR)/$(1)/materials build/$(1)/ 2>/dev/null || true
|
||||||
@for f in $($(1)_TERMINS); do \
|
@for f in $($(1)_KAPITEL); do \
|
||||||
if [ -f "$(COURSE_DIR)/$(1)/slides/$$f.md" ]; then \
|
if [ -f "$(SLIDES_DIR)/$(1)/$$f.md" ]; then \
|
||||||
echo " $$f.html"; \
|
echo " $$f.html"; \
|
||||||
npx @marp-team/marp-cli $(COURSE_DIR)/$(1)/slides/$$f.md -o build/$(1)/$$f.html; \
|
npx @marp-team/marp-cli $(SLIDES_DIR)/$(1)/$$f.md -o build/$(1)/$$f.html; \
|
||||||
fi \
|
fi \
|
||||||
done
|
done
|
||||||
@./scripts/generate-index.sh $(1) build/$(1)
|
@./scripts/generate-index.sh $(1) build/$(1)
|
||||||
@@ -133,10 +124,10 @@ html: html-b html-c
|
|||||||
define pdf_course
|
define pdf_course
|
||||||
@echo "Building PDFs for $(1)..."
|
@echo "Building PDFs for $(1)..."
|
||||||
@mkdir -p build/$(1)
|
@mkdir -p build/$(1)
|
||||||
@for f in $($(1)_TERMINS); do \
|
@for f in $($(1)_KAPITEL); do \
|
||||||
if [ -f "$(COURSE_DIR)/$(1)/slides/$$f.md" ]; then \
|
if [ -f "$(SLIDES_DIR)/$(1)/$$f.md" ]; then \
|
||||||
echo " $$f.pdf"; \
|
echo " $$f.pdf"; \
|
||||||
npx @marp-team/marp-cli $(COURSE_DIR)/$(1)/slides/$$f.md --pdf --allow-local-files -o build/$(1)/$$f.pdf; \
|
npx @marp-team/marp-cli $(SLIDES_DIR)/$(1)/$$f.md --pdf --allow-local-files -o build/$(1)/$$f.pdf; \
|
||||||
fi \
|
fi \
|
||||||
done
|
done
|
||||||
endef
|
endef
|
||||||
@@ -149,6 +140,16 @@ pdf-c: build/.exists
|
|||||||
|
|
||||||
pdf: pdf-b pdf-c
|
pdf: pdf-b pdf-c
|
||||||
|
|
||||||
|
# Klausur slide extraction
|
||||||
|
klausur-b:
|
||||||
|
@./scripts/extract-klausur.sh 223015b
|
||||||
|
|
||||||
|
klausur-c:
|
||||||
|
@./scripts/extract-klausur.sh 223015c
|
||||||
|
|
||||||
|
klausur: klausur-b klausur-c
|
||||||
|
@echo "Klausurfolien slides extracted for all courses!"
|
||||||
|
|
||||||
# QR Code generation (uses nix-shell)
|
# QR Code generation (uses nix-shell)
|
||||||
qr:
|
qr:
|
||||||
ifndef URL
|
ifndef URL
|
||||||
@@ -174,9 +175,9 @@ ifndef COURSE
|
|||||||
@echo "Usage: make optimize-images COURSE=223015b"
|
@echo "Usage: make optimize-images COURSE=223015b"
|
||||||
else
|
else
|
||||||
@echo "Optimizing images for $(COURSE)..."
|
@echo "Optimizing images for $(COURSE)..."
|
||||||
@mkdir -p $(COURSE_DIR)/$(COURSE)/slides/assets-original
|
@mkdir -p $(SLIDES_DIR)/$(COURSE)/assets-original
|
||||||
@nix-shell -p imagemagick --run 'for img in $(COURSE_DIR)/$(COURSE)/slides/assets/*.png $(COURSE_DIR)/$(COURSE)/slides/assets/*.jpg 2>/dev/null; do \
|
@nix-shell -p imagemagick --run 'for img in $(SLIDES_DIR)/$(COURSE)/assets/*.png $(SLIDES_DIR)/$(COURSE)/assets/*.jpg 2>/dev/null; do \
|
||||||
[ -f "$$img" ] && cp "$$img" $(COURSE_DIR)/$(COURSE)/slides/assets-original/ && \
|
[ -f "$$img" ] && cp "$$img" $(SLIDES_DIR)/$(COURSE)/assets-original/ && \
|
||||||
magick "$$img" -resize "1920x>" -quality 85 "$$img" && echo " Optimized: $$(basename $$img)"; \
|
magick "$$img" -resize "1920x>" -quality 85 "$$img" && echo " Optimized: $$(basename $$img)"; \
|
||||||
done || true'
|
done || true'
|
||||||
@echo "Done! Originals in assets-original/"
|
@echo "Done! Originals in assets-original/"
|
||||||
@@ -187,7 +188,8 @@ HDM_DEPLOY_PATH = /home/tengo/html/hdm
|
|||||||
|
|
||||||
build-index: build/.exists
|
build-index: build/.exists
|
||||||
@echo "Building root index..."
|
@echo "Building root index..."
|
||||||
@echo '<!DOCTYPE html><html lang="de"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>HdM Vorlesungen</title><style>*{box-sizing:border-box;margin:0;padding:0}body{font-family:-apple-system,BlinkMacSystemFont,"SF Pro Display","Segoe UI",Roboto,sans-serif;max-width:720px;margin:0 auto;padding:3rem 1.5rem;background:#fafafa;color:#1d1d1f;line-height:1.5}h1{font-size:2rem;font-weight:600;letter-spacing:-0.02em;margin-bottom:.5rem}.subtitle{color:#86868b;font-size:1rem}.courses{margin-top:2rem;display:flex;flex-direction:column;gap:.75rem}a.course{display:block;background:#fff;border-radius:12px;padding:1.5rem;text-decoration:none;color:inherit;box-shadow:0 1px 3px rgba(0,0,0,0.08);transition:all .2s ease;cursor:pointer}a.course:hover{transform:translateY(-2px);box-shadow:0 4px 12px rgba(0,0,0,0.12)}.course-label{font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em}.course-b .course-label{color:#1e5f8a}.course-c .course-label{color:#d63384}.course-title{font-size:1.15rem;font-weight:500;color:#1d1d1f;margin:.25rem 0}.course-info{font-size:.85rem;color:#86868b}.section-title{font-size:1rem;font-weight:600;color:#86868b;margin-top:2.5rem;margin-bottom:.75rem}.references{display:flex;flex-direction:column;gap:.75rem}footer{margin-top:2.5rem;padding-top:1.5rem;border-top:1px solid #e5e5e7;color:#86868b;font-size:.85rem}footer a{color:#1d1d1f;text-decoration:none}footer a:hover{text-decoration:underline}.qr-section{margin-top:2.5rem;padding:1.5rem;background:#fff;border-radius:12px;box-shadow:0 1px 3px rgba(0,0,0,0.08);text-align:center}.qr-code{width:100%;height:auto}.qr-url{margin-top:.75rem;font-size:.85rem;color:#86868b}</style></head><body><h1>HdM Vorlesungen</h1><p class="subtitle">Wintersemester 2025/26 · Michael Czechowski</p><div class="courses"><a class="course course-b" href="223015b/"><span class="course-label">223015b</span><div class="course-title">Dateiformate, Schnittstellen, Speichermedien & Distributionswege</div><span class="course-info">6 Termine · Modul "Technik 1"</span></a><a class="course course-c" href="223015c/"><span class="course-label">223015c</span><div class="course-title">Grundlagen IT- und Internettechnik</div><span class="course-info">3 Termine · Modul "Technik 1"</span></a></div><h2 class="section-title">Referenzen</h2><div class="references"><a class="course" href="https://codecrispi.es/"><span class="course-label">Plattform</span><div class="course-title">Code Crispies</div><span class="course-info">Selbstlernplattform</span></a></div><div class="qr-section"><img src="qr-root.svg" alt="QR Code" class="qr-code"><p class="qr-url">https://librete.ch/hdm/</p></div><footer><a href="mailto:mail@librete.ch">Kontakt</a></footer></body></html>' > build/index.html
|
@mkdir -p build
|
||||||
|
@./scripts/generate-root-index.sh
|
||||||
|
|
||||||
# Deploy
|
# Deploy
|
||||||
define deploy_course
|
define deploy_course
|
||||||
|
|||||||
@@ -1,182 +1,97 @@
|
|||||||
# HdM Slides
|
# HdM Slides
|
||||||
|
|
||||||
**Modul "Technik 1"** - 1. Semester - Digital- und Medienwirtschaft
|
Presentation slides for HdM Stuttgart courses, built with [Marp](https://marp.app/).
|
||||||
Hochschule der Medien Stuttgart - Wintersemester 2025/26
|
|
||||||
|
|
||||||
---
|
## Courses
|
||||||
|
|
||||||
## Kurse
|
| Code | Title | Kapitel |
|
||||||
|
|------|-------|---------|
|
||||||
|
| 223015b | Dateiformate, Schnittstellen, Speichermedien | 6 |
|
||||||
|
| 223015c | Internettechnologien | 3 |
|
||||||
|
|
||||||
### 223015b - Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
## Project Structure
|
||||||
|
|
||||||
| # | Datum | Thema |
|
|
||||||
|---|-------|-------|
|
|
||||||
| 0 | 19.12.2025 | Intro |
|
|
||||||
| 1 | 19.12.2025 | Grundlagen, Text & Audio |
|
|
||||||
| 2 | 09.01.2026 | Bild- & Videoformate |
|
|
||||||
| 3 | 23.01.2026 | Speichermedien & Schnittstellen |
|
|
||||||
| 4 | 30.01.2026 | Distribution, APIs & Zukunft |
|
|
||||||
| 5 | TBA | Vertiefung & offene Fragen |
|
|
||||||
|
|
||||||
### 223015c - Internettechnologien
|
|
||||||
|
|
||||||
| # | Datum | Thema |
|
|
||||||
|---|-------|-------|
|
|
||||||
| 1 | 20.12.2025 | Geschichte, Grundlagen & HTML |
|
|
||||||
| 2 | 10.01.2026 | Netzwerke, Protokolle & CSS |
|
|
||||||
| 3 | 24.01.2026 | Interaktivitat & JavaScript |
|
|
||||||
|
|
||||||
**Dozent:** Michael Czechowski - mail@librete.ch
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
### Mit Nix (empfohlen)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Development shell mit allen Tools
|
|
||||||
nix develop
|
|
||||||
|
|
||||||
# Oder direkt QR-Code generieren
|
|
||||||
nix run .#qr -- "https://example.com"
|
|
||||||
nix run .#qr-slides -- 223015b
|
|
||||||
```
|
```
|
||||||
|
slides/
|
||||||
### Ohne Nix
|
├── 223015b/ # Dateiformate course
|
||||||
|
│ ├── 00-intro.md
|
||||||
```bash
|
│ ├── 01-grundlagen-text-audio.md
|
||||||
npm install
|
│ └── ...
|
||||||
make dev-b # 223015b auf Port 1312
|
└── 223015c/ # Internettechnik course
|
||||||
make dev-c # 223015c auf Port 1313
|
├── 01-geschichte-grundlagen-html.md
|
||||||
|
└── ...
|
||||||
|
scripts/ # Build scripts
|
||||||
|
build/ # Generated output (gitignored)
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
### Dev Server starten
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make dev-b # 223015b (Dateiformate) - http://localhost:1312
|
# Start development server (hot reload)
|
||||||
make dev-c # 223015c (Internettechnik) - http://localhost:1313
|
make dev # Single server for all courses (port 3000)
|
||||||
|
|
||||||
|
# Access individual courses:
|
||||||
|
# 223015b: http://localhost:3000/223015b/
|
||||||
|
# 223015c: http://localhost:3000/223015c/
|
||||||
```
|
```
|
||||||
|
|
||||||
### Build
|
## Build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make build # Alle Kurse (HTML + PDF)
|
make build # Build all (HTML + PDF)
|
||||||
make build-b # Nur 223015b
|
make build-b # Build 223015b only
|
||||||
make build-c # Nur 223015c
|
make build-c # Build 223015c only
|
||||||
make html # Nur HTML
|
make html # HTML only
|
||||||
make pdf # Nur PDF
|
make pdf # PDF only
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploy
|
## Klausur Folien
|
||||||
|
|
||||||
|
Extract exam-relevant slides (marked with `<!-- _class: klausur -->`) into a single file:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make deploy # Alle Kurse
|
make klausur # Extract all courses
|
||||||
make deploy-b # Nur 223015b
|
make klausur-b # 223015b only
|
||||||
make deploy-c # Nur 223015c
|
make klausur-c # 223015c only
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
Output: `slides/<course>/klausurfolien.md`
|
||||||
|
|
||||||
|
The generated file includes:
|
||||||
|
- A title slide per kapitel for orientation
|
||||||
|
- All slides marked with `<!-- _class: klausur -->`
|
||||||
|
|
||||||
## Tools
|
## Tools
|
||||||
|
|
||||||
### QR-Code Generator
|
```bash
|
||||||
|
make qr URL=https://example.com # Generate QR code
|
||||||
|
make qr-slides COURSE=223015b # QR for course URL
|
||||||
|
make optimize-images COURSE=223015b # Resize images
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deploy
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Mit Nix
|
make deploy # Deploy all courses
|
||||||
nix run .#qr -- "https://librete.ch/hdm/223015b/"
|
make deploy-b # Deploy 223015b only
|
||||||
nix run .#qr -- "https://example.com" output.png
|
make deploy-c # Deploy 223015c only
|
||||||
|
|
||||||
# Mit Make
|
|
||||||
make qr URL=https://example.com
|
|
||||||
make qr URL=https://example.com OUTPUT=my-qr.png
|
|
||||||
|
|
||||||
# Fur Kurse
|
|
||||||
make qr-slides COURSE=223015b
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Bilder optimieren
|
## Marking Slides as Klausur-Relevant
|
||||||
|
|
||||||
```bash
|
Add this comment block after the slide separator:
|
||||||
# Mit Nix
|
|
||||||
nix run .#optimize-img -- courses/223015b/slides/assets/
|
|
||||||
|
|
||||||
# Mit Make
|
|
||||||
make optimize-images COURSE=223015b
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Projektstruktur
|
|
||||||
|
|
||||||
```
|
|
||||||
hdm/
|
|
||||||
├── courses/
|
|
||||||
│ ├── 223015b/
|
|
||||||
│ │ └── slides/
|
|
||||||
│ │ ├── 2025-12-19-termin-1-grundlagen-text-audio.md
|
|
||||||
│ │ ├── assets/
|
|
||||||
│ │ └── materials/
|
|
||||||
│ └── 223015c/
|
|
||||||
│ └── slides/
|
|
||||||
│ ├── 2025-12-20-termin-1-geschichte-grundlagen-html.md
|
|
||||||
│ └── assets/
|
|
||||||
├── scripts/
|
|
||||||
│ └── generate-index.sh
|
|
||||||
├── themes/
|
|
||||||
│ └── custom-theme.css
|
|
||||||
├── build/ # Generated output
|
|
||||||
├── flake.nix # Nix flake with tools
|
|
||||||
├── Makefile
|
|
||||||
└── package.json
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Slides erstellen
|
|
||||||
|
|
||||||
### Frontmatter
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
marp: true
|
|
||||||
theme: uncover
|
|
||||||
paginate: true
|
|
||||||
backgroundColor: #fff
|
|
||||||
---
|
|
||||||
```
|
|
||||||
|
|
||||||
### Slide-Trennung
|
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# Slide 1
|
|
||||||
|
|
||||||
Content
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Slide 2
|
<!-- _class: klausur -->
|
||||||
|
<!-- _header: '' -->
|
||||||
|
<!-- _footer: '' -->
|
||||||
|
<!-- _backgroundColor: #e3f2fd -->
|
||||||
|
|
||||||
More content
|
# Your Slide Title
|
||||||
|
|
||||||
|
Content here...
|
||||||
```
|
```
|
||||||
|
|
||||||
### Bilder
|
The `klausur` class adds a visual indicator (diagonal stripes) during presentation.
|
||||||
|
|
||||||
```markdown
|
|
||||||

|
|
||||||
```
|
|
||||||
|
|
||||||
### Themes
|
|
||||||
|
|
||||||
Built-in: `default`, `gaia`, `uncover`
|
|
||||||
Custom: in `themes/` Verzeichnis
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)
|
|
||||||
@@ -1,240 +0,0 @@
|
|||||||
---
|
|
||||||
marp: true
|
|
||||||
theme: gaia
|
|
||||||
paginate: true
|
|
||||||
backgroundColor: #fff
|
|
||||||
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege"
|
|
||||||
footer: "Michael Czechowski – HdM Stuttgart – WS 2025/26"
|
|
||||||
title: Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
|
||||||
---
|
|
||||||
|
|
||||||
<style>
|
|
||||||
:root {
|
|
||||||
--color-foreground: #1a1a2e;
|
|
||||||
--color-highlight: #1e5f8a;
|
|
||||||
--color-dimmed: #4a4a6a;
|
|
||||||
}
|
|
||||||
section.invert {
|
|
||||||
--color-foreground: #fff;
|
|
||||||
}
|
|
||||||
section {
|
|
||||||
font-size: 1.7rem;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
color: #1e5f8a;
|
|
||||||
}
|
|
||||||
section.invert h1 {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
color: #1f2937;
|
|
||||||
}
|
|
||||||
pre {
|
|
||||||
background: #0f0f23;
|
|
||||||
color: #5fb3e4;
|
|
||||||
border-radius: 8px;
|
|
||||||
border-left: 3px solid #1e5f8a;
|
|
||||||
}
|
|
||||||
pre code {
|
|
||||||
background: transparent;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
code {
|
|
||||||
background: #1a1a2e;
|
|
||||||
color: #5fb3e4;
|
|
||||||
padding: 0.15em 0.4em;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: var(--color-highlight);
|
|
||||||
}
|
|
||||||
section.klausur {
|
|
||||||
background: #e3f2fd !important;
|
|
||||||
}
|
|
||||||
section.klausur footer {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- _class: invert -->
|
|
||||||
<!-- _header: '' -->
|
|
||||||
<!-- _backgroundColor: #000 -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
# Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
|
||||||
|
|
||||||
**223015b** · Modul "Technik 1" · 1. Semester
|
|
||||||
Digital- und Medienwirtschaft
|
|
||||||
Hochschule der Medien Stuttgart
|
|
||||||
|
|
||||||
**Wintersemester 2025/26**
|
|
||||||
|
|
||||||
[https://librete.ch/hdm/223015b/](https://librete.ch/hdm/223015b/)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _class: lead -->
|
|
||||||
|
|
||||||
# Willkommen!
|
|
||||||
## Einführung
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Über mich
|
|
||||||
|
|
||||||
**Michael Czechowski**
|
|
||||||
|
|
||||||
- Irgendwas mit IT, Cloud und AI
|
|
||||||
- Schwerpunkte:
|
|
||||||
- Web-Technologien, Barriere-Armut, Systemarchitektur, Open Source
|
|
||||||
- Hintergrund:
|
|
||||||
- Philosophie (Uni Stuttgart) -> NO degree
|
|
||||||
- Wirtschafts-Informatik (Leibniz-FH) -> B.Sc.
|
|
||||||
- Kontakt: mail@librete.ch
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Kurze Vorstellung
|
|
||||||
Praxisbezug betonen
|
|
||||||
Fragen jederzeit willkommen
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# AMA (Ask my anything)
|
|
||||||
|
|
||||||
*Nur ein Vorschlag ...*
|
|
||||||
|
|
||||||
* Hast du alle Bände von AoT daheim?
|
|
||||||
* Hast du eine Studierenden-Kneipe mal geleitet?
|
|
||||||
* Hast du wirklich 17 Semester Philosophie ohne Abschluss studiert?
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Kurze Umfrage
|
|
||||||
|
|
||||||
**Bitte Hand heben:**
|
|
||||||
|
|
||||||
1) Wer hat schon mal ein Video komprimiert/konvertiert?
|
|
||||||
2) Wer kennte die 3-2-1 Regel?
|
|
||||||
3) Wer weiß, was der Unterschied zwischen JPEG und PNG ist?
|
|
||||||
4) Wer hat schon mal mit APIs gearbeitet?
|
|
||||||
5) Wer weiß, was UTF-8 bedeutet?
|
|
||||||
6) Wer hat schon mal mit einem CLI gearbeitet?
|
|
||||||
6) **Wer hat schon mal etwas mit HTML oder CSS gemacht?** (Hex-Farben wie `#FF0000`?)
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Niveau der Gruppe einschätzen
|
|
||||||
Keine falschen Antworten
|
|
||||||
Zeigt, wo wir starten
|
|
||||||
HTML/CSS-Frage: Viele kennen Hex-Codes aus Webdesign
|
|
||||||
API = Application Programming Interface
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Warum dieses Modul?
|
|
||||||
|
|
||||||
**Digitale Medien sind überall** – aber was steckt dahinter?
|
|
||||||
|
|
||||||
* Warum ist ein JPEG kleiner als ein PNG?
|
|
||||||
* Warum klingt MP3 anders als FLAC?
|
|
||||||
* Warum zeigt meine 1 TB Festplatte nur 931 GB?
|
|
||||||
* Warum ist USB-C so verwirrend?
|
|
||||||
* Wie funktioniert eigentlich Streaming?
|
|
||||||
* **→ Die Technik dahinter verstehen!**
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Praxisnahe Fragen aus dem Alltag
|
|
||||||
Nicht nur "was", sondern "warum"
|
|
||||||
Verständnis für technische Entscheidungen
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Das Ziel
|
|
||||||
|
|
||||||
**Technische Grundlagen verstehen**, um fundierte Entscheidungen treffen zu können.
|
|
||||||
|
|
||||||
Als Digital- und Medienwirtschaftler:innen werdet ihr täglich mit technischen Fragen konfrontiert:
|
|
||||||
* Welches Format für welchen Zweck?
|
|
||||||
* Welche Schnittstelle für welches Gerät?
|
|
||||||
* Wie funktioniert die Distribution digitaler Inhalte?
|
|
||||||
* **→ Mitreden können – nicht (zwingend) programmieren!**
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Nicht: Ihr sollt Programmierer werden
|
|
||||||
Sondern: Ihr sollt technische Entscheidungen verstehen
|
|
||||||
Praxisbezug: Medienproduktion, Marketing, Projektmanagement
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Was ihr lernt
|
|
||||||
|
|
||||||
**In dieser Veranstaltung erwerbt ihr folgende Kompetenzen:**
|
|
||||||
|
|
||||||
* Fundiertes Grundwissen über Daten und Informationen
|
|
||||||
* Dateiformate analysieren und verstehen
|
|
||||||
* Grundlagen von Kompression (Audio, Bild, Video)
|
|
||||||
* Speichermedien unterscheiden
|
|
||||||
* Programmier-Schnittstellen kennenlernen
|
|
||||||
* APIs und Distributionswege verstehen
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Fokus auf Verständnis, nicht auf Programmierung
|
|
||||||
Hands-On jede Woche: Selbst ausprobieren
|
|
||||||
Ziel: Einblick in die Denkweise von Software-Entwicklern
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Kursübersicht
|
|
||||||
|
|
||||||
**5 Termine:**
|
|
||||||
|
|
||||||
| # | Datum | Thema |
|
|
||||||
|---|-------|-------|
|
|
||||||
| 1 | 19.12.2025 | Bits, Bytes, Zeichenkodierung & Audio |
|
|
||||||
| 2 | 09.01.2026 | Bild- & Video-Kompression |
|
|
||||||
| 3 | 23.01.2026 | Speichermedien & Schnittstellen |
|
|
||||||
| 4 | 30.01.2026 | Distribution, APIs & Zukunft |
|
|
||||||
| 5 | TBA | Vertiefung & offene Fragen |
|
|
||||||
|
|
||||||
**Format:** Theorie + Hands-On (30-40 Min pro Termin)
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Nicht nur theoretische Inhalte
|
|
||||||
Praktische Übungen jede Woche
|
|
||||||
Medienwissenschaftler:innen, nicht Informatiker:innen
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Prüfungsleistung 18.02.
|
|
||||||
|
|
||||||
**Nach aktuellem Kenntnisstand:**
|
|
||||||
|
|
||||||
* 90 min (40% Grundlagen, 40% Dateiformate, 20% AV)
|
|
||||||
* Schriftliche Klausur
|
|
||||||
* Teils offene Fragen
|
|
||||||
* Vermutlich digital
|
|
||||||
* Kein Coding!
|
|
||||||
* **Prüfungsrelevant:** Alles in den Folien/im Skript
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Details können sich noch ändern
|
|
||||||
Keine Programmieraufgaben
|
|
||||||
Verständnisfragen, keine Auswendiglernerei
|
|
||||||
-->
|
|
||||||
|
|
||||||
@@ -1,937 +0,0 @@
|
|||||||
---
|
|
||||||
marp: true
|
|
||||||
theme: gaia
|
|
||||||
paginate: true
|
|
||||||
backgroundColor: #fff
|
|
||||||
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege"
|
|
||||||
footer: "Michael Czechowski – HdM Stuttgart – WS 2025/26"
|
|
||||||
title: Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
|
||||||
---
|
|
||||||
|
|
||||||
<style>
|
|
||||||
:root {
|
|
||||||
--color-foreground: #1a1a2e;
|
|
||||||
--color-highlight: #1e5f8a;
|
|
||||||
--color-dimmed: #4a4a6a;
|
|
||||||
}
|
|
||||||
section.invert {
|
|
||||||
--color-foreground: #fff;
|
|
||||||
}
|
|
||||||
section {
|
|
||||||
font-size: 1.7rem;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
color: #1e5f8a;
|
|
||||||
}
|
|
||||||
section.invert h1 {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
color: #1f2937;
|
|
||||||
}
|
|
||||||
pre {
|
|
||||||
background: #0f0f23;
|
|
||||||
color: #5fb3e4;
|
|
||||||
border-radius: 8px;
|
|
||||||
border-left: 3px solid #1e5f8a;
|
|
||||||
}
|
|
||||||
pre code {
|
|
||||||
background: transparent;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
code {
|
|
||||||
background: #1a1a2e;
|
|
||||||
color: #5fb3e4;
|
|
||||||
padding: 0.15em 0.4em;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: var(--color-highlight);
|
|
||||||
}
|
|
||||||
section.klausur {
|
|
||||||
background: #e3f2fd !important;
|
|
||||||
}
|
|
||||||
section.klausur footer {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!-- _class: invert -->
|
|
||||||
<!-- _header: '' -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
<!-- _backgroundColor: #000 -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
# Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
|
||||||
|
|
||||||
**223015b** · Modul "Technik 1" · 1. Semester
|
|
||||||
Digital- und Medienwirtschaft
|
|
||||||
Hochschule der Medien Stuttgart
|
|
||||||
|
|
||||||
**Wintersemester 2025/26**
|
|
||||||
|
|
||||||
[https://librete.ch/hdm/223015b/](https://librete.ch/hdm/223015b/)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _header: '' -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _class: lead -->
|
|
||||||
|
|
||||||
# Termin 2 – 09.01.2026
|
|
||||||
## Bild-, Audio- & Videoformate
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _header: '' -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<!--
|
|
||||||
Links: Hochauflösend
|
|
||||||
Rechts: Stark komprimiert (JPEG-Artefakte sichtbar)
|
|
||||||
Instagram-Effekt
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Was ist ein Bild?
|
|
||||||
|
|
||||||
**Digital = Pixelraster**
|
|
||||||
|
|
||||||
**Beispiel: 1920×1080 (Full HD)**
|
|
||||||
= 2.073.600 Pixel
|
|
||||||
|
|
||||||
**Jedes Pixel = 3 Bytes (RGB)**
|
|
||||||
2.073.600 × 3 = **6,2 MB**
|
|
||||||
|
|
||||||
**Für EIN Foto!**
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Zoom auf Pixel-Ebene zeigen
|
|
||||||
Jedes Pixel = RGB-Tripel (3 Bytes)
|
|
||||||
6 MB × 10.000 Fotos = 62 GB
|
|
||||||
Smartphone-Speicher wäre schnell voll ohne Kompression
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _class: klausur -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||
# Rastergrafiken (Bitmaps)
|
|
||||||
|
|
||||||
**Aufbau:** 2D-Array von Pixeln mit Farbwerten
|
|
||||||
|
|
||||||
**Speicherbedarf (unkomprimiert):**
|
|
||||||
Breite × Höhe × Farbtiefe (in Bytes)
|
|
||||||
→ 1920×1080 × 3 Byte (RGB) = **6,2 MB**
|
|
||||||
|
|
||||||
**Farbtiefe:**
|
|
||||||
- 1 Bit = 2 Farben (S/W)
|
|
||||||
- 8 Bit = 256 Farben (Graustufen/Palette)
|
|
||||||
- 24 Bit = 16,7 Mio. Farben (True Color)
|
|
||||||
- 32 Bit = True Color + Alpha (Transparenz)
|
|
||||||
|
|
||||||
**Skalierung:** Interpolation (Nearest Neighbor, Bilinear, Bicubic)
|
|
||||||
|
|
||||||
<!--
|
|
||||||
DEFINITION: Bitmap = Bit-mapped graphics, 2D-Matrix aus Pixeln
|
|
||||||
BERECHNUNG SPEICHERBEDARF: Breite × Höhe × (Farbtiefe / 8)
|
|
||||||
BEISPIEL: 1920×1080 × 24 Bit = 1920×1080×3 = 6.220.800 Bytes ≈ 6,2 MB
|
|
||||||
FARBTIEFE erklärt:
|
|
||||||
- 1 Bit: 2^1 = 2 Farben (Schwarz/Weiß, Fax)
|
|
||||||
- 8 Bit: 2^8 = 256 Farben (GIF, Graustufen)
|
|
||||||
- 24 Bit: 2^24 = 16.777.216 Farben (True Color, RGB je 8 Bit)
|
|
||||||
- 32 Bit: 24 Bit + 8 Bit Alpha-Kanal (Transparenz)
|
|
||||||
INTERPOLATION bei Skalierung:
|
|
||||||
- Nearest Neighbor: Schnell, pixelig (Pixel-Art)
|
|
||||||
- Bilinear: Mittelwert aus 4 Nachbarn (Standard)
|
|
||||||
- Bicubic: 16 Nachbarn, glatter (Photoshop-Standard)
|
|
||||||
- Lanczos: Beste Qualität, rechenintensiv
|
|
||||||
PRÜFUNGSRELEVANT: Speicherberechnung, Farbtiefe-Tabelle, warum Vergrößern problematisch
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _class: klausur -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||
# Vektorgrafiken
|
|
||||||
|
|
||||||
**Speicherung als geometrische Primitive:**
|
|
||||||
- Pfade (Bézierkurven mit Kontrollpunkten)
|
|
||||||
- Grundformen (Rechteck, Ellipse, Polygon)
|
|
||||||
- Text (Glyphen als Outlines)
|
|
||||||
|
|
||||||
**SVG-Beispiel:**
|
|
||||||
`<circle cx="50" cy="50" r="40" fill="#ff0000"/>`
|
|
||||||
→ 3 Parameter statt 5.027 Pixel (r=40)
|
|
||||||
|
|
||||||
**Rendering-Pipeline:**
|
|
||||||
Vektordaten → Rasterisierung → Framebuffer → Display
|
|
||||||
|
|
||||||
**Auflösungsunabhängig:** Gleiche Datei für Icon (32px) und Plakat (3m)
|
|
||||||
|
|
||||||
<!--
|
|
||||||
PRIMITIVE: Grundbausteine der Vektorgrafik
|
|
||||||
- Pfade: Sequenz von Punkten, verbunden durch Linien/Kurven
|
|
||||||
- Bézierkurven: Quadratisch (3 Kontrollpunkte), Kubisch (4 Kontrollpunkte)
|
|
||||||
- Formen: Rechteck, Ellipse, Polygon (intern als Pfade)
|
|
||||||
SVG-SYNTAX Beispiele:
|
|
||||||
- <rect x="0" y="0" width="100" height="50"/>
|
|
||||||
- <circle cx="50" cy="50" r="25"/>
|
|
||||||
- <path d="M 0 0 L 100 100"/> (MoveTo, LineTo)
|
|
||||||
BERECHNUNG: Kreis mit r=40 → Fläche = π×40² ≈ 5.027 Pixel vs. 3 Parameter
|
|
||||||
RENDERING-PIPELINE: Vector → Tessellation → Rasterization → Framebuffer
|
|
||||||
FORMATE:
|
|
||||||
- SVG: XML-basiert, Web-Standard, editierbar
|
|
||||||
- PDF: Seiten-Beschreibungssprache, Vektoren + Raster gemischt
|
|
||||||
- AI/EPS: Adobe-proprietär, Druckvorstufe
|
|
||||||
PRÜFUNGSRELEVANT: Warum Vektoren skalierbar, SVG-Grundsyntax, Rendering-Pipeline
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _class: klausur -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||
# Raster vs. Vektor: Entscheidungskriterien
|
|
||||||
|
|
||||||
| Kriterium | Raster | Vektor |
|
|
||||||
|---|---|---|
|
|
||||||
| **Speicherung** | Pixelmatrix | Geometrie + Attribute |
|
|
||||||
| **Skalierung** | Qualitätsverlust | Verlustfrei |
|
|
||||||
| **Komplexität** | O(Breite × Höhe) | O(Anzahl Objekte) |
|
|
||||||
| **Bearbeitung** | Pixelbasiert | Objektbasiert |
|
|
||||||
|
|
||||||
**Wann Raster?** Fotos, Texturen, komplexe Farbverläufe
|
|
||||||
**Wann Vektor?** Logos, Icons, Typografie, technische Zeichnungen
|
|
||||||
|
|
||||||
**Konvertierung:**
|
|
||||||
- Raster → Vektor: Tracing (verlustbehaftet, approximiert)
|
|
||||||
- Vektor → Raster: Rasterisierung (exakt, aber auflösungsgebunden)
|
|
||||||
|
|
||||||
<!--
|
|
||||||
KOMPLEXITÄT erklärt:
|
|
||||||
- Raster O(w×h): Speicher wächst mit Pixelanzahl
|
|
||||||
- Vektor O(n): Speicher wächst mit Objektanzahl
|
|
||||||
BEISPIEL: Foto einer Wiese
|
|
||||||
- Raster: 1920×1080 = 2 Mio. Pixel, komprimiert ~500 KB
|
|
||||||
- Vektor: Jeder Grashalm ein Pfad → Millionen Objekte, unkomprimierbar
|
|
||||||
KONVERTIERUNG:
|
|
||||||
- Raster→Vektor (Tracing): Kantenerkennung, verlustbehaftet
|
|
||||||
- Tools: Potrace (Open Source), Adobe Live Trace, Inkscape
|
|
||||||
- Funktioniert gut: Logos, Zeichnungen, Text
|
|
||||||
- Funktioniert schlecht: Fotos, Farbverläufe
|
|
||||||
- Vektor→Raster (Rasterisierung): Exakt, aber Auflösung fixiert
|
|
||||||
- Jeder Bildschirm macht das (GPU)
|
|
||||||
- Export: "Auflösung" wählen = Ziel-Pixelgröße
|
|
||||||
ENTSCHEIDUNGSBAUM:
|
|
||||||
- Foto/Screenshot? → Raster
|
|
||||||
- Logo/Icon/Diagramm? → Vektor
|
|
||||||
- Druckvorlage? → Vektor (Auflösungsunabhängig)
|
|
||||||
- Web-Animation? → SVG (Vektor) oder Video (Raster)
|
|
||||||
PRÜFUNGSRELEVANT: Wann welches Format, Konvertierungsrichtungen und deren Eigenschaften
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Lossless: PNG
|
|
||||||
|
|
||||||
**PNG = Portable Network Graphics (1996)**
|
|
||||||
|
|
||||||
**Funktionsweise:**
|
|
||||||
- Vorhersage (Pixel ähneln Nachbarn)
|
|
||||||
- Differenz-Encoding
|
|
||||||
- DEFLATE-Algorithmus (wie ZIP)
|
|
||||||
|
|
||||||
**Kompression:** 20-50% Ersparnis
|
|
||||||
|
|
||||||
**Gut für:** Screenshots, Logos, Text
|
|
||||||
**Schlecht für:** Fotos
|
|
||||||
|
|
||||||
<!--
|
|
||||||
PNG wurde entwickelt als GIF-Alternative (Patent-Probleme)
|
|
||||||
Lossless: Originaldaten bleiben erhalten
|
|
||||||
Transparenz: Alpha-Kanal (sanfte Übergänge)
|
|
||||||
DEFLATE: Gleicher Algorithmus wie ZIP
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Lossy: JPEG
|
|
||||||
|
|
||||||
**JPEG = Joint Photographic Experts Group (1992)**
|
|
||||||
|
|
||||||
**Eigenschaften:**
|
|
||||||
- Lossy Kompression
|
|
||||||
- 90%+ Platzersparnis möglich
|
|
||||||
- Artefakte bei hoher Kompression
|
|
||||||
|
|
||||||
**6 MB → 500 KB** (typisch)
|
|
||||||
|
|
||||||
<!--
|
|
||||||
JPEG-Norm beschreibt nur Kompression, nicht Speicherformat
|
|
||||||
JFIF = JPEG File Interchange Format (das eigentliche Dateiformat)
|
|
||||||
Dateierweiterungen: .jpg, .jpeg, .jfif (alle gleich)
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _header: '' -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<!--
|
|
||||||
Beispiel: Stark komprimiertes JPEG
|
|
||||||
Blocking (8×8-Blöcke sichtbar)
|
|
||||||
Ringing (Geister um Kanten)
|
|
||||||
Color Banding (Verläufe "treppig")
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Wie funktioniert JPEG? (1/2)
|
|
||||||
|
|
||||||
**Schritt 1: RGB → YCbCr**
|
|
||||||
- Y = Helligkeit (Luminanz)
|
|
||||||
- Cb/Cr = Farbe (Chrominanz)
|
|
||||||
|
|
||||||
**Warum?** Menschen sehen Helligkeit besser als Farbe
|
|
||||||
|
|
||||||
**Schritt 2: Chroma Subsampling**
|
|
||||||
Farbauflösung reduzieren (4:2:0)
|
|
||||||
→ 50% Datenmenge weg, kaum sichtbar
|
|
||||||
|
|
||||||
<!--
|
|
||||||
YCbCr = Farbraum-Konversion
|
|
||||||
Y = Brightness, Cb = Blue-Yellow, Cr = Red-Green
|
|
||||||
4:2:0 Subsampling: Farbe nur jedes 2. Pixel horizontal & vertikal
|
|
||||||
Auge merkt's kaum, weil Helligkeitssehen dominiert
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Wie funktioniert JPEG? (2/2)
|
|
||||||
|
|
||||||
**Schritt 3: DCT (Discrete Cosine Transform)**
|
|
||||||
Bild in 8×8-Blöcke → Frequenzspektrum
|
|
||||||
|
|
||||||
**Schritt 4: Quantisierung**
|
|
||||||
Hohe Frequenzen (Details) stark reduzieren
|
|
||||||
→ **Hier passiert Datenverlust!**
|
|
||||||
|
|
||||||
**Schritt 5: Huffman-Coding**
|
|
||||||
Lossless-Kompression der Restdaten
|
|
||||||
|
|
||||||
<!--
|
|
||||||
DCT: Ähnlich wie FFT bei Audio
|
|
||||||
8×8 Blöcke: Warum JPEG "blocky" wird bei hoher Kompression
|
|
||||||
Quantisierung: Quality-Schieberegler steuert genau das
|
|
||||||
Huffman: Finale Effizienz (wie bei MP3)
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# JPEG Quality
|
|
||||||
|
|
||||||
| Quality | Dateigröße | Artefakte |
|
|
||||||
|---------|------------|-----------|
|
|
||||||
| **100** | ≈2-3 MB | Kaum |
|
|
||||||
| **85-90** | ≈200-400 KB | Minimal |
|
|
||||||
| **50** | ≈100 KB | Sichtbar |
|
|
||||||
|
|
||||||
**Sweet Spot: 85-90**
|
|
||||||
10x Kompression, für Menschen kaum unterscheidbar
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Quality 100 = Minimum Compression (nicht lossless!)
|
|
||||||
Quality 85-90 = Standard für Web
|
|
||||||
Quality 50 = Sichtbare Artefakte (Blocking, Ringing)
|
|
||||||
Photoshop "Save for Web": Standard ist 60
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _header: '' -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<!--
|
|
||||||
GIF-Animation (z.B. Meme)
|
|
||||||
256 Farben, aber Animationen möglich
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Die GIF-Geschichte
|
|
||||||
|
|
||||||
**GIF = Graphics Interchange Format (1987)**
|
|
||||||
CompuServe (US-Online-Dienst)
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- 256 Farben max (8-bit Palette)
|
|
||||||
- Lossless (für Palette)
|
|
||||||
- Animationen!
|
|
||||||
|
|
||||||
**1994 Twist:** Unisys hält Patent auf LZW-Kompression
|
|
||||||
→ Fordert Lizenzgebühren
|
|
||||||
|
|
||||||
→ **"Burn All GIFs!" Kampagne**
|
|
||||||
|
|
||||||
<!--
|
|
||||||
CompuServe: Früher Online-Dienst (1969-2009)
|
|
||||||
LZW = Lempel-Ziv-Welch Compression
|
|
||||||
Unisys Patent-Trolling: Erst Jahre nach GIF-Einführung
|
|
||||||
Community-Reaktion: Boykott, Suche nach Alternative
|
|
||||||
Ergebnis: PNG wurde entwickelt (1996)
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# PNG vs. GIF
|
|
||||||
|
|
||||||
**GIF:**
|
|
||||||
✓ Animationen
|
|
||||||
✓ Breite Unterstützung
|
|
||||||
❌ Nur 256 Farben
|
|
||||||
❌ Patent-Probleme (bis 2003)
|
|
||||||
|
|
||||||
**PNG:**
|
|
||||||
✓ Millionen Farben
|
|
||||||
✓ Alpha-Transparenz
|
|
||||||
✓ Patent-frei
|
|
||||||
❌ Keine Animationen (bis APNG, 2004)
|
|
||||||
|
|
||||||
**Ergebnis:** PNG für Grafiken, GIF für Memes!
|
|
||||||
|
|
||||||
<!--
|
|
||||||
APNG = Animated PNG (Firefox, Safari support)
|
|
||||||
WebP (Google, 2010): Animationen + bessere Kompression
|
|
||||||
GIF überlebte kulturell (Meme-Format)
|
|
||||||
"GIF" Aussprache: "Jif" vs. "Gif" – ewiger Streit
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# WebP & AVIF
|
|
||||||
|
|
||||||
**WebP (Google, 2010):**
|
|
||||||
- Lossy UND Lossless
|
|
||||||
- Animationen
|
|
||||||
- 25-35% kleiner als JPEG
|
|
||||||
|
|
||||||
**AVIF (2019):**
|
|
||||||
- Basiert auf AV1-Video-Codec
|
|
||||||
- 50% kleiner als JPEG
|
|
||||||
- HDR-Unterstützung
|
|
||||||
- Patent-frei
|
|
||||||
|
|
||||||
<!--
|
|
||||||
WebP: Von Google entwickelt, deshalb Skepsis
|
|
||||||
AVIF: Alliance for Open Media (Google, Netflix, Amazon, Mozilla...)
|
|
||||||
Browser-Support 2024: WebP fast überall, AVIF wachsend
|
|
||||||
JPEG bleibt dominant (Kompatibilität!)
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _header: '' -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<!--
|
|
||||||
Vorher/Nachher: Hochauflösend vs. Instagram-Upload
|
|
||||||
Sichtbare Qualitätsverluste
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Warum Instagram eure Fotos "ruiniert"
|
|
||||||
|
|
||||||
**Upload-Pipeline:**
|
|
||||||
1. Dein Foto: 12 MP, 8 MB
|
|
||||||
2. Instagram skaliert: max. 1080px
|
|
||||||
3. Re-Kompression: JPEG Quality ~75
|
|
||||||
4. Endgröße: 200-400 KB
|
|
||||||
|
|
||||||
**Warum?**
|
|
||||||
- Speicherkosten (Milliarden Fotos!)
|
|
||||||
- Ladezeiten (Mobile)
|
|
||||||
- Bandbreite (günstiger)
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Instagram ist keine Kunstgalerie
|
|
||||||
Optimiert für Geschwindigkeit, nicht Qualität
|
|
||||||
Facebook macht dasselbe
|
|
||||||
Lösung: Portfolio-Websites (eigene Kontrolle)
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
# Hands-On: Kompression vergleichen
|
|
||||||
|
|
||||||
**Aufgabe (40 Min):**
|
|
||||||
|
|
||||||
1. Hochauflösendes Foto (eigenes oder CC)
|
|
||||||
2. Exportiere:
|
|
||||||
- PNG
|
|
||||||
- JPEG Q100, Q85, Q50
|
|
||||||
- WebP (optional)
|
|
||||||
3. Tool: **[Squoosh.app](https://squoosh.app)** (Google-Tool)
|
|
||||||
4. Vergleiche: Dateigrößen, sichtbare Unterschiede
|
|
||||||
5. Wo werden Artefakte sichtbar?
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Squoosh.app: Browser-basiert, keine Installation
|
|
||||||
Side-by-Side-Vergleich mit Zoom
|
|
||||||
Verschiedene Codecs testen
|
|
||||||
Studis sollen selbst "Sweet Spot" finden
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _class: lead -->
|
|
||||||
|
|
||||||
# Teil 2: Video
|
|
||||||
## Kompression & Codecs
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _header: '' -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<!--
|
|
||||||
Netflix 4K-Streaming
|
|
||||||
Unmöglich ohne moderne Codecs
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Das Problem: Videos sind RIIIIIIIESIG
|
|
||||||
|
|
||||||
**1 Minute 4K-Video (3840×2160):**
|
|
||||||
|
|
||||||
- 30 fps (Bilder/Sekunde)
|
|
||||||
- Jedes Bild: 24,8 MB (unkomprimiert)
|
|
||||||
|
|
||||||
**Rechnung:**
|
|
||||||
30 × 24,8 MB = **744 MB/Sekunde**
|
|
||||||
× 60 Sekunden = **44,6 GB/Minute**
|
|
||||||
|
|
||||||
**2-Stunden-Film: 5,3 TB!**
|
|
||||||
|
|
||||||
<!--
|
|
||||||
4K = 3840×2160 Pixel = 8,3 Megapixel pro Frame
|
|
||||||
30 fps = Standard, Kino = 24 fps, Gaming = 60+ fps
|
|
||||||
Ohne Kompression: Unmöglich zu streamen oder speichern
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Container: Das Dateiformat
|
|
||||||
|
|
||||||
**Was ist ein Container?**
|
|
||||||
Das Dateiformat – eine "Box", die verschiedene Streams zusammenpackt:
|
|
||||||
- Video-Stream, Audio-Stream(s), Untertitel, Metadaten
|
|
||||||
|
|
||||||
**Gängige Container:**
|
|
||||||
- **MP4** (.mp4) – Web, Streaming
|
|
||||||
- **MKV** (.mkv) – Archiv, viele Streams
|
|
||||||
- **AVI** (.avi) – Legacy (veraltet)
|
|
||||||
- **MOV** (.mov) – Apple-Ökosystem
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Container = Verpackung, nicht der Inhalt
|
|
||||||
Ein MP4 sagt nichts über die Qualität aus
|
|
||||||
MKV kann beliebig viele Audio/Untertitel-Spuren haben
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Codec: Der Kompressionsalgorithmus
|
|
||||||
|
|
||||||
**Was ist ein Codec?** (Coder/Decoder)
|
|
||||||
Entscheidet, WIE Video/Audio komprimiert wird
|
|
||||||
|
|
||||||
**Video-Codecs:**
|
|
||||||
|
|
||||||
| Codec | Jahr | Verbreitung |
|
|
||||||
|-------|------|-------------|
|
|
||||||
| H.264/AVC | 2003 | Universell, überall |
|
|
||||||
| H.265/HEVC | 2013 | 4K, effizient, Lizenzen |
|
|
||||||
| VP9 | 2013 | YouTube, Google |
|
|
||||||
| AV1 | 2018 | Zukunft, lizenzfrei |
|
|
||||||
|
|
||||||
**Audio-Codecs:** AAC, MP3, Opus, FLAC
|
|
||||||
|
|
||||||
<!--
|
|
||||||
H.264 = De-facto-Standard seit 20 Jahren
|
|
||||||
H.265 = 50% kleinere Dateien, aber teure Lizenzen
|
|
||||||
AV1 = Open Source, Netflix/YouTube pushen es
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Container + Codec = Video
|
|
||||||
|
|
||||||
**Das Zusammenspiel:**
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────┐
|
|
||||||
│ Container (z.B. MP4) │
|
|
||||||
│ ┌────────────────────────┐ │
|
|
||||||
│ │ Video-Stream (H.264) │ │
|
|
||||||
│ ├────────────────────────┤ │
|
|
||||||
│ │ Audio-Stream (AAC) │ │
|
|
||||||
│ ├────────────────────────┤ │
|
|
||||||
│ │ Untertitel (SRT) │ │
|
|
||||||
│ └────────────────────────┘ │
|
|
||||||
└─────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
**Häufiger Irrtum:** "Das ist eine MP4-Datei"
|
|
||||||
→ Sagt nichts über den Codec aus!
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Container ≠ Codec (häufiges Missverständnis!)
|
|
||||||
MP4 ist KEIN Codec, sondern Container
|
|
||||||
Ein MP4 kann H.264, H.265 oder AV1 enthalten
|
|
||||||
Prüfen mit: MediaInfo, ffprobe
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _header: '' -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<!--
|
|
||||||
Diagramm: Container mit verschiedenen Streams
|
|
||||||
Video-Track (H.264)
|
|
||||||
Audio-Track (AAC)
|
|
||||||
Untertitel-Track (SRT)
|
|
||||||
Metadaten (Titel, Künstler, etc.)
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Video-Kompression: Drei Prinzipien
|
|
||||||
|
|
||||||
**1. Spatial Compression (Intra-Frame)**
|
|
||||||
Jedes Bild einzeln (wie JPEG)
|
|
||||||
→ I-Frames
|
|
||||||
|
|
||||||
**2. Temporal Compression (Inter-Frame)**
|
|
||||||
Nur Änderungen zwischen Bildern
|
|
||||||
→ P-Frames, B-Frames
|
|
||||||
|
|
||||||
**3. Motion Compensation**
|
|
||||||
"Ball bewegt sich von A nach B"
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Spatial: Innerhalb eines Bildes (JPEG-ähnlich)
|
|
||||||
Temporal: Zwischen Bildern (zeitliche Redundanz)
|
|
||||||
Motion Compensation: Intelligente Vorhersage
|
|
||||||
→ 90%+ Effizienz durch temporale Kompression
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# I-Frames, P-Frames, B-Frames
|
|
||||||
|
|
||||||
**I-Frame (Intra):**
|
|
||||||
Vollständiges Bild (wie JPEG)
|
|
||||||
Groß, aber unabhängig
|
|
||||||
|
|
||||||
**P-Frame (Predicted):**
|
|
||||||
Referenziert vorherige Frames
|
|
||||||
Viel kleiner
|
|
||||||
|
|
||||||
**B-Frame (Bi-directional):**
|
|
||||||
Referenziert vorherige UND zukünftige Frames
|
|
||||||
Am effizientesten
|
|
||||||
|
|
||||||
**GOP:** I - B - B - P - B - B - P - B - B - I
|
|
||||||
|
|
||||||
<!--
|
|
||||||
GOP = Group of Pictures (typisch 12-15 Frames)
|
|
||||||
I-Frame: Alle 1-2 Sekunden nötig (für Seeking)
|
|
||||||
P-Frame: "Pixel X bewegt sich 5px rechts"
|
|
||||||
B-Frame: Komplex, aber beste Kompression
|
|
||||||
Wenn du vorspulst: Sucht nach nächstem I-Frame
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _header: '' -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<!--
|
|
||||||
Visualisierung: I/P/B-Frame-Abhängigkeiten
|
|
||||||
I-Frame = Vollbild (Keyframe), P/B-Frames speichern nur Unterschiede
|
|
||||||
Quelle: https://www.canon.com.hk/cpx/en/technical/va_EOS_Movie_Compression_Options_All_I_and_IPB.html
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# H.264: Der König
|
|
||||||
|
|
||||||
**H.264 / AVC (2003)**
|
|
||||||
|
|
||||||
**Warum dominant?**
|
|
||||||
✓ Exzellente Kompression (100:1 möglich)
|
|
||||||
✓ Hardware-Support (jedes Gerät seit ~2010)
|
|
||||||
✓ YouTube, Netflix, Blu-ray – alles H.264
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- Variable Block-Größen (16×16 bis 4×4)
|
|
||||||
- Deblocking-Filter
|
|
||||||
- CABAC-Coding
|
|
||||||
|
|
||||||
<!--
|
|
||||||
AVC = Advanced Video Coding
|
|
||||||
MPEG-4 Part 10 = H.264 (gleicher Standard)
|
|
||||||
Revolutionierte Video-Streaming
|
|
||||||
Hardware-Decoder in CPUs/GPUs → Batterie-schonend
|
|
||||||
CABAC = Context-Adaptive Binary Arithmetic Coding
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Das Patent-Problem
|
|
||||||
|
|
||||||
**H.264 ist NICHT frei!**
|
|
||||||
|
|
||||||
**MPEG-LA (Patent Pool):**
|
|
||||||
- 2.000+ Patente von ~30 Unternehmen
|
|
||||||
- Apple, Microsoft, Sony, Panasonic...
|
|
||||||
|
|
||||||
**Lizenzgebühren:**
|
|
||||||
- Hardware-Decoder: $0,20/Einheit
|
|
||||||
- Content-Distribution: Kostenlos für "Internet Broadcast"
|
|
||||||
|
|
||||||
**Problem:** Open-Source-Projekte in Grauzone
|
|
||||||
|
|
||||||
<!--
|
|
||||||
MPEG-LA = Licensing Authority
|
|
||||||
Firefox weigerte sich lange, H.264 zu supporten (Patent-Gründe)
|
|
||||||
Chromium musste extern linken
|
|
||||||
Patent-Pool: Firmen teilen Patente, gemeinsame Lizenzierung
|
|
||||||
"Free to View" Klausel: YouTube etc. kostenlos
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# H.265 / HEVC
|
|
||||||
|
|
||||||
**H.265 (2013):**
|
|
||||||
50% bessere Kompression als H.264
|
|
||||||
|
|
||||||
**ABER:** Patent-Desaster
|
|
||||||
|
|
||||||
**Drei (!) konkurrierende Patent-Pools:**
|
|
||||||
- MPEG-LA
|
|
||||||
- HEVC Advance
|
|
||||||
- Velos Media
|
|
||||||
|
|
||||||
→ Viele bleiben bei H.264 oder suchen Alternativen
|
|
||||||
|
|
||||||
<!--
|
|
||||||
HEVC = High Efficiency Video Coding
|
|
||||||
Technisch überlegen, aber juristisch Albtraum
|
|
||||||
Apple nutzt HEVC (iPhone-Videos)
|
|
||||||
Netflix zögert wegen Lizenzkosten
|
|
||||||
Fragmentierung verzögert Adoption
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _header: '' -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<!--
|
|
||||||
YouTube VP9-Logo
|
|
||||||
Google's Patent-freie Alternative
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# VP9: Googles Antwort
|
|
||||||
|
|
||||||
**VP9 (2013):**
|
|
||||||
Entwickelt von Google (On2-Akquisition)
|
|
||||||
|
|
||||||
**Eigenschaften:**
|
|
||||||
✓ Ähnlich H.265-Kompression
|
|
||||||
✓ KOSTENLOS, patent-frei (laut Google)
|
|
||||||
✓ YouTube nutzt VP9 für 4K
|
|
||||||
|
|
||||||
**Nachteile:**
|
|
||||||
❌ Hardware-Support langsam
|
|
||||||
❌ Höherer CPU-Aufwand
|
|
||||||
❌ Nicht universell wie H.264
|
|
||||||
|
|
||||||
<!--
|
|
||||||
On2 Technologies: Gekauft 2010 für $133M
|
|
||||||
VP8 → VP9 → AV1 (Evolution)
|
|
||||||
YouTube forciert VP9: 4K-Videos nur VP9/AV1
|
|
||||||
Hardware-Decoder erst ab ~2016 (langsame Adoption)
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _header: '' -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<!--
|
|
||||||
AV1-Logo
|
|
||||||
Alliance for Open Media
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# AV1: Die Open-Source-Revolution
|
|
||||||
|
|
||||||
**AV1 (2018):**
|
|
||||||
Alliance for Open Media: Google, Netflix, Amazon, Microsoft, Apple, Mozilla...
|
|
||||||
|
|
||||||
**Ziel:** Patent-freier, moderner Codec
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
✓ 30% besser als H.265
|
|
||||||
✓ Royalty-free, Open Source
|
|
||||||
✓ 8K, HDR, hohe Frame-Rates
|
|
||||||
|
|
||||||
**Stand 2025:**
|
|
||||||
YouTube, Netflix nutzen AV1 für 4K/8K
|
|
||||||
|
|
||||||
<!--
|
|
||||||
AOM = Alliance for Open Media (2015 gegründet)
|
|
||||||
Alle Big-Tech-Player vereint (historisch!)
|
|
||||||
"Fuck you" an Patent-Mafia
|
|
||||||
Problem: Encoding SEHR langsam (10-100x vs. H.264)
|
|
||||||
Hardware-Encoder kommen (ab 2020er-GPUs)
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Adaptive Bitrate Streaming
|
|
||||||
|
|
||||||
**Problem:** Internet-Geschwindigkeit variiert
|
|
||||||
|
|
||||||
**Lösung:** Mehrere Qualitäten parallel
|
|
||||||
|
|
||||||
**MPEG-DASH / HLS:**
|
|
||||||
- 4K (20 Mbps)
|
|
||||||
- 1080p (5 Mbps)
|
|
||||||
- 720p (2,5 Mbps)
|
|
||||||
- 480p (1 Mbps)
|
|
||||||
- 240p (0,5 Mbps)
|
|
||||||
|
|
||||||
Segmente: 2-10 Sekunden (Player wählt dynamisch)
|
|
||||||
|
|
||||||
<!--
|
|
||||||
DASH = Dynamic Adaptive Streaming over HTTP
|
|
||||||
HLS = HTTP Live Streaming (Apple)
|
|
||||||
Beide ähnlich, aber inkompatibel
|
|
||||||
Manifest-Datei: Liste aller Qualitäten
|
|
||||||
Player misst Bandbreite, wechselt live
|
|
||||||
→ Warum Netflix plötzlich pixelig wird
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _header: '' -->
|
|
||||||
<!-- _footer: '' -->
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<!--
|
|
||||||
Visualisierung: Qualitätswechsel während Playback
|
|
||||||
Bandbreite schwankt → Player reagiert
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Container im Detail
|
|
||||||
|
|
||||||
**MP4:** Standard für Web/Mobile, DRM-fähig (H.264, H.265, AV1)
|
|
||||||
|
|
||||||
**MKV:** Open Source, beliebig viele Spuren (fast jeder Codec)
|
|
||||||
|
|
||||||
**WebM:** Google/Web-optimiert (nur VP9/AV1 + Opus/Vorbis)
|
|
||||||
|
|
||||||
<!--
|
|
||||||
MP4 = MPEG-4 Part 14 (ISO-Standard)
|
|
||||||
Matroska = Russisch: Matrjoschka (Puppen ineinander)
|
|
||||||
WebM = Subset von Matroska (HTML5-Video)
|
|
||||||
MKV vs. MP4: Offenheit vs. Kompatibilität
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Hands-On: Video analysieren
|
|
||||||
|
|
||||||
**Aufgabe (40 Min):**
|
|
||||||
|
|
||||||
**Tools:**
|
|
||||||
- Desktop: FFmpeg, HandBrake, [MediaInfo](https://mediaarea.net/MediaInfoOnline)
|
|
||||||
- Browser: [Squoosh.app](https://squoosh.app) (Bilder), [MediaInfo Online](https://mediaarea.net/MediaInfoOnline)
|
|
||||||
- iOS/Android: MediaInfo App, VLC
|
|
||||||
|
|
||||||
1. Download: CC-Video (Big Buck Bunny, ~1 Min)
|
|
||||||
2. Analysiere: Container, Codec, Bitrate, Auflösung
|
|
||||||
3. Konvertiere: H.264 vs. H.265 (gleiche Qualität)
|
|
||||||
4. Vergleiche: Größen, Encoding-Zeit
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Big Buck Bunny: Open-Source-Film (Blender Foundation)
|
|
||||||
FFmpeg: Swiss Army Knife für Video
|
|
||||||
HandBrake: GUI für FFmpeg (einfacher)
|
|
||||||
MediaInfo: Detaillierte Datei-Analyse
|
|
||||||
Encoding-Zeit: H.265 deutlich langsamer als H.264
|
|
||||||
-->
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- _class: lead -->
|
|
||||||
|
|
||||||
# Fragen & Diskussion
|
|
||||||
|
|
||||||
**Kontakt:** mail@librete.ch
|
|
||||||
**Folien:** Online verfügbar unter https://librete.ch/hdm/223015b
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Lizenz & Attribution
|
|
||||||
|
|
||||||
Diese Präsentation ist lizenziert unter **Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)**
|
|
||||||
|
|
||||||
- Erlaubt Teilen & Anpassen mit Namensnennung
|
|
||||||
- Adaptionen müssen unter gleicher Lizenz geteilt werden
|
|
||||||
|
|
||||||
Vollständige Lizenz: https://creativecommons.org/licenses/by-sa/4.0/
|
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 2.0 MiB |
|
Before Width: | Height: | Size: 2.0 MiB |
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
description = "HdM Slides - Marp presentation builder with tools";
|
description = "HdM Slides - Marp presentation builder";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
@@ -9,114 +9,19 @@
|
|||||||
outputs = { self, nixpkgs, flake-utils }:
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
flake-utils.lib.eachDefaultSystem (system:
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
let
|
let
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = import nixpkgs { inherit system; };
|
||||||
|
|
||||||
# QR code generator script
|
|
||||||
qr-gen = pkgs.writeShellScriptBin "qr" ''
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
echo "Usage: qr <url> [output.png]"
|
|
||||||
echo ""
|
|
||||||
echo "Examples:"
|
|
||||||
echo " qr https://example.com"
|
|
||||||
echo " qr https://example.com my-qr.png"
|
|
||||||
echo " qr 'https://librete.ch/hdm/223015b/' slides-qr.png"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
URL="$1"
|
|
||||||
OUTPUT="''${2:-qr-code.png}"
|
|
||||||
|
|
||||||
${pkgs.qrencode}/bin/qrencode -o "$OUTPUT" -s 10 -m 2 "$URL"
|
|
||||||
echo "Generated: $OUTPUT"
|
|
||||||
'';
|
|
||||||
|
|
||||||
# QR code for course slides
|
|
||||||
qr-slides = pkgs.writeShellScriptBin "qr-slides" ''
|
|
||||||
COURSE="''${1:-223015b}"
|
|
||||||
OUTPUT="''${2:-build/$COURSE/qr-$COURSE.png}"
|
|
||||||
|
|
||||||
mkdir -p "$(dirname "$OUTPUT")"
|
|
||||||
${pkgs.qrencode}/bin/qrencode -o "$OUTPUT" -s 10 -m 2 "https://librete.ch/hdm/$COURSE/"
|
|
||||||
echo "Generated QR for $COURSE: $OUTPUT"
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Image optimizer script
|
|
||||||
optimize-img = pkgs.writeShellScriptBin "optimize-img" ''
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
echo "Usage: optimize-img <image-or-directory> [max-width]"
|
|
||||||
echo ""
|
|
||||||
echo "Resizes images to max width (default: 1920px)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
TARGET="$1"
|
|
||||||
MAX_WIDTH="''${2:-1920}"
|
|
||||||
|
|
||||||
if [ -d "$TARGET" ]; then
|
|
||||||
for img in "$TARGET"/*.{png,jpg,jpeg,webp} 2>/dev/null; do
|
|
||||||
[ -f "$img" ] || continue
|
|
||||||
echo "Optimizing: $(basename "$img")"
|
|
||||||
${pkgs.imagemagick}/bin/magick "$img" -resize "''${MAX_WIDTH}x>" -quality 85 "$img"
|
|
||||||
done
|
|
||||||
elif [ -f "$TARGET" ]; then
|
|
||||||
echo "Optimizing: $TARGET"
|
|
||||||
${pkgs.imagemagick}/bin/magick "$TARGET" -resize "''${MAX_WIDTH}x>" -quality 85 "$TARGET"
|
|
||||||
else
|
|
||||||
echo "Error: $TARGET not found"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Done!"
|
|
||||||
'';
|
|
||||||
|
|
||||||
in {
|
in {
|
||||||
# Development shell with all tools
|
|
||||||
devShells.default = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
nodejs_20
|
nodejs_22
|
||||||
nodePackages.npm
|
nodePackages.npm
|
||||||
qrencode
|
|
||||||
imagemagick
|
|
||||||
gnumake
|
gnumake
|
||||||
];
|
];
|
||||||
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
echo "HdM Slides Development Environment"
|
echo "HdM Slides - run 'make' for available commands"
|
||||||
echo ""
|
|
||||||
echo "Available commands:"
|
|
||||||
echo " make dev-b - Start 223015b dev server (port 1312)"
|
|
||||||
echo " make dev-c - Start 223015c dev server (port 1313)"
|
|
||||||
echo " make build - Build all courses"
|
|
||||||
echo " qr <url> - Generate QR code"
|
|
||||||
echo " qr-slides 223015b - Generate QR for course"
|
|
||||||
echo " optimize-img <dir> - Optimize images"
|
|
||||||
echo ""
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Standalone apps
|
|
||||||
packages = {
|
|
||||||
qr = qr-gen;
|
|
||||||
qr-slides = qr-slides;
|
|
||||||
optimize-img = optimize-img;
|
|
||||||
default = qr-gen;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Direct runnable apps
|
|
||||||
apps = {
|
|
||||||
qr = {
|
|
||||||
type = "app";
|
|
||||||
program = "${qr-gen}/bin/qr";
|
|
||||||
};
|
|
||||||
qr-slides = {
|
|
||||||
type = "app";
|
|
||||||
program = "${qr-slides}/bin/qr-slides";
|
|
||||||
};
|
|
||||||
optimize-img = {
|
|
||||||
type = "app";
|
|
||||||
program = "${optimize-img}/bin/optimize-img";
|
|
||||||
};
|
|
||||||
default = self.apps.${system}.qr;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
const { Marp } = require('@marp-team/marp-core');
|
||||||
|
const hljs = require('highlight.js');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
engine: (opts) => {
|
||||||
|
const marp = new Marp(opts);
|
||||||
|
const md = marp.markdown;
|
||||||
|
const defaultInline = md.renderer.rules.code_inline
|
||||||
|
|| ((tokens, idx, options, env, self) => `<code>${md.utils.escapeHtml(tokens[idx].content)}</code>`);
|
||||||
|
md.renderer.rules.code_inline = (tokens, idx, options, env, self) => {
|
||||||
|
const content = tokens[idx].content;
|
||||||
|
try {
|
||||||
|
const highlighted = hljs.highlight(content, { language: 'html', ignoreIllegals: true }).value;
|
||||||
|
return `<code class="hljs language-html">${highlighted}</code>`;
|
||||||
|
} catch (e) {
|
||||||
|
return defaultInline(tokens, idx, options, env, self);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return marp;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -3,20 +3,28 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "HdM Stuttgart - Lecture Slides (Marp)",
|
"description": "HdM Stuttgart - Lecture Slides (Marp)",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:b": "PORT=1312 marp --server --allow-local-files courses/223015b/slides/",
|
"dev": "PORT=3000 marp --server --allow-local-files slides/",
|
||||||
"dev:c": "PORT=1313 marp --server --allow-local-files courses/223015c/slides/",
|
|
||||||
"build": "make build",
|
"build": "make build",
|
||||||
"build:b": "make build-b",
|
"build:b": "make build-b",
|
||||||
"build:c": "make build-c",
|
"build:c": "make build-c",
|
||||||
"pdf": "make pdf",
|
"pdf": "make pdf",
|
||||||
"html": "make html",
|
"html": "make html",
|
||||||
|
"klausur": "make klausur",
|
||||||
|
"deploy": "make deploy",
|
||||||
"test": "echo \"No tests specified\" && exit 0"
|
"test": "echo \"No tests specified\" && exit 0"
|
||||||
},
|
},
|
||||||
"keywords": ["marp", "slides", "hdm", "lectures"],
|
"keywords": [
|
||||||
|
"marp",
|
||||||
|
"slides",
|
||||||
|
"hdm",
|
||||||
|
"lectures"
|
||||||
|
],
|
||||||
"author": "Michael Czechowski <mail@librete.ch>",
|
"author": "Michael Czechowski <mail@librete.ch>",
|
||||||
"license": "CC-BY-SA-4.0",
|
"license": "CC-BY-SA-4.0",
|
||||||
"type": "commonjs",
|
"type": "commonjs",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@marp-team/marp-cli": "^4.2.3"
|
"@marp-team/marp-cli": "^4.2.3",
|
||||||
|
"@marp-team/marp-core": "^4.3.0",
|
||||||
|
"highlight.js": "^11.11.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,106 +1,44 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Development server script for HdM slides
|
# Development server for HdM slides
|
||||||
# Starts index server + marp servers for each course
|
# Usage:
|
||||||
|
# ./dev-server.sh - Marp live server for all courses (port 1312)
|
||||||
|
# ./dev-server.sh 223015b 1313 - Marp live server for single course
|
||||||
|
# ./dev-server.sh 223015c 1314 - Marp live server for single course
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
INDEX_PORT=1310
|
SLIDES_DIR="slides"
|
||||||
COURSE_B_PORT=1311
|
COURSE="${1:-}"
|
||||||
COURSE_C_PORT=1312
|
DEV_PORT="${2:-1312}"
|
||||||
COURSE_DIR="courses"
|
|
||||||
DEV_INDEX_DIR=".dev-index"
|
|
||||||
|
|
||||||
# Colors
|
# Colors
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
BLUE='\033[0;34m'
|
BLUE='\033[0;34m'
|
||||||
|
RED='\033[0;31m'
|
||||||
NC='\033[0m' # No Color
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
# Cleanup function
|
# Kill existing process on our port only
|
||||||
cleanup() {
|
kill_port() {
|
||||||
echo -e "\n${RED}Shutting down servers...${NC}"
|
fuser -k "$DEV_PORT/tcp" 2>/dev/null || true
|
||||||
kill $PID_INDEX $PID_B $PID_C 2>/dev/null || true
|
sleep 0.5
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Kill existing processes on our ports
|
|
||||||
kill_existing() {
|
|
||||||
echo -e "${BLUE}Cleaning up existing processes...${NC}"
|
|
||||||
# Kill marp processes first
|
|
||||||
pkill -9 -f "marp-cli" 2>/dev/null || true
|
|
||||||
pkill -f "python3 -m http.server" 2>/dev/null || true
|
|
||||||
# Kill ports including marp's WebSocket ports (37717-37720 range)
|
|
||||||
fuser -k $INDEX_PORT/tcp $COURSE_B_PORT/tcp $COURSE_C_PORT/tcp 2>/dev/null || true
|
|
||||||
fuser -k 37717/tcp 37718/tcp 37719/tcp 37720/tcp 2>/dev/null || true
|
|
||||||
sleep 2
|
|
||||||
}
|
|
||||||
|
|
||||||
# Generate dev index
|
|
||||||
generate_index() {
|
|
||||||
mkdir -p "$DEV_INDEX_DIR"
|
|
||||||
cat > "$DEV_INDEX_DIR/index.html" << 'EOF'
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="de">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
||||||
<title>HdM Slides - Dev</title>
|
|
||||||
<style>
|
|
||||||
*{box-sizing:border-box;margin:0;padding:0}
|
|
||||||
body{font-family:-apple-system,BlinkMacSystemFont,"SF Pro Display","Segoe UI",Roboto,sans-serif;max-width:720px;margin:0 auto;padding:3rem 1.5rem;background:#fafafa;color:#1d1d1f;line-height:1.5}
|
|
||||||
h1{font-size:2rem;font-weight:600;letter-spacing:-0.02em;margin-bottom:.5rem}
|
|
||||||
.subtitle{color:#86868b;font-size:1rem}
|
|
||||||
.courses{margin-top:2rem;display:flex;flex-direction:column;gap:.75rem}
|
|
||||||
a.course{display:block;background:#fff;border-radius:12px;padding:1.5rem;text-decoration:none;color:inherit;box-shadow:0 1px 3px rgba(0,0,0,0.08);transition:all .2s ease;cursor:pointer}
|
|
||||||
a.course:hover{transform:translateY(-2px);box-shadow:0 4px 12px rgba(0,0,0,0.12)}
|
|
||||||
.course-label{font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em}
|
|
||||||
.course-b .course-label{color:#1e5f8a}
|
|
||||||
.course-c .course-label{color:#d63384}
|
|
||||||
.course-title{font-size:1.15rem;font-weight:500;color:#1d1d1f;margin:.25rem 0}
|
|
||||||
.course-info{font-size:.85rem;color:#86868b}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>HdM Slides</h1>
|
|
||||||
<p class="subtitle">Development Server</p>
|
|
||||||
<div class="courses">
|
|
||||||
EOF
|
|
||||||
echo " <a class=\"course course-b\" href=\"http://localhost:$COURSE_B_PORT\"><span class=\"course-label\">223015b</span><div class=\"course-title\">Dateiformate, Schnittstellen, Speichermedien & Distributionswege</div><span class=\"course-info\">Port $COURSE_B_PORT</span></a>" >> "$DEV_INDEX_DIR/index.html"
|
|
||||||
echo " <a class=\"course course-c\" href=\"http://localhost:$COURSE_C_PORT\"><span class=\"course-label\">223015c</span><div class=\"course-title\">Grundlagen IT- und Internettechnik</div><span class=\"course-info\">Port $COURSE_C_PORT</span></a>" >> "$DEV_INDEX_DIR/index.html"
|
|
||||||
cat >> "$DEV_INDEX_DIR/index.html" << 'EOF'
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
EOF
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Main
|
# Main
|
||||||
trap cleanup SIGINT SIGTERM
|
trap 'echo -e "\n${RED}Shutting down...${NC}"; kill 0; exit 0' SIGINT SIGTERM
|
||||||
|
|
||||||
kill_existing
|
kill_port
|
||||||
generate_index
|
|
||||||
|
|
||||||
echo -e "${GREEN}Starting development servers...${NC}"
|
if [ -n "$COURSE" ]; then
|
||||||
echo ""
|
SERVE_DIR="$SLIDES_DIR/$COURSE"
|
||||||
echo -e " Index: ${BLUE}http://localhost:$INDEX_PORT${NC}"
|
echo -e "${GREEN}Marp dev server${NC} · ${BLUE}$COURSE${NC}"
|
||||||
echo -e " 223015b: ${BLUE}http://localhost:$COURSE_B_PORT${NC}"
|
else
|
||||||
echo -e " 223015c: ${BLUE}http://localhost:$COURSE_C_PORT${NC}"
|
SERVE_DIR="$SLIDES_DIR"
|
||||||
echo ""
|
echo -e "${GREEN}Marp dev server${NC} · ${BLUE}all courses${NC}"
|
||||||
echo -e "Press ${RED}Ctrl+C${NC} to stop all servers"
|
fi
|
||||||
|
|
||||||
|
echo -e " ${BLUE}http://localhost:$DEV_PORT${NC}"
|
||||||
|
echo -e " ${BLUE}$SERVE_DIR/${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Start servers
|
PORT=$DEV_PORT exec npx @marp-team/marp-cli -c marp.config.js --server "$SERVE_DIR/"
|
||||||
python3 -m http.server $INDEX_PORT --directory "$DEV_INDEX_DIR" &
|
|
||||||
PID_INDEX=$!
|
|
||||||
|
|
||||||
PORT=$COURSE_B_PORT npx @marp-team/marp-cli --server "$COURSE_DIR/223015b/slides/" &
|
|
||||||
PID_B=$!
|
|
||||||
|
|
||||||
sleep 3 # Stagger starts to avoid WebSocket port collision
|
|
||||||
|
|
||||||
PORT=$COURSE_C_PORT npx @marp-team/marp-cli --server "$COURSE_DIR/223015c/slides/" &
|
|
||||||
PID_C=$!
|
|
||||||
|
|
||||||
# Wait for any process to exit
|
|
||||||
wait
|
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Extract klausur-relevant slides from all kapitel
|
||||||
|
# Usage: ./extract-klausur.sh <course_id>
|
||||||
|
# Output: slides/<course>/klausurfolien.md
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
COURSE="${1:-223015b}"
|
||||||
|
SLIDES_DIR="slides/$COURSE"
|
||||||
|
OUTPUT_FILE="$SLIDES_DIR/klausurfolien.md"
|
||||||
|
|
||||||
|
# Find the first kapitel file (00-intro.md or 01-*.md) to copy styles from
|
||||||
|
FIRST_KAPITEL=$(ls "$SLIDES_DIR"/00-intro.md "$SLIDES_DIR"/01-*.md 2>/dev/null | head -1)
|
||||||
|
|
||||||
|
if [[ -z "$FIRST_KAPITEL" ]]; then
|
||||||
|
echo "Error: No 00-intro.md or 01-*.md file found in $SLIDES_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Extracting klausur slides for $COURSE..."
|
||||||
|
|
||||||
|
# Extract frontmatter and styles (everything up to first <!-- _class: line after style block)
|
||||||
|
# This gets the YAML frontmatter + <style> block
|
||||||
|
awk '
|
||||||
|
BEGIN { in_frontmatter = 0; in_style = 0; done = 0 }
|
||||||
|
/^---$/ && !in_frontmatter { in_frontmatter = 1; print; next }
|
||||||
|
/^---$/ && in_frontmatter && !in_style { in_frontmatter = 0; print; next }
|
||||||
|
in_frontmatter { print; next }
|
||||||
|
/<style>/ { in_style = 1; print; next }
|
||||||
|
/<\/style>/ { in_style = 0; print; print ""; done = 1; next }
|
||||||
|
in_style { print; next }
|
||||||
|
done { exit }
|
||||||
|
' "$FIRST_KAPITEL" > "$OUTPUT_FILE"
|
||||||
|
|
||||||
|
# Add warning comment
|
||||||
|
cat >> "$OUTPUT_FILE" << 'EOF'
|
||||||
|
<!--
|
||||||
|
╔═══════════════════════════════════════════════════════════════════╗
|
||||||
|
║ AUTO-GENERATED FILE - DO NOT EDIT MANUALLY ║
|
||||||
|
║ ║
|
||||||
|
║ This file is generated by: make klausur ║
|
||||||
|
║ Source: scripts/extract-klausur.sh ║
|
||||||
|
║ ║
|
||||||
|
║ To update, edit the source slides and re-run make klausur ║
|
||||||
|
╚═══════════════════════════════════════════════════════════════════╝
|
||||||
|
-->
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Extract and copy the cover slide (first slide after frontmatter/styles, up to first ---)
|
||||||
|
awk '
|
||||||
|
BEGIN { past_style = 0; in_cover = 0; printed = 0 }
|
||||||
|
/<\/style>/ { past_style = 1; next }
|
||||||
|
past_style && !in_cover && /^[^[:space:]]/ { in_cover = 1 }
|
||||||
|
in_cover && /^---$/ { print "---\n"; exit }
|
||||||
|
in_cover { print }
|
||||||
|
' "$FIRST_KAPITEL" >> "$OUTPUT_FILE"
|
||||||
|
|
||||||
|
# Process each kapitel file in order - extract klausur slides only
|
||||||
|
for md_file in $(ls "$SLIDES_DIR"/[0-9][0-9]-*.md 2>/dev/null | grep -v klausurfolien | sort); do
|
||||||
|
filename=$(basename "$md_file")
|
||||||
|
kapitel_num=$(echo "$filename" | grep -oE '^[0-9]+' | sed 's/^0*//')
|
||||||
|
|
||||||
|
# Skip intro (kapitel 0)
|
||||||
|
if [[ "$kapitel_num" == "0" ]] || [[ -z "$kapitel_num" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if file has any klausur slides
|
||||||
|
if ! grep -q '<!-- _class: klausur -->' "$md_file"; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " Processing Kapitel $kapitel_num..."
|
||||||
|
|
||||||
|
# Extract klausur slides, hide header/footer, convert * to - bullets
|
||||||
|
awk '
|
||||||
|
/<!-- _class: klausur -->/ {
|
||||||
|
in_klausur = 1
|
||||||
|
# Add header/footer hiding
|
||||||
|
print "<!-- _header: \"\" -->"
|
||||||
|
print "<!-- _footer: \"\" -->"
|
||||||
|
print ""
|
||||||
|
next
|
||||||
|
}
|
||||||
|
in_klausur && /^---$/ {
|
||||||
|
print "\n---\n"
|
||||||
|
in_klausur = 0
|
||||||
|
next
|
||||||
|
}
|
||||||
|
in_klausur {
|
||||||
|
# Skip marp directives (we add our own)
|
||||||
|
if (/<!-- _header:/ || /<!-- _footer:/ || /<!-- _backgroundColor:/) next
|
||||||
|
# Convert * bullets to - bullets (avoid fragments)
|
||||||
|
gsub(/^\* /, "- ")
|
||||||
|
gsub(/^ \* /, " - ")
|
||||||
|
gsub(/^ \* /, " - ")
|
||||||
|
print
|
||||||
|
}
|
||||||
|
' "$md_file" >> "$OUTPUT_FILE"
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove trailing --- and empty lines
|
||||||
|
perl -i -0777 -pe 's/\n*---\n*$/\n/' "$OUTPUT_FILE"
|
||||||
|
|
||||||
|
# Count slides
|
||||||
|
slide_count=$(grep -c '^---$' "$OUTPUT_FILE" 2>/dev/null || echo "0")
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Generated: $OUTPUT_FILE"
|
||||||
|
echo "Total slides: $slide_count"
|
||||||
@@ -42,6 +42,15 @@ TOPIC_MAP["geschichte-grundlagen-html"]="Geschichte, Grundlagen & HTML"
|
|||||||
TOPIC_MAP["netzwerke-protokolle-css"]="Netzwerke, Protokolle & CSS"
|
TOPIC_MAP["netzwerke-protokolle-css"]="Netzwerke, Protokolle & CSS"
|
||||||
TOPIC_MAP["interaktivitaet-javascript"]="Interaktivität & JavaScript"
|
TOPIC_MAP["interaktivitaet-javascript"]="Interaktivität & JavaScript"
|
||||||
|
|
||||||
|
# Configure which topics should appear disabled per course
|
||||||
|
# Two modes: fully disabled (non-clickable card) and buttons-disabled (link remains clickable, buttons are disabled)
|
||||||
|
declare -A DISABLED_FULL
|
||||||
|
declare -A DISABLED_BUTTONS
|
||||||
|
# For course B: chapters 3,4,5 should be fully disabled
|
||||||
|
DISABLED_FULL["223015b"]="speichermedien-schnittstellen distribution-apis-zukunft vertiefung-offene-fragen"
|
||||||
|
# For course C: chapter 3 should keep link clickable but buttons disabled
|
||||||
|
DISABLED_BUTTONS["223015c"]="interaktivitaet-javascript"
|
||||||
|
|
||||||
cat > "$BUILD_DIR/index.html" << HEADER
|
cat > "$BUILD_DIR/index.html" << HEADER
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="de">
|
<html lang="de">
|
||||||
@@ -61,6 +70,15 @@ cat > "$BUILD_DIR/index.html" << HEADER
|
|||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
header { margin-bottom: 2rem; }
|
header { margin-bottom: 2rem; }
|
||||||
|
.breadcrumb {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
.breadcrumb a {
|
||||||
|
color: #86868b;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.breadcrumb a:hover { text-decoration: underline; }
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 1.75rem;
|
font-size: 1.75rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@@ -68,6 +86,12 @@ cat > "$BUILD_DIR/index.html" << HEADER
|
|||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
color: $ACCENT_COLOR;
|
color: $ACCENT_COLOR;
|
||||||
}
|
}
|
||||||
|
.course-heading {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1d1d1f;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
.subtitle {
|
.subtitle {
|
||||||
color: #86868b;
|
color: #86868b;
|
||||||
font-size: 0.95rem;
|
font-size: 0.95rem;
|
||||||
@@ -77,13 +101,14 @@ cat > "$BUILD_DIR/index.html" << HEADER
|
|||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
margin-top: 0.25rem;
|
margin-top: 0.25rem;
|
||||||
}
|
}
|
||||||
|
/* Use the .termine wrapper and add a gap between cards */
|
||||||
.termine {
|
.termine {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.75rem;
|
gap: 0.75rem;
|
||||||
}
|
}
|
||||||
.termin-card {
|
.kapitel-card {
|
||||||
position: relative;
|
position: relative;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
@@ -93,32 +118,35 @@ cat > "$BUILD_DIR/index.html" << HEADER
|
|||||||
grid-template-columns: 1fr auto auto;
|
grid-template-columns: 1fr auto auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
padding: 0; /* inner padding handled by kapitel-link */
|
||||||
}
|
}
|
||||||
.termin-card:hover {
|
.kapitel-card:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 4px 12px rgba(0,0,0,0.12);
|
box-shadow: 0 4px 12px rgba(0,0,0,0.12);
|
||||||
}
|
}
|
||||||
.termin-link {
|
.kapitel-link {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 1.25rem 1.5rem;
|
padding: 1.25rem 1.5rem;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
}
|
}
|
||||||
.termin-label {
|
/* Disabled look: dim the entire card and prevent pointer events */
|
||||||
|
.kapitel-card.disabled { opacity: 0.6; pointer-events: none; }
|
||||||
|
.kapitel-label {
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: $ACCENT_COLOR;
|
color: $ACCENT_COLOR;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
}
|
}
|
||||||
.termin-title {
|
.kapitel-title {
|
||||||
font-size: 1.05rem;
|
font-size: 1.05rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #1d1d1f;
|
color: #1d1d1f;
|
||||||
margin: 0.15rem 0;
|
margin: 0.15rem 0;
|
||||||
}
|
}
|
||||||
.termin-date {
|
.kapitel-date {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
color: #86868b;
|
color: #86868b;
|
||||||
}
|
}
|
||||||
@@ -135,11 +163,11 @@ cat > "$BUILD_DIR/index.html" << HEADER
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
margin-right: 0.5rem;
|
||||||
}
|
}
|
||||||
.btn-slides {
|
.btn-slides {
|
||||||
background: $ACCENT_COLOR;
|
background: $ACCENT_COLOR;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
margin-right: 0.5rem;
|
|
||||||
}
|
}
|
||||||
.btn-slides:hover {
|
.btn-slides:hover {
|
||||||
filter: brightness(1.1);
|
filter: brightness(1.1);
|
||||||
@@ -147,11 +175,11 @@ cat > "$BUILD_DIR/index.html" << HEADER
|
|||||||
.btn-pdf {
|
.btn-pdf {
|
||||||
background: #f5f5f7;
|
background: #f5f5f7;
|
||||||
color: #1d1d1f;
|
color: #1d1d1f;
|
||||||
margin-right: 1rem;
|
|
||||||
}
|
}
|
||||||
.btn-pdf:hover { background: #e8e8ed; }
|
.btn-pdf:hover { background: #e8e8ed; }
|
||||||
|
.btn-disabled { opacity: 0.6; pointer-events: none; }
|
||||||
/* Make entire card clickable via overlay */
|
/* Make entire card clickable via overlay */
|
||||||
.termin-link::after {
|
.kapitel-link::after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
@@ -184,10 +212,10 @@ cat > "$BUILD_DIR/index.html" << HEADER
|
|||||||
color: #86868b;
|
color: #86868b;
|
||||||
}
|
}
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
.termin-card {
|
.kapitel-card {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
.termin-link {
|
.kapitel-link {
|
||||||
padding-bottom: 0.75rem;
|
padding-bottom: 0.75rem;
|
||||||
}
|
}
|
||||||
.btn-slides, .btn-pdf {
|
.btn-slides, .btn-pdf {
|
||||||
@@ -198,63 +226,140 @@ cat > "$BUILD_DIR/index.html" << HEADER
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<h1>$TITLE</h1>
|
<p class="breadcrumb"><a href="../">← Kursübersicht</a></p>
|
||||||
|
<h1>HdM Vorlesungen</h1>
|
||||||
|
<h2 class="course-heading">$TITLE</h2>
|
||||||
<p class="subtitle">$SUBTITLE</p>
|
<p class="subtitle">$SUBTITLE</p>
|
||||||
<p class="meta">HdM Stuttgart · Wintersemester 2025/26 · Michael Czechowski</p>
|
<p class="meta">HdM Stuttgart · Sommersemester 2026 · Michael Czechowski</p>
|
||||||
</header>
|
</header>
|
||||||
<div class="termine">
|
<div class="termine">
|
||||||
HEADER
|
HEADER
|
||||||
|
|
||||||
# Generate links for each termin (sorted)
|
# Generate links for each kapitel (sorted)
|
||||||
for html in $(ls "$BUILD_DIR"/2*.html 2>/dev/null | sort); do
|
for html in $(ls "$BUILD_DIR"/[0-9][0-9]-*.html 2>/dev/null | sort); do
|
||||||
filename=$(basename "$html")
|
filename=$(basename "$html")
|
||||||
|
|
||||||
# Extract components from filename
|
# Extract components from filename (format: NN-topic.html)
|
||||||
date=$(echo "$filename" | grep -oE '^[0-9]{4}-[0-9x]{2}-[0-9x]{2}')
|
kapitel_num=$(echo "$filename" | grep -oE '^[0-9]+' | sed 's/^0*//')
|
||||||
termin_num=$(echo "$filename" | grep -oE 'termin-[0-9]+' | grep -oE '[0-9]+')
|
topic_raw=$(echo "$filename" | sed -E 's/^[0-9]+-//' | sed 's/\.html$//')
|
||||||
topic_raw=$(echo "$filename" | sed -E 's/^[0-9]{4}-[0-9x]{2}-[0-9x]{2}-termin-[0-9]+-//' | sed 's/\.html$//')
|
|
||||||
|
|
||||||
# Look up nice topic name or fallback
|
# Look up nice topic name or fallback
|
||||||
topic="${TOPIC_MAP[$topic_raw]}"
|
topic="${TOPIC_MAP[$topic_raw]}"
|
||||||
if [[ -z "$topic" ]]; then
|
if [[ -z "$topic" ]]; then
|
||||||
topic=$(echo "$topic_raw" | sed 's/-/ /g' | sed 's/.*/\u&/')
|
topic=$(echo "$topic_raw" | sed 's/-/ /g' | sed 's/.*/\\u&/')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Format date
|
# Handle kapitel number
|
||||||
if [[ "$date" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && [[ ! "$date" =~ xx ]]; then
|
if [[ "$kapitel_num" == "0" ]] || [[ -z "$kapitel_num" ]]; then
|
||||||
formatted_date=$(date -d "$date" "+%d. %B %Y" 2>/dev/null || echo "$date")
|
kapitel_label="Einführung"
|
||||||
else
|
else
|
||||||
formatted_date="Termin folgt"
|
kapitel_label="Kapitel $kapitel_num"
|
||||||
fi
|
|
||||||
|
|
||||||
# Handle termin number
|
|
||||||
if [[ "$termin_num" == "0" ]]; then
|
|
||||||
termin_label="Einführung"
|
|
||||||
else
|
|
||||||
termin_label="Termin $termin_num"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
pdf_filename="${filename%.html}.pdf"
|
pdf_filename="${filename%.html}.pdf"
|
||||||
|
|
||||||
# Check if PDF exists
|
# Determine whether this topic is configured as disabled for this course
|
||||||
pdf_link=""
|
disabled_full=false
|
||||||
if [[ -f "$BUILD_DIR/$pdf_filename" ]]; then
|
disabled_buttons=false
|
||||||
pdf_link="<a href=\"$pdf_filename\" class=\"btn btn-pdf\">PDF</a>"
|
for t in ${DISABLED_FULL["$COURSE"]}; do
|
||||||
|
if [[ "$topic_raw" == "$t" ]]; then
|
||||||
|
disabled_full=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ "$disabled_full" == false ]]; then
|
||||||
|
for t in ${DISABLED_BUTTONS["$COURSE"]}; do
|
||||||
|
if [[ "$topic_raw" == "$t" ]]; then
|
||||||
|
disabled_buttons=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Decide card class
|
||||||
|
card_class="kapitel-card"
|
||||||
|
if [[ "$disabled_full" == true ]] || [[ "$disabled_buttons" == true ]]; then
|
||||||
|
card_class="$card_class disabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build link/button HTML depending on disabled state
|
||||||
|
if [[ "$disabled_full" == true ]]; then
|
||||||
|
# non-interactive card (visually dimmed and not clickable)
|
||||||
|
link_html="<div class=\"kapitel-link\"><div class=\"kapitel-label\">$kapitel_label</div><div class=\"kapitel-title\">$topic</div></div>"
|
||||||
|
slides_html="<span class=\"btn btn-slides btn-disabled\">Folien</span>"
|
||||||
|
pdf_html=""
|
||||||
|
if [[ -f "$BUILD_DIR/$pdf_filename" ]]; then
|
||||||
|
pdf_html="<span class=\"btn btn-pdf btn-disabled\">PDF</span>"
|
||||||
|
fi
|
||||||
|
elif [[ "$disabled_buttons" == true ]]; then
|
||||||
|
# link stays clickable, but buttons are disabled; card appears dimmed
|
||||||
|
link_html="<a href=\"$filename\" class=\"kapitel-link\"><div class=\"kapitel-label\">$kapitel_label</div><div class=\"kapitel-title\">$topic</div></a>"
|
||||||
|
slides_html="<span class=\"btn btn-slides btn-disabled\">Folien</span>"
|
||||||
|
pdf_html=""
|
||||||
|
if [[ -f "$BUILD_DIR/$pdf_filename" ]]; then
|
||||||
|
pdf_html="<span class=\"btn btn-pdf btn-disabled\">PDF</span>"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# normal interactive card
|
||||||
|
pdf_link=""
|
||||||
|
if [[ -f "$BUILD_DIR/$pdf_filename" ]]; then
|
||||||
|
pdf_link="<a href=\"$pdf_filename\" class=\"btn btn-pdf\">PDF</a>"
|
||||||
|
fi
|
||||||
|
link_html="<a href=\"$filename\" class=\"kapitel-link\"><div class=\"kapitel-label\">$kapitel_label</div><div class=\"kapitel-title\">$topic</div></a>"
|
||||||
|
slides_html="<a href=\"$filename\" class=\"btn btn-slides\">Folien</a>"
|
||||||
|
pdf_html="$pdf_link"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cat >> "$BUILD_DIR/index.html" << LINK
|
cat >> "$BUILD_DIR/index.html" << LINK
|
||||||
<div class="termin-card">
|
<div class="$card_class">
|
||||||
<a href="$filename" class="termin-link">
|
$link_html
|
||||||
<div class="termin-label">$termin_label</div>
|
$slides_html
|
||||||
<div class="termin-title">$topic</div>
|
$pdf_html
|
||||||
<div class="termin-date">$formatted_date</div>
|
|
||||||
</a>
|
|
||||||
<a href="$filename" class="btn btn-slides">Folien</a>
|
|
||||||
$pdf_link
|
|
||||||
</div>
|
</div>
|
||||||
LINK
|
LINK
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Add klausurfolien entry if it exists (disabled — wird noch überarbeitet)
|
||||||
|
if [[ -f "$BUILD_DIR/klausurfolien.html" ]]; then
|
||||||
|
pdf_disabled=""
|
||||||
|
if [[ -f "$BUILD_DIR/klausurfolien.pdf" ]]; then
|
||||||
|
pdf_disabled="<span class=\"btn btn-pdf btn-disabled\">PDF</span>"
|
||||||
|
fi
|
||||||
|
cat >> "$BUILD_DIR/index.html" << KLAUSUR
|
||||||
|
<div class="kapitel-card disabled" style="border-left: 3px solid $ACCENT_COLOR;">
|
||||||
|
<div class="kapitel-link">
|
||||||
|
<div class="kapitel-label">Prüfung</div>
|
||||||
|
<div class="kapitel-title">Klausurrelevante Folien</div>
|
||||||
|
</div>
|
||||||
|
<span class="btn btn-slides btn-disabled">Folien</span>
|
||||||
|
$pdf_disabled
|
||||||
|
</div>
|
||||||
|
KLAUSUR
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add klausurfragen entry if it exists (disabled — wird noch überarbeitet)
|
||||||
|
if [[ -f "$BUILD_DIR/klausurfragen.html" ]] || [[ -f "$BUILD_DIR/klausurfragen.pdf" ]]; then
|
||||||
|
pdf_disabled=""
|
||||||
|
if [[ -f "$BUILD_DIR/klausurfragen.pdf" ]]; then
|
||||||
|
pdf_disabled="<span class=\"btn btn-pdf btn-disabled\">PDF</span>"
|
||||||
|
fi
|
||||||
|
slides_disabled=""
|
||||||
|
if [[ -f "$BUILD_DIR/klausurfragen.html" ]]; then
|
||||||
|
slides_disabled="<span class=\"btn btn-slides btn-disabled\">Folien</span>"
|
||||||
|
fi
|
||||||
|
cat >> "$BUILD_DIR/index.html" << KLAUSURFRAGEN
|
||||||
|
<div class="kapitel-card disabled" style="border-left: 3px solid $ACCENT_COLOR;">
|
||||||
|
<div class="kapitel-link">
|
||||||
|
<div class="kapitel-label">Prüfung</div>
|
||||||
|
<div class="kapitel-title">Klausurfragen</div>
|
||||||
|
</div>
|
||||||
|
$slides_disabled
|
||||||
|
$pdf_disabled
|
||||||
|
</div>
|
||||||
|
KLAUSURFRAGEN
|
||||||
|
fi
|
||||||
|
|
||||||
cat >> "$BUILD_DIR/index.html" << FOOTER
|
cat >> "$BUILD_DIR/index.html" << FOOTER
|
||||||
</div>
|
</div>
|
||||||
<div class="qr-section">
|
<div class="qr-section">
|
||||||
@@ -263,7 +368,7 @@ cat >> "$BUILD_DIR/index.html" << FOOTER
|
|||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<a href="mailto:mail@librete.ch">Kontakt</a> ·
|
<a href="mailto:mail@librete.ch">Kontakt</a> ·
|
||||||
<a href="../">Alle Kurse</a>
|
<a href="../">Kursübersicht</a>
|
||||||
</footer>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Generate root index.html for HdM slides overview
|
||||||
|
# Usage: ./generate-root-index.sh
|
||||||
|
|
||||||
|
BUILD_DIR="${1:-build}"
|
||||||
|
|
||||||
|
cat > "$BUILD_DIR/index.html" << 'HEADER'
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>HdM Vorlesungen</title>
|
||||||
|
<style>
|
||||||
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", Roboto, sans-serif;
|
||||||
|
max-width: 720px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 3rem 1.5rem;
|
||||||
|
background: #fafafa;
|
||||||
|
color: #1d1d1f;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
.subtitle { color: #86868b; font-size: 1rem; }
|
||||||
|
.courses {
|
||||||
|
margin-top: 2rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
.course-card {
|
||||||
|
position: relative;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr auto auto;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
.course-card:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.12);
|
||||||
|
}
|
||||||
|
.course-link {
|
||||||
|
display: block;
|
||||||
|
padding: 1.25rem 1.5rem;
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
.course-link::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
.course-label {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
}
|
||||||
|
.course-b .course-label { color: #1e5f8a; }
|
||||||
|
.course-c .course-label { color: #d63384; }
|
||||||
|
.course-title {
|
||||||
|
font-size: 1.15rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1d1d1f;
|
||||||
|
margin: 0.25rem 0;
|
||||||
|
}
|
||||||
|
.course-info { font-size: 0.85rem; color: #86868b; }
|
||||||
|
.section-title {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #86868b;
|
||||||
|
margin-top: 2.5rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
.references {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
margin-top: 2.5rem;
|
||||||
|
padding-top: 1.5rem;
|
||||||
|
border-top: 1px solid #e5e5e7;
|
||||||
|
color: #86868b;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
footer a { color: #1d1d1f; text-decoration: none; }
|
||||||
|
footer a:hover { text-decoration: underline; }
|
||||||
|
.qr-section {
|
||||||
|
margin-top: 2.5rem;
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.qr-code { width: 100%; height: auto; }
|
||||||
|
.qr-url { margin-top: 0.75rem; font-size: 0.85rem; color: #86868b; }
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.course-card { grid-template-columns: 1fr; }
|
||||||
|
.course-link { padding-bottom: 0.75rem; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>HdM Vorlesungen</h1>
|
||||||
|
<p class="subtitle">Sommersemester 2026 · Michael Czechowski</p>
|
||||||
|
<div class="courses">
|
||||||
|
<div class="course-card course-b">
|
||||||
|
<a href="223015b/" class="course-link">
|
||||||
|
<span class="course-label">223015b</span>
|
||||||
|
<div class="course-title">Dateiformate, Schnittstellen, Speichermedien & Distributionswege</div>
|
||||||
|
<span class="course-info">6 Kapitel · Modul "Technik 1"</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="course-card course-c">
|
||||||
|
<a href="223015c/" class="course-link">
|
||||||
|
<span class="course-label">223015c</span>
|
||||||
|
<div class="course-title">Grundlagen IT- und Internettechnik</div>
|
||||||
|
<span class="course-info">3 Kapitel · Modul "Technik 1"</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h2 class="section-title">Referenzen</h2>
|
||||||
|
<div class="references">
|
||||||
|
<div class="course-card">
|
||||||
|
<a href="https://codecrispi.es/" class="course-link">
|
||||||
|
<span class="course-label">Plattform</span>
|
||||||
|
<div class="course-title">Code Crispies</div>
|
||||||
|
<span class="course-info">Selbstlernplattform</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="qr-section">
|
||||||
|
<img src="qr-root.svg" alt="QR Code" class="qr-code">
|
||||||
|
<p class="qr-url">https://librete.ch/hdm/</p>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<a href="mailto:mail@librete.ch">Kontakt</a>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
HEADER
|
||||||
|
|
||||||
|
echo "Generated $BUILD_DIR/index.html"
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
---
|
||||||
|
marp: true
|
||||||
|
theme: gaia
|
||||||
|
paginate: true
|
||||||
|
backgroundColor: #fff
|
||||||
|
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege (223015b)"
|
||||||
|
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
|
||||||
|
title: Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
||||||
|
---
|
||||||
|
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--color-foreground: #1a1a2e;
|
||||||
|
--color-highlight: #1e5f8a;
|
||||||
|
--color-dimmed: #4a4a6a;
|
||||||
|
}
|
||||||
|
section.invert {
|
||||||
|
--color-foreground: #fff;
|
||||||
|
}
|
||||||
|
section {
|
||||||
|
font-size: 1.7rem;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
color: #1e5f8a;
|
||||||
|
}
|
||||||
|
section.invert h1 {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
color: #1f2937;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
background: #0f0f23;
|
||||||
|
color: #5fb3e4;
|
||||||
|
border-radius: 8px;
|
||||||
|
border-left: 3px solid #1e5f8a;
|
||||||
|
}
|
||||||
|
pre code {
|
||||||
|
background: transparent;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
code {
|
||||||
|
background: #0f0f23;
|
||||||
|
padding: 0.15em 0.4em;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||||||
|
}
|
||||||
|
section code:not(.hljs) { color: #5fb3e4 !important; }
|
||||||
|
section code.hljs { color: #f8f8f8 !important; }
|
||||||
|
a {
|
||||||
|
color: var(--color-highlight);
|
||||||
|
}
|
||||||
|
section.klausur {
|
||||||
|
background: repeating-linear-gradient(
|
||||||
|
135deg,
|
||||||
|
#e3f2fd,
|
||||||
|
#e3f2fd 40px,
|
||||||
|
#fff 40px,
|
||||||
|
#fff 80px
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
@media print {
|
||||||
|
section.klausur {
|
||||||
|
background: #e3f2fd !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
section.aufgabe {
|
||||||
|
background: #e3f2fd !important;
|
||||||
|
}
|
||||||
|
section.aufgabe footer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- _class: invert -->
|
||||||
|
<!-- _header: '' -->
|
||||||
|
<!-- _backgroundColor: #000 -->
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
||||||
|
|
||||||
|
**223015b** · Modul "Technik 1" · 1. Semester
|
||||||
|
Digital- und Medienwirtschaft
|
||||||
|
Hochschule der Medien Stuttgart
|
||||||
|
|
||||||
|
**Sommersemester 2026**
|
||||||
|
|
||||||
|
[https://librete.ch/hdm/223015b/](https://librete.ch/hdm/223015b/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _header: '' -->
|
||||||
|
<!-- _footer: '' -->
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: lead -->
|
||||||
|
|
||||||
|
# Herzlich willkommen!
|
||||||
|
## Einführung
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Über mich
|
||||||
|
|
||||||
|
**Michael Werner Czechowski**
|
||||||
|
|
||||||
|
- Systems and Platform Engineer
|
||||||
|
- Schwerpunkte:
|
||||||
|
- Web-Technologien, Barriere-Armut, Systemarchitektur, Open Source
|
||||||
|
- Hintergrund:
|
||||||
|
- Philosophie (Uni Stuttgart)
|
||||||
|
- Wirtschaftsinformatik (Leibniz-FH Hannover)
|
||||||
|
- Kontakt: lb-czechowski@hdm-stuttgart.de
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Warum dieses Modul?
|
||||||
|
|
||||||
|
**Digitale Medien sind überall.**
|
||||||
|
|
||||||
|
* Warum enthalten Fotos oft Informationen über den Aufnahmeort?
|
||||||
|
* Warum lassen sich gelöschte Dateien wiederherstellen?
|
||||||
|
* Warum benötigt eine Minute 4K-Video unkomprimiert 45 GB Speicher?
|
||||||
|
* Warum zeigt eine "1 TB"-Festplatte nur 931 GB an?
|
||||||
|
* Warum ist USB-C nicht gleich USB-C?
|
||||||
|
* Ziel: **→ Mitreden können!**
|
||||||
|
|
||||||
|
<!--
|
||||||
|
1. EXIF (Exchangeable Image File Format)-Metadaten speichern GPS-Koordinaten, Kameramodell und Zeitstempel automatisch. Die meisten wissen nicht, dass diese Daten beim Versenden mitgeschickt werden. → Kapitel 4: Metadaten
|
||||||
|
|
||||||
|
2. Beim Löschen wird nur der Verzeichniseintrag im Dateisystem entfernt, nicht die Daten selbst. Die Bits bleiben auf dem Datenträger, bis sie überschrieben werden. → Kapitel 3: Dateisysteme
|
||||||
|
|
||||||
|
3. 3840 × 2160 Pixel × 3 Byte (RGB) × 30 Bilder/Sek × 60 Sek = ~45 GB. Codecs wie H.264/H.265 komprimieren um Faktor 100+. → Kapitel 1+2: Kompression
|
||||||
|
|
||||||
|
4. Hersteller rechnen dezimal (1 TB = 10¹² Bytes), Betriebssysteme binär (1 TiB = 2⁴⁰ Bytes). Die Differenz beträgt bei Terabyte bereits ~10%. → Kapitel 1: Dateneinheiten
|
||||||
|
|
||||||
|
5. USB-C ist nur die Steckerform. Dahinter können USB 2.0 (480 Mbit/s), USB 3.2 (20 Gbit/s) oder Thunderbolt 4 (40 Gbit/s) laufen — gleiches Kabel, völlig unterschiedliche Leistung. → Kapitel 3: Schnittstellen
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Kurze Umfrage
|
||||||
|
|
||||||
|
**Bitte Hand heben:**
|
||||||
|
|
||||||
|
* Wer kennt den Unterschied zwischen analog und digital?
|
||||||
|
* Wer hat schon mal eine Datei von einem Format in ein anderes konvertiert?
|
||||||
|
* Wer hat schon mal Metadaten aus einem Foto entfernt?
|
||||||
|
* Wer hat schon mal ein Backup verloren?
|
||||||
|
* Wer hat schon mal ein Backup wiederhergestellt?
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Niveau der Gruppe einschätzen
|
||||||
|
Keine falschen Antworten
|
||||||
|
Zeigt, wo wir starten
|
||||||
|
API = Application Programming Interface
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Kursübersicht
|
||||||
|
|
||||||
|
**Kapitel:**
|
||||||
|
|
||||||
|
* 1. **Grundlagen**, Text & Audio (Bits, Bytes, Zeichenkodierung, MP3)
|
||||||
|
* 2. Bild- & Video-**Kompression** (JPEG, PNG, H.264/H.265)
|
||||||
|
* 3. **Speichermedien** & **Schnittstellen** (HDD, SSD, USB, Thunderbolt)
|
||||||
|
* 4. **Distribution** und Verteilung (Streaming, REST, Cloud)
|
||||||
|
* Vertiefung & offene Fragen
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: klausur -->
|
||||||
|
<!-- _header: '' -->
|
||||||
|
<!-- _footer: '' -->
|
||||||
|
<!-- _backgroundColor: #e3f2fd -->
|
||||||
|
|
||||||
|
# Prüfungsleistung
|
||||||
|
|
||||||
|
**Nach aktuellem Kenntnisstand:**
|
||||||
|
|
||||||
|
* 90 min insg. (Technik 1)
|
||||||
|
* Schriftliche Klausur (digital)
|
||||||
|
* Teils offene Fragen
|
||||||
|
* Kein Coding/Programmieren
|
||||||
|
* **Prüfungsrelevante Folien:**
|
||||||
|
- Gestreift oder Vollton (PDF) markiert
|
||||||
@@ -0,0 +1,850 @@
|
|||||||
|
---
|
||||||
|
marp: true
|
||||||
|
theme: gaia
|
||||||
|
paginate: true
|
||||||
|
backgroundColor: #fff
|
||||||
|
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege (223015b)"
|
||||||
|
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
|
||||||
|
title: Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
||||||
|
---
|
||||||
|
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--color-foreground: #1a1a2e;
|
||||||
|
--color-highlight: #1e5f8a;
|
||||||
|
--color-dimmed: #4a4a6a;
|
||||||
|
}
|
||||||
|
section.invert {
|
||||||
|
--color-foreground: #fff;
|
||||||
|
}
|
||||||
|
section {
|
||||||
|
font-size: 1.7rem;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
color: #1e5f8a;
|
||||||
|
}
|
||||||
|
section.invert h1 {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
color: #1f2937;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
background: #0f0f23;
|
||||||
|
color: #5fb3e4;
|
||||||
|
border-radius: 8px;
|
||||||
|
border-left: 3px solid #1e5f8a;
|
||||||
|
}
|
||||||
|
pre code {
|
||||||
|
background: transparent;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
code {
|
||||||
|
background: #0f0f23;
|
||||||
|
padding: 0.15em 0.4em;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||||||
|
}
|
||||||
|
section code:not(.hljs) { color: #5fb3e4 !important; }
|
||||||
|
section code.hljs { color: #f8f8f8 !important; }
|
||||||
|
a {
|
||||||
|
color: var(--color-highlight);
|
||||||
|
}
|
||||||
|
section.klausur {
|
||||||
|
background: repeating-linear-gradient(
|
||||||
|
135deg,
|
||||||
|
#e3f2fd,
|
||||||
|
#e3f2fd 40px,
|
||||||
|
#fff 40px,
|
||||||
|
#fff 80px
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
@media print {
|
||||||
|
section.klausur {
|
||||||
|
background: #e3f2fd !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
section.aufgabe {
|
||||||
|
background: #e3f2fd !important;
|
||||||
|
}
|
||||||
|
section.aufgabe footer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
section.erklaerung {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
section.erklaerung h1 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: #1e5f8a;
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
|
}
|
||||||
|
section.erklaerung ul,
|
||||||
|
section.erklaerung ol {
|
||||||
|
font-size: 1.0rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
section.erklaerung p {
|
||||||
|
font-size: 1.0rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
section.erklaerung table {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- _class: invert -->
|
||||||
|
<!-- _header: '' -->
|
||||||
|
<!-- _backgroundColor: #000 -->
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
||||||
|
|
||||||
|
**223015b** · Modul "Technik 1" · 1. Semester
|
||||||
|
Digital- und Medienwirtschaft
|
||||||
|
Hochschule der Medien Stuttgart
|
||||||
|
|
||||||
|
**Sommersemester 2026**
|
||||||
|
|
||||||
|
[https://librete.ch/hdm/223015b/](https://librete.ch/hdm/223015b/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _header: '' -->
|
||||||
|
<!-- _footer: '' -->
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: lead -->
|
||||||
|
|
||||||
|
# Kapitel 3 – 23.01.2026
|
||||||
|
## Speichermedien & Schnittstellen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _header: '' -->
|
||||||
|
<!-- _footer: '' -->
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
<!--
|
||||||
|
HDD aufgeschraubt neben SSD-Platine
|
||||||
|
Mechanisch vs. Elektronisch
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Speicherkapazität: KB vs. KiB
|
||||||
|
|
||||||
|
**Das Problem:** Hersteller vs. Betriebssysteme
|
||||||
|
|
||||||
|
| Dezimal (SI) | Binär (IEC) |
|
||||||
|
|--------------|-------------|
|
||||||
|
| 1 KB = 1.000 Bytes | 1 KiB = 1.024 Bytes |
|
||||||
|
| 1 MB = 1.000 KB | 1 MiB = 1.024 KiB |
|
||||||
|
| 1 GB = 1.000 MB | 1 GiB = 1.024 MiB |
|
||||||
|
| 1 TB = 1.000 GB | 1 TiB = 1.024 GiB |
|
||||||
|
|
||||||
|
**1 TB Festplatte → Windows zeigt ~931 GB!**
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Hersteller: Dezimal (SI-Präfix) - klingt mehr!
|
||||||
|
Betriebssysteme: Binär - aber zeigen "GB" statt "GiB"
|
||||||
|
Diskrepanz bei 1 TB: 1.000.000.000.000 vs. 1.099.511.627.776 Bytes
|
||||||
|
→ 10% Unterschied bei TB-Größen
|
||||||
|
Verwirrung für KonsumentInnen seit Jahrzehnten
|
||||||
|
ISO/IEC 80000-13: Definiert KiB, MiB, GiB, TiB (2008)
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# HDD: Aufbau & Struktur
|
||||||
|
|
||||||
|
**Komponenten:**
|
||||||
|
- **Platter:** Magnetisch beschichtete Scheiben
|
||||||
|
- **Spindel:** Dreht mit 5.400-7.200 RPM
|
||||||
|
- **Schreib-Lese-Kopf:** Schwebt nm-dünn über Platter
|
||||||
|
- **Aktuator:** Bewegt Kopf zur richtigen Spur
|
||||||
|
|
||||||
|
**Logische Struktur:**
|
||||||
|
- **Spuren:** Konzentrische Kreise auf Platter
|
||||||
|
- **Sektoren:** Unterteilung der Spuren (512 Bytes)
|
||||||
|
- **Zylinder:** Gleiche Spuren aller Platter
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Aufbau seit 1956 (IBM) grundsätzlich gleich
|
||||||
|
Platter: Aluminium oder Glas mit Magnetschicht
|
||||||
|
Spindelgeschwindigkeit: Desktop 7.200, Laptop 5.400, Server 15.000 RPM
|
||||||
|
Head Crash: Schreib-Lese-Kopf berührt Platter → Kratzer → Datenverlust
|
||||||
|
Sektor: Kleinste adressierbare Einheit
|
||||||
|
LBA (Logical Block Addressing): Abstraktion der physischen Struktur
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# NVMe: Die SSD-Revolution
|
||||||
|
|
||||||
|
**NVMe = Non-Volatile Memory Express (2011)**
|
||||||
|
|
||||||
|
**Unterschied zu SATA-SSD:**
|
||||||
|
- SATA: Max. ~550 MB/s (AHCI-Protokoll)
|
||||||
|
- NVMe: Bis zu 7.000+ MB/s (PCIe direkt)
|
||||||
|
|
||||||
|
**Form-Faktoren:**
|
||||||
|
2,5" (SATA), M.2 (SATA oder NVMe), PCIe-Karte
|
||||||
|
|
||||||
|
<!--
|
||||||
|
NVMe = Non-Volatile Memory Express
|
||||||
|
Protokoll speziell für Flash-Speicher entwickelt.
|
||||||
|
|
||||||
|
SATA wurde für HDDs entwickelt.
|
||||||
|
Für SSDs ein Flaschenhals.
|
||||||
|
|
||||||
|
M.2 ist ein Formfaktor, kein Protokoll!
|
||||||
|
M.2 kann SATA oder NVMe sein – prüfen!
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# HDD vs. SSD: Vergleich
|
||||||
|
|
||||||
|
| Aspekt | HDD | SSD (NVMe) |
|
||||||
|
|--------|----:|----------:|
|
||||||
|
| Sequentiell | ~150 MB/s | ~3.500 MB/s |
|
||||||
|
| Random Read | ~1 MB/s | ~500 MB/s |
|
||||||
|
| Latenz | ~10 ms | ~0,02 ms |
|
||||||
|
| Preis/TB | ~15€ | ~60€ |
|
||||||
|
| Max. Kapazität | 24 TB | 8 TB (Consumer) |
|
||||||
|
| Haltbarkeit | 3-5 Jahre | 5-10 Jahre |
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Der Random-Access-Unterschied ist dramatisch.
|
||||||
|
500× schneller bei zufälligen Zugriffen.
|
||||||
|
|
||||||
|
Das ist der Grund, warum SSDs Betriebssysteme
|
||||||
|
so viel schneller starten lassen.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: klausur -->
|
||||||
|
<!-- _header: '' -->
|
||||||
|
<!-- _footer: '' -->
|
||||||
|
<!-- _backgroundColor: #e3f2fd -->
|
||||||
|
|
||||||
|
# Wann HDD, wann SSD?
|
||||||
|
|
||||||
|
| Anwendung | Empfehlung |
|
||||||
|
|-----------|------------|
|
||||||
|
| Betriebssystem | SSD (NVMe) |
|
||||||
|
| Anwendungen, Spiele | SSD |
|
||||||
|
| Video-Editing (Projekte) | SSD |
|
||||||
|
| Foto-Archiv | HDD oder SSD |
|
||||||
|
| Backup | HDD |
|
||||||
|
| NAS / Server | HDD (oder Mix) |
|
||||||
|
| Cold Storage | HDD oder Band |
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Die Faustregel:
|
||||||
|
- Oft genutzt, schnell gebraucht → SSD
|
||||||
|
- Selten genutzt, viel Kapazität → HDD
|
||||||
|
|
||||||
|
Viele setzen auf beides:
|
||||||
|
Kleine SSD für System + große HDD für Archiv.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: erklaerung -->
|
||||||
|
<!-- _header: '' -->
|
||||||
|
<!-- _footer: '' -->
|
||||||
|
|
||||||
|
# HDD vs. SSD – Vertiefung
|
||||||
|
|
||||||
|
**HDD (Hard Disk Drive):** Magnetplatten rotieren mit 5.400–7.200 RPM; ein Schreib-/Lesekopf schwebt nanometerweit über der Oberfläche. Die Zugriffszeit setzt sich zusammen aus Seek Time (Kopf bewegen) + Rotational Latency (warten auf Sektor).
|
||||||
|
|
||||||
|
**SSD (Solid State Drive):** NAND-Flash-Zellen speichern Bits als elektrische Ladung. Kein mechanischer Zugriff → konstant schnelle Latenz. Aber: Zellen haben begrenzte Schreibzyklen (P/E Cycles).
|
||||||
|
|
||||||
|
| Aspekt | HDD | SATA SSD | NVMe SSD |
|
||||||
|
|--------|-----|----------|----------|
|
||||||
|
| Latenz | 5–10 ms | 0,1 ms | 0,02 ms |
|
||||||
|
| Seq. Lesen | 150 MB/s | 550 MB/s | 7.000 MB/s |
|
||||||
|
| IOPS (4K random) | 100 | 90.000 | 1.000.000 |
|
||||||
|
| TBW (1 TB Modell) | ∞ | 600 TBW | 600 TBW |
|
||||||
|
|
||||||
|
**Wear Leveling:** SSD-Controller verteilen Schreibvorgänge gleichmäßig, um einzelne Zellen nicht vorzeitig zu erschöpfen. TRIM informiert den Controller über gelöschte Blöcke.
|
||||||
|
|
||||||
|
**Praxis:** System-SSD für OS/Anwendungen (Geschwindigkeit), HDD für Medienarchiv (Kapazität/Preis). RAID schützt vor Einzelausfällen bei beiden.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: lead -->
|
||||||
|
|
||||||
|
# Dateisysteme
|
||||||
|
## Die Organisation der Daten
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Was macht ein Dateisystem?
|
||||||
|
|
||||||
|
**Aufgaben:**
|
||||||
|
- Dateien in Blöcke aufteilen
|
||||||
|
- Speicherort verwalten (Allokation)
|
||||||
|
- Verzeichnisstruktur pflegen
|
||||||
|
- Metadaten speichern (Name, Datum, Rechte)
|
||||||
|
- Integrität sichern (Journaling)
|
||||||
|
|
||||||
|
**Ohne Dateisystem:**
|
||||||
|
Nur eine Folge von Bytes ohne Struktur.
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Das Dateisystem ist die Abstraktionsschicht
|
||||||
|
zwischen Anwendungen und rohem Speicher.
|
||||||
|
|
||||||
|
Es entscheidet:
|
||||||
|
- Wie Dateien gefunden werden
|
||||||
|
- Wie freier Speicher verwaltet wird
|
||||||
|
- Was bei Abstürzen passiert
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# FAT32: Der Kompatibilitätskönig
|
||||||
|
|
||||||
|
**File Allocation Table, 32-bit (1996)**
|
||||||
|
|
||||||
|
**Vorteile:**
|
||||||
|
- Überall lesbar (Windows, Mac, Linux, Kameras, Fernseher...)
|
||||||
|
- Einfach, robust
|
||||||
|
|
||||||
|
**Nachteile:**
|
||||||
|
- Max. 4 GB pro Datei
|
||||||
|
- Max. 2 TB pro Volume
|
||||||
|
- Keine Berechtigungen
|
||||||
|
- Kein Journaling
|
||||||
|
|
||||||
|
**Ideal für:** USB-Sticks, SD-Karten (Kompatibilität)
|
||||||
|
|
||||||
|
<!--
|
||||||
|
4 GB Limit ist das Hauptproblem.
|
||||||
|
Ein 4K-Video oder ISO-Image passt oft nicht drauf.
|
||||||
|
|
||||||
|
Trotzdem: FAT32 ist der kleinste gemeinsame Nenner.
|
||||||
|
Wenn Kompatibilität wichtiger ist als Features → FAT32.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# exFAT: FAT32 ohne Limits
|
||||||
|
|
||||||
|
**Extended FAT (2006, Microsoft)**
|
||||||
|
|
||||||
|
**Vorteile:**
|
||||||
|
- Keine praktischen Dateigrößen-Limits
|
||||||
|
- Breite Unterstützung (seit 2019 auch Linux-Kernel)
|
||||||
|
- Für Flash-Speicher optimiert
|
||||||
|
|
||||||
|
**Nachteile:**
|
||||||
|
- Kein Journaling
|
||||||
|
- Weniger robust als NTFS/APFS/ext4
|
||||||
|
|
||||||
|
**Ideal für:** Große Dateien auf portablen Medien
|
||||||
|
|
||||||
|
<!--
|
||||||
|
exFAT ist der Nachfolger von FAT32 für portable Medien.
|
||||||
|
SD-Karten über 32 GB sind standardmäßig exFAT.
|
||||||
|
|
||||||
|
Microsoft hat 2019 die Patente freigegeben.
|
||||||
|
Seitdem native Linux-Unterstützung.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# NTFS: Windows-Standard
|
||||||
|
|
||||||
|
**New Technology File System (1993)**
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Journaling (Crash-Sicherheit)
|
||||||
|
- Dateirechte (ACLs)
|
||||||
|
- Kompression, Verschlüsselung
|
||||||
|
- Große Dateien und Volumes
|
||||||
|
|
||||||
|
**Nachteile:**
|
||||||
|
- Nur Windows schreibt nativ
|
||||||
|
- macOS: Nur lesen
|
||||||
|
- Linux: Über ntfs-3g (langsamer)
|
||||||
|
|
||||||
|
<!--
|
||||||
|
NTFS ist seit Windows NT der Standard.
|
||||||
|
Alle modernen Windows-Versionen nutzen es.
|
||||||
|
|
||||||
|
Für Windows-only-Systeme die beste Wahl.
|
||||||
|
Für portable Medien: Kompatibilitätsprobleme.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# APFS: Apple-Modern
|
||||||
|
|
||||||
|
**Apple File System (2017)**
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Snapshots (Zeitpunkt-Kopien)
|
||||||
|
- Copy-on-Write (CoW)
|
||||||
|
- Native Verschlüsselung
|
||||||
|
- Optimiert für SSDs
|
||||||
|
|
||||||
|
**Nachteile:**
|
||||||
|
- Nur Apple-Geräte
|
||||||
|
- Nicht abwärtskompatibel mit HFS+
|
||||||
|
|
||||||
|
<!--
|
||||||
|
APFS ersetzte HFS+ auf allen Apple-Geräten.
|
||||||
|
Snapshots ermöglichen Time Machine und APFS-Klone.
|
||||||
|
|
||||||
|
Copy-on-Write: Daten werden nicht überschrieben,
|
||||||
|
sondern neue Versionen werden geschrieben.
|
||||||
|
Gut für Integrität und Snapshots.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# ext4: Linux-Standard
|
||||||
|
|
||||||
|
**Fourth Extended File System (2008)**
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Journaling
|
||||||
|
- Extents (effiziente große Dateien)
|
||||||
|
- Online-Defragmentierung
|
||||||
|
- Bewährt und stabil
|
||||||
|
|
||||||
|
**Nachteile:**
|
||||||
|
- Windows/macOS können nicht nativ lesen
|
||||||
|
- Weniger Features als btrfs/ZFS
|
||||||
|
|
||||||
|
<!--
|
||||||
|
ext4 ist der Standard für Linux-Systeme.
|
||||||
|
Evolution: ext (1992) → ext2 → ext3 → ext4
|
||||||
|
|
||||||
|
Alternativen: btrfs (Snapshots, CoW), XFS, ZFS
|
||||||
|
Für Server oft XFS oder ZFS.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Dateisysteme: Übersicht
|
||||||
|
|
||||||
|
| FS | Max. Datei | Journaling | Ideal für |
|
||||||
|
|----|----------:|:----------:|-----------|
|
||||||
|
| FAT32 | 4 GB | ❌ | Kompatibilität |
|
||||||
|
| exFAT | 16 EB | ❌ | Große portable Dateien |
|
||||||
|
| NTFS | 16 EB | ✓ | Windows |
|
||||||
|
| APFS | 8 EB | ✓ | macOS, iOS |
|
||||||
|
| ext4 | 16 TB | ✓ | Linux |
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Die Wahl hängt vom Kontext ab.
|
||||||
|
|
||||||
|
Portable Medien: FAT32 oder exFAT
|
||||||
|
Interne Laufwerke: NTFS, APFS, ext4 je nach OS
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: lead -->
|
||||||
|
|
||||||
|
# Backup & Archivierung
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _header: '' -->
|
||||||
|
<!-- _footer: '' -->
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
<!--
|
||||||
|
Symbolbild: Kaputte Festplatte oder Ransomware
|
||||||
|
Das Worst-Case-Szenario
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Warum Backup?
|
||||||
|
|
||||||
|
**Realitäten:**
|
||||||
|
- HDDs haben 1-2% jährliche Ausfallrate
|
||||||
|
- SSDs können ohne Vorwarnung sterben
|
||||||
|
- Ransomware verschlüsselt Daten
|
||||||
|
- Versehentliches Löschen passiert
|
||||||
|
- Diebstahl, Brand, Wasserschaden
|
||||||
|
|
||||||
|
**Die Frage ist nicht ob, sondern wann.**
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Backblaze veröffentlicht jährliche HDD-Statistiken.
|
||||||
|
1-2% Ausfallrate klingt wenig, aber bei 100 Platten...
|
||||||
|
|
||||||
|
Pixar verlor fast "Toy Story 2" (1998).
|
||||||
|
Rettung: Eine Mitarbeiterin hatte ein Home-Backup.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: klausur -->
|
||||||
|
<!-- _header: '' -->
|
||||||
|
<!-- _footer: '' -->
|
||||||
|
<!-- _backgroundColor: #e3f2fd -->
|
||||||
|
|
||||||
|
# Die 3-2-1-Regel
|
||||||
|
|
||||||
|
**3** Kopien eurer Daten
|
||||||
|
(Original + 2 Backups)
|
||||||
|
|
||||||
|
**2** verschiedene Medientypen
|
||||||
|
(z.B. SSD + HDD, oder lokal + Cloud)
|
||||||
|
|
||||||
|
**1** Kopie an anderem Ort
|
||||||
|
(Offsite: Cloud, anderes Gebäude)
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Herkunft: Peter Krogh, "The DAM Book" (2005)
|
||||||
|
|
||||||
|
Warum 3 Kopien?
|
||||||
|
- Original kann kaputt gehen
|
||||||
|
- Backup 1 auch
|
||||||
|
- Backup 2 = Sicherheitspuffer
|
||||||
|
|
||||||
|
Warum 2 Medientypen?
|
||||||
|
- Gleiche Medien haben gleiche Schwachstellen
|
||||||
|
- Batch-Fehler bei HDDs derselben Charge
|
||||||
|
|
||||||
|
Warum 1 Offsite?
|
||||||
|
- Brand/Wasserschaden zerstört alles vor Ort
|
||||||
|
- Ransomware verschlüsselt angeschlossene Laufwerke
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: erklaerung -->
|
||||||
|
<!-- _header: '' -->
|
||||||
|
<!-- _footer: '' -->
|
||||||
|
|
||||||
|
# 3-2-1-Backup-Regel – Vertiefung
|
||||||
|
|
||||||
|
Peter Krogh formulierte die Regel 2005 in „The DAM Book" (Digital Asset Management). Sie schützt gegen unterschiedliche Verlustszenarien:
|
||||||
|
|
||||||
|
| Bedrohung | Schutz durch | Beispiel |
|
||||||
|
|-----------|--------------|----------|
|
||||||
|
| Hardware-Defekt | 3 Kopien | SSD stirbt → HDD-Backup vorhanden |
|
||||||
|
| Firmware-Bug/Ransomware | 2 Medientypen | Malware infiziert nur ein System |
|
||||||
|
| Feuer/Diebstahl/Flut | 1 Offsite | Haus brennt → Cloud-Backup sicher |
|
||||||
|
|
||||||
|
**Moderne Erweiterung 3-2-1-1-0:**
|
||||||
|
- **+1** Air-Gapped (offline, nicht verbunden)
|
||||||
|
- **+0** Verifizierte Backups (regelmäßig Restore testen)
|
||||||
|
|
||||||
|
**Ransomware-Problem:** Vernetzte Backups werden oft mitverschlüsselt. Air-Gapped-Medien (externe HDD im Safe, LTO-Band) bleiben sicher, weil sie physisch getrennt sind.
|
||||||
|
|
||||||
|
**Realitäts-Check:** Die meisten Datenverluste entstehen durch menschliche Fehler (versehentliches Löschen), nicht Hardware-Ausfälle. Versionierte Backups (Time Machine, Borg) schützen auch davor – die gelöschte Datei existiert noch in älteren Snapshots.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Backup-Arten
|
||||||
|
|
||||||
|
**Vollständig (Full):**
|
||||||
|
Kompletter Datenbestand jedes Mal.
|
||||||
|
Einfach, aber langsam und platzhungrig.
|
||||||
|
|
||||||
|
**Inkrementell:**
|
||||||
|
Nur Änderungen seit dem letzten Backup.
|
||||||
|
Schnell, aber Wiederherstellung komplex (Kette).
|
||||||
|
|
||||||
|
**Differenziell:**
|
||||||
|
Änderungen seit dem letzten Voll-Backup.
|
||||||
|
Mittelweg zwischen beiden.
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Typisches Schema:
|
||||||
|
- Sonntag: Voll-Backup
|
||||||
|
- Mo-Sa: Inkrementell oder Differenziell
|
||||||
|
|
||||||
|
Inkrementell: Schnellstes Backup, langsamste Wiederherstellung
|
||||||
|
Differenziell: Kompromiss
|
||||||
|
Voll: Langsamstes Backup, schnellste Wiederherstellung
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Backup in der Praxis
|
||||||
|
|
||||||
|
**macOS:** Time Machine
|
||||||
|
**Windows:** Veeam Agent (kostenlos), Windows Backup
|
||||||
|
**Linux:** rsync, Borg, Restic
|
||||||
|
**Cloud:** Backblaze, iCloud, Google Drive
|
||||||
|
|
||||||
|
**Wichtig:**
|
||||||
|
- Automatisieren (manuell wird vergessen)
|
||||||
|
- Regelmäßig testen (Backup nützt nichts, wenn Restore nicht funktioniert)
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Time Machine: Stündliche Snapshots, APFS-Integration
|
||||||
|
Veeam: Enterprise-Level, kostenlose Privatversion
|
||||||
|
rsync: Unix-Klassiker, extrem effizient
|
||||||
|
Borg: Deduplizierung + Verschlüsselung
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Langzeitarchivierung
|
||||||
|
|
||||||
|
**Probleme:**
|
||||||
|
- Bit Rot (Daten degradieren)
|
||||||
|
- Format-Obsoleszenz (wer öffnet .wpd?)
|
||||||
|
- Hardware-Obsoleszenz (Diskettenlaufwerk?)
|
||||||
|
|
||||||
|
**Lösungen:**
|
||||||
|
- Migration alle 5-10 Jahre auf neue Medien
|
||||||
|
- Offene Standards (PDF/A, TIFF, Plain Text)
|
||||||
|
- Redundante Kopien
|
||||||
|
|
||||||
|
<!--
|
||||||
|
WordPerfect dominierte die 1980er/90er.
|
||||||
|
Heute kann kaum jemand .wpd-Dateien öffnen.
|
||||||
|
|
||||||
|
Flash-Dateien (.swf) sind seit 2020 praktisch tot.
|
||||||
|
Millionen von Websites und Spielen verloren.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Archivmedien
|
||||||
|
|
||||||
|
**LTO-Tapes:**
|
||||||
|
- 18 TB pro Band (LTO-9)
|
||||||
|
- ~5€/TB
|
||||||
|
- 30 Jahre Haltbarkeit
|
||||||
|
- Für Cold Storage ideal
|
||||||
|
|
||||||
|
**M-DISC:**
|
||||||
|
- Spezielle DVD/Blu-ray
|
||||||
|
- 1.000+ Jahre Haltbarkeit (Herstellerangabe)
|
||||||
|
- Für kleine, wichtige Daten
|
||||||
|
|
||||||
|
**Cloud:**
|
||||||
|
- Glacier, Backblaze B2
|
||||||
|
- Günstig für Langzeit
|
||||||
|
|
||||||
|
<!--
|
||||||
|
LTO = Linear Tape-Open
|
||||||
|
AWS, Google, Netflix nutzen Tape für Archive.
|
||||||
|
|
||||||
|
M-DISC nutzt anorganische Schicht statt Dye.
|
||||||
|
Theoretisch sehr langlebig, praktisch ungetestet.
|
||||||
|
|
||||||
|
Cloud-Archive haben laufende Kosten.
|
||||||
|
Aber: Keine Hardware-Wartung.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: lead -->
|
||||||
|
|
||||||
|
# Schnittstellen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# USB: Die Universal-Schnittstelle
|
||||||
|
|
||||||
|
| Version | Jahr | Geschwindigkeit |
|
||||||
|
|---------|------|----------------:|
|
||||||
|
| USB 1.1 | 1998 | 12 Mbit/s |
|
||||||
|
| USB 2.0 | 2000 | 480 Mbit/s (~60 MB/s) |
|
||||||
|
| USB 3.0 | 2008 | 5 Gbit/s (~625 MB/s) |
|
||||||
|
| USB 3.1 Gen 2 | 2013 | 10 Gbit/s |
|
||||||
|
| USB 3.2 Gen 2×2 | 2017 | 20 Gbit/s |
|
||||||
|
| USB4 | 2019 | 40 Gbit/s |
|
||||||
|
|
||||||
|
<!--
|
||||||
|
USB = Universal Serial Bus
|
||||||
|
|
||||||
|
Die Namensgebung ist ein Chaos.
|
||||||
|
USB 3.0 wurde nachträglich zu "USB 3.1 Gen 1" umbenannt.
|
||||||
|
Dann zu "USB 3.2 Gen 1".
|
||||||
|
|
||||||
|
Die Industrie verwirrt absichtlich.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# USB-C: Der Stecker, nicht die Geschwindigkeit
|
||||||
|
|
||||||
|
**USB-C ist ein Steckertyp, kein Protokoll!**
|
||||||
|
|
||||||
|
Ein USB-C-Kabel kann sein:
|
||||||
|
- USB 2.0 (480 Mbit/s)
|
||||||
|
- USB 3.2 (bis 20 Gbit/s)
|
||||||
|
- USB4 (40 Gbit/s)
|
||||||
|
- Thunderbolt 3/4 (40 Gbit/s)
|
||||||
|
|
||||||
|
**Am Stecker nicht erkennbar.**
|
||||||
|
→ Kabel-Spezifikation prüfen!
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Das ist eine häufige Quelle für Frustration.
|
||||||
|
|
||||||
|
"Ich habe ein USB-C-Kabel, warum ist es so langsam?"
|
||||||
|
Weil es ein USB 2.0-Kabel mit USB-C-Stecker ist.
|
||||||
|
|
||||||
|
Gute Kabel sind teurer, aber es lohnt sich.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Thunderbolt
|
||||||
|
|
||||||
|
**Thunderbolt 3/4 (2015/2020):**
|
||||||
|
- 40 Gbit/s
|
||||||
|
- PCIe über Kabel (externe GPUs möglich)
|
||||||
|
- DisplayPort integriert
|
||||||
|
- USB-C-Stecker
|
||||||
|
|
||||||
|
**Vorteile:**
|
||||||
|
- Sehr schnell
|
||||||
|
- Vielseitig (Daten, Video, Strom)
|
||||||
|
|
||||||
|
**Nachteile:**
|
||||||
|
- Teure Kabel
|
||||||
|
- Nicht alle USB-C-Ports sind Thunderbolt
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Intel und Apple entwickelten Thunderbolt gemeinsam.
|
||||||
|
Lizenzfrei seit 2019.
|
||||||
|
|
||||||
|
Thunderbolt-Kabel haben oft ein Blitz-Symbol.
|
||||||
|
Aber nicht immer.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Video-Schnittstellen
|
||||||
|
|
||||||
|
| Schnittstelle | Max. Auflösung | Features |
|
||||||
|
|---------------|---------------:|----------|
|
||||||
|
| HDMI 2.0 | 4K/60Hz | ARC, CEC |
|
||||||
|
| HDMI 2.1 | 8K/60Hz, 4K/120Hz | VRR, eARC |
|
||||||
|
| DisplayPort 1.4 | 8K/60Hz | Daisy-Chain |
|
||||||
|
| DisplayPort 2.0 | 16K/60Hz | Mehr Bandbreite |
|
||||||
|
|
||||||
|
**HDMI:** Consumer-Geräte (TV, Konsolen)
|
||||||
|
**DisplayPort:** Computer, Monitore
|
||||||
|
|
||||||
|
<!--
|
||||||
|
HDMI hat Lizenzgebühren, DisplayPort nicht.
|
||||||
|
Deshalb ist DP bei Monitoren beliebter.
|
||||||
|
|
||||||
|
DisplayPort kann Daisy-Chaining:
|
||||||
|
Laptop → Monitor 1 → Monitor 2 über ein Kabel.
|
||||||
|
|
||||||
|
HDMI hat ARC (Audio Return Channel):
|
||||||
|
TV schickt Audio an Soundbar über HDMI.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Netzwerk
|
||||||
|
|
||||||
|
**Ethernet:**
|
||||||
|
| Standard | Geschwindigkeit |
|
||||||
|
|----------|----------------:|
|
||||||
|
| Fast Ethernet | 100 Mbit/s |
|
||||||
|
| Gigabit | 1 Gbit/s |
|
||||||
|
| 2.5 Gigabit | 2,5 Gbit/s |
|
||||||
|
| 10 Gigabit | 10 Gbit/s |
|
||||||
|
|
||||||
|
**WiFi:**
|
||||||
|
| Generation | Standard | Geschwindigkeit |
|
||||||
|
|------------|----------|----------------:|
|
||||||
|
| WiFi 5 | 802.11ac | ~1,3 Gbit/s |
|
||||||
|
| WiFi 6 | 802.11ax | ~9,6 Gbit/s |
|
||||||
|
| WiFi 7 | 802.11be | ~46 Gbit/s |
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Gigabit-Ethernet ist heute Standard.
|
||||||
|
2,5G und 10G verbreiten sich für NAS und Poweruser.
|
||||||
|
|
||||||
|
WiFi-Geschwindigkeiten sind theoretische Maxima.
|
||||||
|
Real: Bruchteil davon, abhängig von Entfernung und Störungen.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Welche Schnittstelle für was?
|
||||||
|
|
||||||
|
| Anwendung | Empfehlung |
|
||||||
|
|-----------|------------|
|
||||||
|
| Externe SSD | USB 3.2 Gen 2 oder Thunderbolt |
|
||||||
|
| USB-Stick | USB 3.0 reicht |
|
||||||
|
| Monitor | DisplayPort oder HDMI 2.0+ |
|
||||||
|
| NAS im Heimnetz | Gigabit Ethernet |
|
||||||
|
| Backup-Platte | USB 3.0 |
|
||||||
|
| Video-Editing extern | Thunderbolt |
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Die Schnittstelle muss zum Gerät passen.
|
||||||
|
|
||||||
|
Externe HDD über Thunderbolt?
|
||||||
|
Bringt nichts, die HDD ist der Flaschenhals.
|
||||||
|
|
||||||
|
NVMe-SSD über USB 2.0?
|
||||||
|
Verschwendung, USB ist der Flaschenhals.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: aufgabe -->
|
||||||
|
|
||||||
|
# Hands-On: Eigene Speicher analysieren
|
||||||
|
|
||||||
|
**Aufgabe (30 Min):**
|
||||||
|
|
||||||
|
1. Welche Laufwerke habt ihr? (SSD, HDD, extern)
|
||||||
|
2. Welches Dateisystem nutzt ihr?
|
||||||
|
3. Wie ist eure Backup-Situation?
|
||||||
|
4. Welche Schnittstellen nutzt ihr?
|
||||||
|
|
||||||
|
**Tools:**
|
||||||
|
- Windows: Datenträgerverwaltung
|
||||||
|
- macOS: Festplattendienstprogramm
|
||||||
|
- Linux: `lsblk`, `df -h`
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Ziel: Bewusstsein für eigene Infrastruktur.
|
||||||
|
|
||||||
|
Die meisten wissen nicht, welches Dateisystem
|
||||||
|
auf ihrem USB-Stick ist.
|
||||||
|
-->
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- _class: lead -->
|
||||||
|
|
||||||
|
# Fragen & Diskussion
|
||||||
|
|
||||||
|
**Kontakt:** lb-czechowski@hdm-stuttgart.de
|
||||||
|
**Folien:** [librete.ch/hdm/223015b](https://librete.ch/hdm/223015b/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Lizenz & Attribution
|
||||||
|
|
||||||
|
Diese Präsentation ist lizenziert unter **Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)**
|
||||||
|
|
||||||
|
- Erlaubt Teilen & Anpassen mit Namensnennung
|
||||||
|
- Adaptionen müssen unter gleicher Lizenz geteilt werden
|
||||||
|
|
||||||
|
Vollständige Lizenz: [creativecommons.org/licenses/by-sa/4.0/](https://creativecommons.org/licenses/by-sa/4.0/)
|
||||||
|
|
||||||
@@ -3,8 +3,8 @@ marp: true
|
|||||||
theme: gaia
|
theme: gaia
|
||||||
paginate: true
|
paginate: true
|
||||||
backgroundColor: #fff
|
backgroundColor: #fff
|
||||||
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege"
|
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege (223015b)"
|
||||||
footer: "Michael Czechowski – HdM Stuttgart – WS 2025/26"
|
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
|
||||||
title: Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
title: Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -40,18 +40,34 @@ pre code {
|
|||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
code {
|
code {
|
||||||
background: #1a1a2e;
|
background: #0f0f23;
|
||||||
color: #5fb3e4;
|
|
||||||
padding: 0.15em 0.4em;
|
padding: 0.15em 0.4em;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||||||
}
|
}
|
||||||
|
section code:not(.hljs) { color: #5fb3e4 !important; }
|
||||||
|
section code.hljs { color: #f8f8f8 !important; }
|
||||||
a {
|
a {
|
||||||
color: var(--color-highlight);
|
color: var(--color-highlight);
|
||||||
}
|
}
|
||||||
section.klausur {
|
section.klausur {
|
||||||
|
background: repeating-linear-gradient(
|
||||||
|
135deg,
|
||||||
|
#e3f2fd,
|
||||||
|
#e3f2fd 40px,
|
||||||
|
#fff 40px,
|
||||||
|
#fff 80px
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
@media print {
|
||||||
|
section.klausur {
|
||||||
|
background: #e3f2fd !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
section.aufgabe {
|
||||||
background: #e3f2fd !important;
|
background: #e3f2fd !important;
|
||||||
}
|
}
|
||||||
section.klausur footer {
|
section.aufgabe footer {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -69,7 +85,7 @@ section.klausur footer {
|
|||||||
Digital- und Medienwirtschaft
|
Digital- und Medienwirtschaft
|
||||||
Hochschule der Medien Stuttgart
|
Hochschule der Medien Stuttgart
|
||||||
|
|
||||||
**Wintersemester 2025/26**
|
**Sommersemester 2026**
|
||||||
|
|
||||||
[https://librete.ch/hdm/223015b/](https://librete.ch/hdm/223015b/)
|
[https://librete.ch/hdm/223015b/](https://librete.ch/hdm/223015b/)
|
||||||
|
|
||||||
@@ -84,7 +100,7 @@ Hochschule der Medien Stuttgart
|
|||||||
|
|
||||||
<!-- _class: lead -->
|
<!-- _class: lead -->
|
||||||
|
|
||||||
# Termin 4 – 30.01.2026
|
# Kapitel 4 – 30.01.2026
|
||||||
## Distribution, APIs & Zukunft
|
## Distribution, APIs & Zukunft
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -144,7 +160,7 @@ AWS Snowmobile: 45-Fuß-Container auf LKW
|
|||||||
|
|
||||||
**Prozess:**
|
**Prozess:**
|
||||||
1. AWS schickt verschlüsseltes Gerät
|
1. AWS schickt verschlüsseltes Gerät
|
||||||
2. Kunde kopiert Daten lokal (schnell!)
|
2. KundIn kopiert Daten lokal (schnell!)
|
||||||
3. Gerät zurück an AWS
|
3. Gerät zurück an AWS
|
||||||
4. AWS lädt in S3 hoch
|
4. AWS lädt in S3 hoch
|
||||||
|
|
||||||
@@ -204,7 +220,7 @@ Server unter Last (symbolisch)
|
|||||||
**Klassisches Modell:** Ein Server, viele Clients
|
**Klassisches Modell:** Ein Server, viele Clients
|
||||||
|
|
||||||
**Problem:**
|
**Problem:**
|
||||||
1 Million User wollen 1 GB-Datei
|
1 Million Nutzende wollen 1 GB-Datei
|
||||||
→ Server braucht **1 PB Bandbreite!**
|
→ Server braucht **1 PB Bandbreite!**
|
||||||
→ Server überlastet → **"Hug of Death"**
|
→ Server überlastet → **"Hug of Death"**
|
||||||
|
|
||||||
@@ -236,7 +252,7 @@ Globale Verteilung
|
|||||||
**Funktionsweise:**
|
**Funktionsweise:**
|
||||||
1. **Origin Server** (Hauptquelle)
|
1. **Origin Server** (Hauptquelle)
|
||||||
2. **Edge Servers** (geografisch verteilt)
|
2. **Edge Servers** (geografisch verteilt)
|
||||||
3. User → nächster Edge Server
|
3. Nutzende → nächster Edge Server
|
||||||
4. Erste Anfrage: Edge holt von Origin, cached
|
4. Erste Anfrage: Edge holt von Origin, cached
|
||||||
5. Weitere Anfragen: Direkt vom Edge (schnell!)
|
5. Weitere Anfragen: Direkt vom Edge (schnell!)
|
||||||
|
|
||||||
@@ -261,7 +277,7 @@ Große CDN-Anbieter: Cloudflare, Akamai, Amazon CloudFront, Fastly
|
|||||||
- Lange Cache-Zeit (TTL: Tage/Wochen)
|
- Lange Cache-Zeit (TTL: Tage/Wochen)
|
||||||
|
|
||||||
**Dynamic Content:**
|
**Dynamic Content:**
|
||||||
- User-spezifisch (Profil)
|
- Nutzungs-spezifisch (Profil)
|
||||||
- Kurze TTL oder nicht cachebar
|
- Kurze TTL oder nicht cachebar
|
||||||
|
|
||||||
**Cache Invalidation:**
|
**Cache Invalidation:**
|
||||||
@@ -333,14 +349,14 @@ Dezentral, jeder ist Client & Server
|
|||||||
- IPFS (InterPlanetary File System)
|
- IPFS (InterPlanetary File System)
|
||||||
- Blockchain (Bitcoin, Ethereum)
|
- Blockchain (Bitcoin, Ethereum)
|
||||||
|
|
||||||
**Vorteil:** Skalierbar (mehr User = mehr Bandbreite!)
|
**Vorteil:** Skalierbar (mehr Nutzende = mehr Bandbreite!)
|
||||||
|
|
||||||
**Nachteil:** Langsam bei wenigen Peers, oft für Piraterie missbraucht
|
**Nachteil:** Langsam bei wenigen Peers, oft für Piraterie missbraucht
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
P2P vs. Client-Server: Kein zentraler Server
|
P2P vs. Client-Server: Kein zentraler Server
|
||||||
Last verteilt sich auf alle Teilnehmer
|
Last verteilt sich auf alle Teilnehmenden
|
||||||
Je mehr User, desto schneller (umgekehrt zu Client-Server!)
|
Je mehr Nutzende, desto schneller (umgekehrt zu Client-Server!)
|
||||||
Zensur-resistent: Kein Single Point of Failure
|
Zensur-resistent: Kein Single Point of Failure
|
||||||
Rechtliche Grauzone: Technologie neutral, aber oft illegal genutzt
|
Rechtliche Grauzone: Technologie neutral, aber oft illegal genutzt
|
||||||
-->
|
-->
|
||||||
@@ -1007,8 +1023,8 @@ Privacy-Albtraum
|
|||||||
|
|
||||||
**Beispiele:**
|
**Beispiele:**
|
||||||
- **Foto:** Kamera, Datum, GPS, Belichtung
|
- **Foto:** Kamera, Datum, GPS, Belichtung
|
||||||
- **MP3:** Künstler, Album, Jahr, Genre, Cover
|
- **MP3:** KünstlerInnen, Album, Jahr, Genre, Cover
|
||||||
- **PDF:** Autor, Datum, Software
|
- **PDF:** AutorIn, Datum, Software
|
||||||
- **E-Mail:** Absender, Empfänger, Zeitstempel
|
- **E-Mail:** Absender, Empfänger, Zeitstempel
|
||||||
|
|
||||||
**Warum wichtig?**
|
**Warum wichtig?**
|
||||||
@@ -1164,7 +1180,7 @@ Wikipedia für Musik-Metadaten
|
|||||||
**Idee:** Wikipedia für Musik-Metadaten
|
**Idee:** Wikipedia für Musik-Metadaten
|
||||||
|
|
||||||
**Community-gepflegt:**
|
**Community-gepflegt:**
|
||||||
- Künstler, Alben, Tracks
|
- KünstlerInnen, Alben, Tracks
|
||||||
- Relationships (Band-Mitglieder, Label...)
|
- Relationships (Band-Mitglieder, Label...)
|
||||||
- Releases (verschiedene Editionen, Länder)
|
- Releases (verschiedene Editionen, Länder)
|
||||||
|
|
||||||
@@ -1223,7 +1239,7 @@ Versteckte Informationen sichtbar
|
|||||||
**PDF-Metadaten (XMP):**
|
**PDF-Metadaten (XMP):**
|
||||||
|
|
||||||
**Gespeichert:**
|
**Gespeichert:**
|
||||||
- Titel, Autor, Betreff, Keywords
|
- Titel, AutorIn, Betreff, Keywords
|
||||||
- Erstellungsdatum, Änderungsdatum
|
- Erstellungsdatum, Änderungsdatum
|
||||||
- Software, **Company** (aus Office-Lizenz!)
|
- Software, **Company** (aus Office-Lizenz!)
|
||||||
|
|
||||||
@@ -1252,7 +1268,7 @@ Dangerzone: FOSS-Tool (Freedom of Press Foundation)
|
|||||||
**Offene Formate:**
|
**Offene Formate:**
|
||||||
✓ Spezifikation öffentlich
|
✓ Spezifikation öffentlich
|
||||||
✓ Keine Lizenzgebühren
|
✓ Keine Lizenzgebühren
|
||||||
✓ Viele Programme unterstützen
|
✓ Viele Programme unterstützen1
|
||||||
**Beispiele:** PNG, OGG, MKV, Markdown, SVG
|
**Beispiele:** PNG, OGG, MKV, Markdown, SVG
|
||||||
|
|
||||||
**Proprietäre Formate:**
|
**Proprietäre Formate:**
|
||||||
@@ -1267,7 +1283,7 @@ Lock-in: "Gefangene Daten" (nur in Software X öffenbar)
|
|||||||
Firma geht pleite → Format stirbt (WordPerfect-Beispiel)
|
Firma geht pleite → Format stirbt (WordPerfect-Beispiel)
|
||||||
Offene Standards: Überlebensfähiger (Community kann implementieren)
|
Offene Standards: Überlebensfähiger (Community kann implementieren)
|
||||||
-->
|
-->
|
||||||
|
111
|
||||||
---
|
---
|
||||||
|
|
||||||
# Vendor Lock-in: Beispiele
|
# Vendor Lock-in: Beispiele
|
||||||
@@ -1584,7 +1600,7 @@ QKD: Abhör-sichere Kommunikation (Quantenmechanik garantiert)
|
|||||||
|
|
||||||
**Filecoin (2017):**
|
**Filecoin (2017):**
|
||||||
- Blockchain-basiert
|
- Blockchain-basiert
|
||||||
- User vermieten Festplatten-Platz
|
- Nutzende vermieten Festplatten-Platz
|
||||||
- Bezahlung in FIL (Kryptowährung)
|
- Bezahlung in FIL (Kryptowährung)
|
||||||
|
|
||||||
**Arweave (2018):**
|
**Arweave (2018):**
|
||||||
@@ -1622,7 +1638,7 @@ Legitime Use-Cases: NFT-Storage, Zensur-resistente Archivierung
|
|||||||
- 5G + Edge Computing nötig
|
- 5G + Edge Computing nötig
|
||||||
|
|
||||||
**Cloud Gaming:**
|
**Cloud Gaming:**
|
||||||
- Spiel im Rechenzentrum, Stream zu User
|
- Spiel im Rechenzentrum, Stream zu Nutzenden
|
||||||
- Input-Lag = Todfeind (<50ms)
|
- Input-Lag = Todfeind (<50ms)
|
||||||
|
|
||||||
**Problem:** Physik (Lichtgeschwindigkeit!)
|
**Problem:** Physik (Lichtgeschwindigkeit!)
|
||||||
@@ -1631,7 +1647,7 @@ Legitime Use-Cases: NFT-Storage, Zensur-resistente Archivierung
|
|||||||
8K: YouTube unterstützt, aber wer hat 8K-Monitor?
|
8K: YouTube unterstützt, aber wer hat 8K-Monitor?
|
||||||
VR: Meta Quest, Apple Vision Pro
|
VR: Meta Quest, Apple Vision Pro
|
||||||
Latenz: Lichtgeschwindigkeit ~300.000 km/s, aber Routing + Processing addiert sich
|
Latenz: Lichtgeschwindigkeit ~300.000 km/s, aber Routing + Processing addiert sich
|
||||||
Edge Computing: Server näher an User (5G-Masten)
|
Edge Computing: Server näher an Nutzende (5G-Masten)
|
||||||
Cloud Gaming: Stadia gescheitert (2023 †), GeForce Now, Xbox Cloud
|
Cloud Gaming: Stadia gescheitert (2023 †), GeForce Now, Xbox Cloud
|
||||||
Input-Lag: Fiber ~5ms/1000km, aber Server-Processing + Encoding + Decoding
|
Input-Lag: Fiber ~5ms/1000km, aber Server-Processing + Encoding + Decoding
|
||||||
-->
|
-->
|
||||||
@@ -1839,7 +1855,7 @@ Evaluation: Feedback ernst nehmen, Kurs verbessern
|
|||||||
|
|
||||||
# Fragen & Diskussion
|
# Fragen & Diskussion
|
||||||
|
|
||||||
**Kontakt:** mail@librete.ch
|
**Kontakt:** lb-czechowski@hdm-stuttgart.de
|
||||||
**Folien:** Online verfügbar unter https://librete.ch/hdm/223015b
|
**Folien:** Online verfügbar unter https://librete.ch/hdm/223015b
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -3,8 +3,8 @@ marp: true
|
|||||||
theme: gaia
|
theme: gaia
|
||||||
paginate: true
|
paginate: true
|
||||||
backgroundColor: #fff
|
backgroundColor: #fff
|
||||||
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege"
|
header: "Dateiformate, Schnittstellen, Speichermedien & Distributionswege (223015b)"
|
||||||
footer: "Michael Czechowski – HdM Stuttgart – WS 2025/26"
|
footer: "Michael Czechowski – HdM Stuttgart – SoSe 2026"
|
||||||
title: Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
title: Dateiformate, Schnittstellen, Speichermedien & Distributionswege
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -40,18 +40,34 @@ pre code {
|
|||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
code {
|
code {
|
||||||
background: #1a1a2e;
|
background: #0f0f23;
|
||||||
color: #5fb3e4;
|
|
||||||
padding: 0.15em 0.4em;
|
padding: 0.15em 0.4em;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||||||
}
|
}
|
||||||
|
section code:not(.hljs) { color: #5fb3e4 !important; }
|
||||||
|
section code.hljs { color: #f8f8f8 !important; }
|
||||||
a {
|
a {
|
||||||
color: var(--color-highlight);
|
color: var(--color-highlight);
|
||||||
}
|
}
|
||||||
section.klausur {
|
section.klausur {
|
||||||
|
background: repeating-linear-gradient(
|
||||||
|
135deg,
|
||||||
|
#e3f2fd,
|
||||||
|
#e3f2fd 40px,
|
||||||
|
#fff 40px,
|
||||||
|
#fff 80px
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
@media print {
|
||||||
|
section.klausur {
|
||||||
|
background: #e3f2fd !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
section.aufgabe {
|
||||||
background: #e3f2fd !important;
|
background: #e3f2fd !important;
|
||||||
}
|
}
|
||||||
section.klausur footer {
|
section.aufgabe footer {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -69,7 +85,7 @@ section.klausur footer {
|
|||||||
Digital- und Medienwirtschaft
|
Digital- und Medienwirtschaft
|
||||||
Hochschule der Medien Stuttgart
|
Hochschule der Medien Stuttgart
|
||||||
|
|
||||||
**Wintersemester 2025/26**
|
**Sommersemester 2026**
|
||||||
|
|
||||||
[https://librete.ch/hdm/223015b/](https://librete.ch/hdm/223015b/)
|
[https://librete.ch/hdm/223015b/](https://librete.ch/hdm/223015b/)
|
||||||
|
|
||||||
@@ -84,7 +100,7 @@ Hochschule der Medien Stuttgart
|
|||||||
|
|
||||||
<!-- _class: lead -->
|
<!-- _class: lead -->
|
||||||
|
|
||||||
# Termin 5 – TBA
|
# Kapitel 5 – TBA
|
||||||
## Vertiefung & Offene Fragen
|
## Vertiefung & Offene Fragen
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -110,7 +126,7 @@ Themen nach Interesse der Studierenden
|
|||||||
|
|
||||||
# Fragen & Diskussion
|
# Fragen & Diskussion
|
||||||
|
|
||||||
**Kontakt:** mail@librete.ch
|
**Kontakt:** lb-czechowski@hdm-stuttgart.de
|
||||||
**Folien:** Online verfügbar unter https://librete.ch/hdm/223015b
|
**Folien:** Online verfügbar unter https://librete.ch/hdm/223015b
|
||||||
|
|
||||||
---
|
---
|
||||||
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 425 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 241 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 484 KiB |
|
After Width: | Height: | Size: 249 KiB |
|
After Width: | Height: | Size: 388 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 32 KiB |
@@ -0,0 +1,311 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>ASCII-Tabelle</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--hl: #1e5f8a;
|
||||||
|
--dark: #1a1a2e;
|
||||||
|
--muted: #6b7280;
|
||||||
|
--border: #cbd5e1;
|
||||||
|
--bg-soft: #f8fafc;
|
||||||
|
--c-ctrl: #e5e7eb; /* control */
|
||||||
|
--c-ctrl-text: #4b5563;
|
||||||
|
--c-space: #fef3c7; /* space */
|
||||||
|
--c-punct: #ddd6fe; /* punctuation */
|
||||||
|
--c-digit: #bfdbfe; /* digits */
|
||||||
|
--c-upper: #bbf7d0; /* uppercase */
|
||||||
|
--c-lower: #fed7aa; /* lowercase */
|
||||||
|
--c-del: #fecaca; /* DEL */
|
||||||
|
}
|
||||||
|
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||||
|
body { padding: 18px 24px; }
|
||||||
|
h1 { text-align: center; margin: 0 0 2px; font-size: 1.5rem; }
|
||||||
|
.sub { text-align: center; color: var(--muted); margin-bottom: 14px; font-size: 0.9rem; }
|
||||||
|
.sub strong { color: var(--dark); }
|
||||||
|
|
||||||
|
.table-wrap { display: flex; justify-content: center; }
|
||||||
|
|
||||||
|
table.ascii {
|
||||||
|
border-collapse: separate;
|
||||||
|
border-spacing: 3px;
|
||||||
|
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
||||||
|
}
|
||||||
|
table.ascii th, table.ascii td {
|
||||||
|
width: 68px;
|
||||||
|
height: 60px;
|
||||||
|
padding: 0;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
table.ascii th {
|
||||||
|
background: var(--dark); color: #fff;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
font-weight: 700;
|
||||||
|
width: 56px;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
table.ascii th.row { width: 64px; }
|
||||||
|
table.ascii th .b { display: block; font-size: 0.68rem; opacity: 0.7; font-weight: 400; margin-top: 2px; letter-spacing: 0.04em; }
|
||||||
|
|
||||||
|
table.ascii td {
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
td .hex { position: absolute; top: 3px; left: 5px; font-size: 0.62rem; color: var(--muted); font-weight: 700; }
|
||||||
|
td .dec { position: absolute; bottom: 3px; right: 5px; font-size: 0.62rem; color: var(--muted); font-weight: 400; }
|
||||||
|
td .ch { font-size: 1.45rem; font-weight: 700; line-height: 1; }
|
||||||
|
td.ctrl .ch { font-size: 0.82rem; font-weight: 700; }
|
||||||
|
td.ctrl .ch small { display: block; font-size: 0.6rem; font-weight: 400; color: var(--muted); margin-top: 2px; letter-spacing: 0; }
|
||||||
|
|
||||||
|
td.ctrl { background: var(--c-ctrl); color: var(--c-ctrl-text); }
|
||||||
|
td.space { background: var(--c-space); }
|
||||||
|
td.punct { background: var(--c-punct); }
|
||||||
|
td.digit { background: var(--c-digit); }
|
||||||
|
td.upper { background: var(--c-upper); }
|
||||||
|
td.lower { background: var(--c-lower); }
|
||||||
|
td.del { background: var(--c-del); color: var(--c-ctrl-text); }
|
||||||
|
|
||||||
|
.legend {
|
||||||
|
margin: 14px auto 0;
|
||||||
|
display: flex; gap: 14px; justify-content: center; flex-wrap: wrap;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
.legend .item { display: flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 4px; border: 1px solid var(--border); }
|
||||||
|
.legend .swatch { width: 14px; height: 14px; border-radius: 3px; border: 1px solid var(--border); }
|
||||||
|
.legend .swatch.ctrl { background: var(--c-ctrl); }
|
||||||
|
.legend .swatch.space { background: var(--c-space); }
|
||||||
|
.legend .swatch.punct { background: var(--c-punct); }
|
||||||
|
.legend .swatch.digit { background: var(--c-digit); }
|
||||||
|
.legend .swatch.upper { background: var(--c-upper); }
|
||||||
|
.legend .swatch.lower { background: var(--c-lower); }
|
||||||
|
.legend .swatch.del { background: var(--c-del); }
|
||||||
|
|
||||||
|
.meta-row {
|
||||||
|
margin-top: 10px;
|
||||||
|
display: flex; gap: 18px; justify-content: center;
|
||||||
|
font-size: 0.85rem; color: var(--muted);
|
||||||
|
}
|
||||||
|
.meta-row strong { color: var(--dark); }
|
||||||
|
.meta-row code { background: var(--dark); color: #f8f8f8; padding: 1px 6px; border-radius: 3px; font-family: ui-monospace, monospace; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>ASCII-Tabelle (1963) · 7 Bit · 128 Zeichen</h1>
|
||||||
|
<div class="sub">Spalte = High-Nibble (Hex 0–7) · Zeile = Low-Nibble (Hex 0–F) · <strong>Hex</strong> oben, <strong>Dezimal</strong> unten</div>
|
||||||
|
|
||||||
|
<div class="table-wrap">
|
||||||
|
<table class="ascii">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="row">↓ Low<br>→ High</th>
|
||||||
|
<th>0<span class="b">0000</span></th>
|
||||||
|
<th>1<span class="b">0001</span></th>
|
||||||
|
<th>2<span class="b">0010</span></th>
|
||||||
|
<th>3<span class="b">0011</span></th>
|
||||||
|
<th>4<span class="b">0100</span></th>
|
||||||
|
<th>5<span class="b">0101</span></th>
|
||||||
|
<th>6<span class="b">0110</span></th>
|
||||||
|
<th>7<span class="b">0111</span></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th class="row">0<span class="b">0000</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">00</span><span class="ch">NUL<small>null</small></span><span class="dec">0</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">10</span><span class="ch">DLE<small>data link esc</small></span><span class="dec">16</span></td>
|
||||||
|
<td class="space"><span class="hex">20</span><span class="ch">SP<small>space</small></span><span class="dec">32</span></td>
|
||||||
|
<td class="digit"><span class="hex">30</span><span class="ch">0</span><span class="dec">48</span></td>
|
||||||
|
<td class="punct"><span class="hex">40</span><span class="ch">@</span><span class="dec">64</span></td>
|
||||||
|
<td class="upper"><span class="hex">50</span><span class="ch">P</span><span class="dec">80</span></td>
|
||||||
|
<td class="punct"><span class="hex">60</span><span class="ch">`</span><span class="dec">96</span></td>
|
||||||
|
<td class="lower"><span class="hex">70</span><span class="ch">p</span><span class="dec">112</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">1<span class="b">0001</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">01</span><span class="ch">SOH<small>start hdr</small></span><span class="dec">1</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">11</span><span class="ch">DC1<small>XON</small></span><span class="dec">17</span></td>
|
||||||
|
<td class="punct"><span class="hex">21</span><span class="ch">!</span><span class="dec">33</span></td>
|
||||||
|
<td class="digit"><span class="hex">31</span><span class="ch">1</span><span class="dec">49</span></td>
|
||||||
|
<td class="upper"><span class="hex">41</span><span class="ch">A</span><span class="dec">65</span></td>
|
||||||
|
<td class="upper"><span class="hex">51</span><span class="ch">Q</span><span class="dec">81</span></td>
|
||||||
|
<td class="lower"><span class="hex">61</span><span class="ch">a</span><span class="dec">97</span></td>
|
||||||
|
<td class="lower"><span class="hex">71</span><span class="ch">q</span><span class="dec">113</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">2<span class="b">0010</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">02</span><span class="ch">STX<small>start txt</small></span><span class="dec">2</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">12</span><span class="ch">DC2</span><span class="dec">18</span></td>
|
||||||
|
<td class="punct"><span class="hex">22</span><span class="ch">"</span><span class="dec">34</span></td>
|
||||||
|
<td class="digit"><span class="hex">32</span><span class="ch">2</span><span class="dec">50</span></td>
|
||||||
|
<td class="upper"><span class="hex">42</span><span class="ch">B</span><span class="dec">66</span></td>
|
||||||
|
<td class="upper"><span class="hex">52</span><span class="ch">R</span><span class="dec">82</span></td>
|
||||||
|
<td class="lower"><span class="hex">62</span><span class="ch">b</span><span class="dec">98</span></td>
|
||||||
|
<td class="lower"><span class="hex">72</span><span class="ch">r</span><span class="dec">114</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">3<span class="b">0011</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">03</span><span class="ch">ETX<small>end txt</small></span><span class="dec">3</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">13</span><span class="ch">DC3<small>XOFF</small></span><span class="dec">19</span></td>
|
||||||
|
<td class="punct"><span class="hex">23</span><span class="ch">#</span><span class="dec">35</span></td>
|
||||||
|
<td class="digit"><span class="hex">33</span><span class="ch">3</span><span class="dec">51</span></td>
|
||||||
|
<td class="upper"><span class="hex">43</span><span class="ch">C</span><span class="dec">67</span></td>
|
||||||
|
<td class="upper"><span class="hex">53</span><span class="ch">S</span><span class="dec">83</span></td>
|
||||||
|
<td class="lower"><span class="hex">63</span><span class="ch">c</span><span class="dec">99</span></td>
|
||||||
|
<td class="lower"><span class="hex">73</span><span class="ch">s</span><span class="dec">115</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">4<span class="b">0100</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">04</span><span class="ch">EOT<small>end trans</small></span><span class="dec">4</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">14</span><span class="ch">DC4</span><span class="dec">20</span></td>
|
||||||
|
<td class="punct"><span class="hex">24</span><span class="ch">$</span><span class="dec">36</span></td>
|
||||||
|
<td class="digit"><span class="hex">34</span><span class="ch">4</span><span class="dec">52</span></td>
|
||||||
|
<td class="upper"><span class="hex">44</span><span class="ch">D</span><span class="dec">68</span></td>
|
||||||
|
<td class="upper"><span class="hex">54</span><span class="ch">T</span><span class="dec">84</span></td>
|
||||||
|
<td class="lower"><span class="hex">64</span><span class="ch">d</span><span class="dec">100</span></td>
|
||||||
|
<td class="lower"><span class="hex">74</span><span class="ch">t</span><span class="dec">116</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">5<span class="b">0101</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">05</span><span class="ch">ENQ<small>enquiry</small></span><span class="dec">5</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">15</span><span class="ch">NAK</span><span class="dec">21</span></td>
|
||||||
|
<td class="punct"><span class="hex">25</span><span class="ch">%</span><span class="dec">37</span></td>
|
||||||
|
<td class="digit"><span class="hex">35</span><span class="ch">5</span><span class="dec">53</span></td>
|
||||||
|
<td class="upper"><span class="hex">45</span><span class="ch">E</span><span class="dec">69</span></td>
|
||||||
|
<td class="upper"><span class="hex">55</span><span class="ch">U</span><span class="dec">85</span></td>
|
||||||
|
<td class="lower"><span class="hex">65</span><span class="ch">e</span><span class="dec">101</span></td>
|
||||||
|
<td class="lower"><span class="hex">75</span><span class="ch">u</span><span class="dec">117</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">6<span class="b">0110</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">06</span><span class="ch">ACK<small>ack</small></span><span class="dec">6</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">16</span><span class="ch">SYN</span><span class="dec">22</span></td>
|
||||||
|
<td class="punct"><span class="hex">26</span><span class="ch">&</span><span class="dec">38</span></td>
|
||||||
|
<td class="digit"><span class="hex">36</span><span class="ch">6</span><span class="dec">54</span></td>
|
||||||
|
<td class="upper"><span class="hex">46</span><span class="ch">F</span><span class="dec">70</span></td>
|
||||||
|
<td class="upper"><span class="hex">56</span><span class="ch">V</span><span class="dec">86</span></td>
|
||||||
|
<td class="lower"><span class="hex">66</span><span class="ch">f</span><span class="dec">102</span></td>
|
||||||
|
<td class="lower"><span class="hex">76</span><span class="ch">v</span><span class="dec">118</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">7<span class="b">0111</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">07</span><span class="ch">BEL<small>bell 🔔</small></span><span class="dec">7</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">17</span><span class="ch">ETB</span><span class="dec">23</span></td>
|
||||||
|
<td class="punct"><span class="hex">27</span><span class="ch">'</span><span class="dec">39</span></td>
|
||||||
|
<td class="digit"><span class="hex">37</span><span class="ch">7</span><span class="dec">55</span></td>
|
||||||
|
<td class="upper"><span class="hex">47</span><span class="ch">G</span><span class="dec">71</span></td>
|
||||||
|
<td class="upper"><span class="hex">57</span><span class="ch">W</span><span class="dec">87</span></td>
|
||||||
|
<td class="lower"><span class="hex">67</span><span class="ch">g</span><span class="dec">103</span></td>
|
||||||
|
<td class="lower"><span class="hex">77</span><span class="ch">w</span><span class="dec">119</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">8<span class="b">1000</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">08</span><span class="ch">BS<small>backspace</small></span><span class="dec">8</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">18</span><span class="ch">CAN</span><span class="dec">24</span></td>
|
||||||
|
<td class="punct"><span class="hex">28</span><span class="ch">(</span><span class="dec">40</span></td>
|
||||||
|
<td class="digit"><span class="hex">38</span><span class="ch">8</span><span class="dec">56</span></td>
|
||||||
|
<td class="upper"><span class="hex">48</span><span class="ch">H</span><span class="dec">72</span></td>
|
||||||
|
<td class="upper"><span class="hex">58</span><span class="ch">X</span><span class="dec">88</span></td>
|
||||||
|
<td class="lower"><span class="hex">68</span><span class="ch">h</span><span class="dec">104</span></td>
|
||||||
|
<td class="lower"><span class="hex">78</span><span class="ch">x</span><span class="dec">120</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">9<span class="b">1001</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">09</span><span class="ch">HT<small>tab ⇥</small></span><span class="dec">9</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">19</span><span class="ch">EM</span><span class="dec">25</span></td>
|
||||||
|
<td class="punct"><span class="hex">29</span><span class="ch">)</span><span class="dec">41</span></td>
|
||||||
|
<td class="digit"><span class="hex">39</span><span class="ch">9</span><span class="dec">57</span></td>
|
||||||
|
<td class="upper"><span class="hex">49</span><span class="ch">I</span><span class="dec">73</span></td>
|
||||||
|
<td class="upper"><span class="hex">59</span><span class="ch">Y</span><span class="dec">89</span></td>
|
||||||
|
<td class="lower"><span class="hex">69</span><span class="ch">i</span><span class="dec">105</span></td>
|
||||||
|
<td class="lower"><span class="hex">79</span><span class="ch">y</span><span class="dec">121</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">A<span class="b">1010</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">0A</span><span class="ch">LF<small>↵ newline</small></span><span class="dec">10</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">1A</span><span class="ch">SUB<small>EOF DOS</small></span><span class="dec">26</span></td>
|
||||||
|
<td class="punct"><span class="hex">2A</span><span class="ch">*</span><span class="dec">42</span></td>
|
||||||
|
<td class="punct"><span class="hex">3A</span><span class="ch">:</span><span class="dec">58</span></td>
|
||||||
|
<td class="upper"><span class="hex">4A</span><span class="ch">J</span><span class="dec">74</span></td>
|
||||||
|
<td class="upper"><span class="hex">5A</span><span class="ch">Z</span><span class="dec">90</span></td>
|
||||||
|
<td class="lower"><span class="hex">6A</span><span class="ch">j</span><span class="dec">106</span></td>
|
||||||
|
<td class="lower"><span class="hex">7A</span><span class="ch">z</span><span class="dec">122</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">B<span class="b">1011</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">0B</span><span class="ch">VT</span><span class="dec">11</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">1B</span><span class="ch">ESC<small>escape</small></span><span class="dec">27</span></td>
|
||||||
|
<td class="punct"><span class="hex">2B</span><span class="ch">+</span><span class="dec">43</span></td>
|
||||||
|
<td class="punct"><span class="hex">3B</span><span class="ch">;</span><span class="dec">59</span></td>
|
||||||
|
<td class="upper"><span class="hex">4B</span><span class="ch">K</span><span class="dec">75</span></td>
|
||||||
|
<td class="punct"><span class="hex">5B</span><span class="ch">[</span><span class="dec">91</span></td>
|
||||||
|
<td class="lower"><span class="hex">6B</span><span class="ch">k</span><span class="dec">107</span></td>
|
||||||
|
<td class="punct"><span class="hex">7B</span><span class="ch">{</span><span class="dec">123</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">C<span class="b">1100</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">0C</span><span class="ch">FF<small>form feed</small></span><span class="dec">12</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">1C</span><span class="ch">FS</span><span class="dec">28</span></td>
|
||||||
|
<td class="punct"><span class="hex">2C</span><span class="ch">,</span><span class="dec">44</span></td>
|
||||||
|
<td class="punct"><span class="hex">3C</span><span class="ch"><</span><span class="dec">60</span></td>
|
||||||
|
<td class="upper"><span class="hex">4C</span><span class="ch">L</span><span class="dec">76</span></td>
|
||||||
|
<td class="punct"><span class="hex">5C</span><span class="ch">\</span><span class="dec">92</span></td>
|
||||||
|
<td class="lower"><span class="hex">6C</span><span class="ch">l</span><span class="dec">108</span></td>
|
||||||
|
<td class="punct"><span class="hex">7C</span><span class="ch">|</span><span class="dec">124</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">D<span class="b">1101</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">0D</span><span class="ch">CR<small>carriage</small></span><span class="dec">13</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">1D</span><span class="ch">GS</span><span class="dec">29</span></td>
|
||||||
|
<td class="punct"><span class="hex">2D</span><span class="ch">-</span><span class="dec">45</span></td>
|
||||||
|
<td class="punct"><span class="hex">3D</span><span class="ch">=</span><span class="dec">61</span></td>
|
||||||
|
<td class="upper"><span class="hex">4D</span><span class="ch">M</span><span class="dec">77</span></td>
|
||||||
|
<td class="punct"><span class="hex">5D</span><span class="ch">]</span><span class="dec">93</span></td>
|
||||||
|
<td class="lower"><span class="hex">6D</span><span class="ch">m</span><span class="dec">109</span></td>
|
||||||
|
<td class="punct"><span class="hex">7D</span><span class="ch">}</span><span class="dec">125</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">E<span class="b">1110</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">0E</span><span class="ch">SO</span><span class="dec">14</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">1E</span><span class="ch">RS</span><span class="dec">30</span></td>
|
||||||
|
<td class="punct"><span class="hex">2E</span><span class="ch">.</span><span class="dec">46</span></td>
|
||||||
|
<td class="punct"><span class="hex">3E</span><span class="ch">></span><span class="dec">62</span></td>
|
||||||
|
<td class="upper"><span class="hex">4E</span><span class="ch">N</span><span class="dec">78</span></td>
|
||||||
|
<td class="punct"><span class="hex">5E</span><span class="ch">^</span><span class="dec">94</span></td>
|
||||||
|
<td class="lower"><span class="hex">6E</span><span class="ch">n</span><span class="dec">110</span></td>
|
||||||
|
<td class="punct"><span class="hex">7E</span><span class="ch">~</span><span class="dec">126</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="row">F<span class="b">1111</span></th>
|
||||||
|
<td class="ctrl"><span class="hex">0F</span><span class="ch">SI</span><span class="dec">15</span></td>
|
||||||
|
<td class="ctrl"><span class="hex">1F</span><span class="ch">US</span><span class="dec">31</span></td>
|
||||||
|
<td class="punct"><span class="hex">2F</span><span class="ch">/</span><span class="dec">47</span></td>
|
||||||
|
<td class="punct"><span class="hex">3F</span><span class="ch">?</span><span class="dec">63</span></td>
|
||||||
|
<td class="upper"><span class="hex">4F</span><span class="ch">O</span><span class="dec">79</span></td>
|
||||||
|
<td class="punct"><span class="hex">5F</span><span class="ch">_</span><span class="dec">95</span></td>
|
||||||
|
<td class="lower"><span class="hex">6F</span><span class="ch">o</span><span class="dec">111</span></td>
|
||||||
|
<td class="del"><span class="hex">7F</span><span class="ch">DEL</span><span class="dec">127</span></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="legend">
|
||||||
|
<div class="item"><span class="swatch ctrl"></span>Steuerzeichen (0–31)</div>
|
||||||
|
<div class="item"><span class="swatch space"></span>Leerzeichen (32)</div>
|
||||||
|
<div class="item"><span class="swatch punct"></span>Satzzeichen</div>
|
||||||
|
<div class="item"><span class="swatch digit"></span>Ziffern (48–57)</div>
|
||||||
|
<div class="item"><span class="swatch upper"></span>Großbuchstaben (65–90)</div>
|
||||||
|
<div class="item"><span class="swatch lower"></span>Kleinbuchstaben (97–122)</div>
|
||||||
|
<div class="item"><span class="swatch del"></span>DEL (127)</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="meta-row">
|
||||||
|
<span><strong>Beispiel:</strong> <code>A</code> = Hex <code>41</code> = Dez <code>65</code> = Bin <code>0100 0001</code></span>
|
||||||
|
<span><strong>Trick:</strong> Ziffern <code>0–9</code> liegen bei <code>30–39</code> · <code>'A'+1='B'</code> · Groß ↔ Klein: Bit 5 togglen</span>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Byte-Fluss: Bit → Hex → ASCII</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--hl: #d63384;
|
||||||
|
--dark: #1a1a2e;
|
||||||
|
--muted: #6b7280;
|
||||||
|
--border: #cbd5e1;
|
||||||
|
--bg-soft: #f8fafc;
|
||||||
|
--byte-border: #94a3b8;
|
||||||
|
}
|
||||||
|
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||||
|
body { padding: 22px 28px; }
|
||||||
|
h1 { text-align: center; margin: 0 0 4px; font-size: 1.55rem; }
|
||||||
|
.sub { text-align: center; color: var(--muted); margin-bottom: 18px; font-size: 0.95rem; }
|
||||||
|
|
||||||
|
.stage { display: flex; flex-direction: column; align-items: center; gap: 8px; max-width: 920px; margin: 0 auto; }
|
||||||
|
|
||||||
|
.file {
|
||||||
|
width: 100%; box-sizing: border-box;
|
||||||
|
border: 2px solid var(--dark);
|
||||||
|
border-radius: 10px;
|
||||||
|
background: var(--bg-soft);
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 6px 20px rgba(0,0,0,0.08);
|
||||||
|
}
|
||||||
|
.file .head {
|
||||||
|
background: var(--dark); color: #fff; padding: 8px 14px;
|
||||||
|
font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700;
|
||||||
|
display: flex; justify-content: space-between; align-items: center;
|
||||||
|
}
|
||||||
|
.file .head .name { font-family: ui-monospace, monospace; }
|
||||||
|
.file .head .meta { font-weight: 400; opacity: 0.7; text-transform: none; letter-spacing: 0; font-size: 0.85em; }
|
||||||
|
.file .body { padding: 12px 14px; }
|
||||||
|
|
||||||
|
.row-bytes { display: flex; gap: 6px; margin-bottom: 6px; flex-wrap: nowrap; }
|
||||||
|
.row-bytes:last-child { margin-bottom: 0; }
|
||||||
|
|
||||||
|
.byte-bin {
|
||||||
|
border: 1px solid var(--byte-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 4px 7px;
|
||||||
|
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
||||||
|
font-size: 0.92rem;
|
||||||
|
font-weight: 700;
|
||||||
|
background: #fff;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
}
|
||||||
|
.byte-hex {
|
||||||
|
border: 1px solid var(--byte-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 0;
|
||||||
|
font-family: ui-monospace, monospace;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
background: #fff;
|
||||||
|
min-width: 88px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.byte-ascii {
|
||||||
|
border: 1px solid var(--byte-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 0;
|
||||||
|
font-family: ui-monospace, monospace;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 700;
|
||||||
|
background: #fff;
|
||||||
|
min-width: 88px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.byte-ascii.np { color: var(--muted); font-style: italic; }
|
||||||
|
|
||||||
|
.truncate { color: var(--muted); font-family: ui-monospace, monospace; padding: 4px 6px; font-weight: 700; align-self: center; }
|
||||||
|
|
||||||
|
.arrow-stack { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 4px 0; }
|
||||||
|
.arrow {
|
||||||
|
width: 0; height: 0;
|
||||||
|
border-left: 11px solid transparent;
|
||||||
|
border-right: 11px solid transparent;
|
||||||
|
border-top: 14px solid var(--hl);
|
||||||
|
}
|
||||||
|
.arrow-label {
|
||||||
|
font-size: 0.78rem; color: var(--hl); font-weight: 700;
|
||||||
|
text-transform: uppercase; letter-spacing: 0.05em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend {
|
||||||
|
margin-top: 12px;
|
||||||
|
display: flex; gap: 14px; flex-wrap: wrap; justify-content: center;
|
||||||
|
font-size: 0.85rem; color: var(--muted);
|
||||||
|
}
|
||||||
|
.legend strong { color: var(--dark); }
|
||||||
|
.legend code { background: var(--bg-soft); border: 1px solid var(--border); padding: 1px 6px; border-radius: 3px; font-family: ui-monospace, monospace; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>1 Byte = 8 Bit = 2 Hex = 1 ASCII-Zeichen</h1>
|
||||||
|
<div class="sub">Dieselbe Datei — dieselben Byte, drei Schreibweisen. Jeder Rahmen = ein Byte.</div>
|
||||||
|
|
||||||
|
<div class="stage">
|
||||||
|
|
||||||
|
<!-- Stage 1: Bitstream -->
|
||||||
|
<div class="file">
|
||||||
|
<div class="head"><span class="name">datei.bin</span><span class="meta">Roh-Bit · 8 Bit pro Rahmen</span></div>
|
||||||
|
<div class="body">
|
||||||
|
<div class="row-bytes">
|
||||||
|
<span class="byte-bin">01001000</span><span class="byte-bin">01100101</span><span class="byte-bin">01101100</span><span class="byte-bin">01101100</span><span class="byte-bin">01101111</span><span class="byte-bin">00101100</span><span class="byte-bin">00100000</span><span class="byte-bin">01010111</span>
|
||||||
|
</div>
|
||||||
|
<div class="row-bytes">
|
||||||
|
<span class="byte-bin">01101111</span><span class="byte-bin">01110010</span><span class="byte-bin">01101100</span><span class="byte-bin">01100100</span><span class="byte-bin">00100001</span><span class="byte-bin">00100000</span><span class="byte-bin">01001000</span><span class="byte-bin">01101111</span>
|
||||||
|
</div>
|
||||||
|
<div class="row-bytes">
|
||||||
|
<span class="byte-bin">01110111</span><span class="byte-bin">00100000</span><span class="byte-bin">01100001</span><span class="byte-bin">01110010</span><span class="byte-bin">01100101</span><span class="byte-bin">00100000</span><span class="byte-bin">01111001</span><span class="byte-bin">01101111</span>
|
||||||
|
</div>
|
||||||
|
<div class="row-bytes">
|
||||||
|
<span class="byte-bin">01110101</span><span class="byte-bin">00111111</span><span class="byte-bin">00001010</span><span class="truncate">… (weitere Byte)</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="arrow-stack">
|
||||||
|
<div class="arrow-label">je 8 Bit → 2 Hex-Ziffern</div>
|
||||||
|
<div class="arrow"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Stage 2: Hex -->
|
||||||
|
<div class="file">
|
||||||
|
<div class="head"><span class="name">datei.hex</span><span class="meta">Hex-Sicht · 2 Hex-Ziffern pro Rahmen</span></div>
|
||||||
|
<div class="body">
|
||||||
|
<div class="row-bytes">
|
||||||
|
<span class="byte-hex">48</span><span class="byte-hex">65</span><span class="byte-hex">6C</span><span class="byte-hex">6C</span><span class="byte-hex">6F</span><span class="byte-hex">2C</span><span class="byte-hex">20</span><span class="byte-hex">57</span>
|
||||||
|
</div>
|
||||||
|
<div class="row-bytes">
|
||||||
|
<span class="byte-hex">6F</span><span class="byte-hex">72</span><span class="byte-hex">6C</span><span class="byte-hex">64</span><span class="byte-hex">21</span><span class="byte-hex">20</span><span class="byte-hex">48</span><span class="byte-hex">6F</span>
|
||||||
|
</div>
|
||||||
|
<div class="row-bytes">
|
||||||
|
<span class="byte-hex">77</span><span class="byte-hex">20</span><span class="byte-hex">61</span><span class="byte-hex">72</span><span class="byte-hex">65</span><span class="byte-hex">20</span><span class="byte-hex">79</span><span class="byte-hex">6F</span>
|
||||||
|
</div>
|
||||||
|
<div class="row-bytes">
|
||||||
|
<span class="byte-hex">75</span><span class="byte-hex">3F</span><span class="byte-hex">0A</span><span class="truncate">…</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="arrow-stack">
|
||||||
|
<div class="arrow-label">je 1 Byte → 1 Zeichen</div>
|
||||||
|
<div class="arrow"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Stage 3: ASCII -->
|
||||||
|
<div class="file">
|
||||||
|
<div class="head"><span class="name">datei.txt</span><span class="meta">Text-Sicht · 1 ASCII-Zeichen pro Rahmen</span></div>
|
||||||
|
<div class="body">
|
||||||
|
<div class="row-bytes">
|
||||||
|
<span class="byte-ascii">H</span><span class="byte-ascii">e</span><span class="byte-ascii">l</span><span class="byte-ascii">l</span><span class="byte-ascii">o</span><span class="byte-ascii">,</span><span class="byte-ascii np">␣</span><span class="byte-ascii">W</span>
|
||||||
|
</div>
|
||||||
|
<div class="row-bytes">
|
||||||
|
<span class="byte-ascii">o</span><span class="byte-ascii">r</span><span class="byte-ascii">l</span><span class="byte-ascii">d</span><span class="byte-ascii">!</span><span class="byte-ascii np">␣</span><span class="byte-ascii">H</span><span class="byte-ascii">o</span>
|
||||||
|
</div>
|
||||||
|
<div class="row-bytes">
|
||||||
|
<span class="byte-ascii">w</span><span class="byte-ascii np">␣</span><span class="byte-ascii">a</span><span class="byte-ascii">r</span><span class="byte-ascii">e</span><span class="byte-ascii np">␣</span><span class="byte-ascii">y</span><span class="byte-ascii">o</span>
|
||||||
|
</div>
|
||||||
|
<div class="row-bytes">
|
||||||
|
<span class="byte-ascii">u</span><span class="byte-ascii">?</span><span class="byte-ascii np">↵</span><span class="truncate">…</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="legend">
|
||||||
|
<span><code>␣</code> = Leerzeichen (0x20)</span>
|
||||||
|
<span><code>↵</code> = Zeilenumbruch (0x0A, nicht druckbar)</span>
|
||||||
|
<span><strong>Byte ändern sich nicht.</strong> Nur die Anzeige.</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
After Width: | Height: | Size: 77 KiB |
@@ -0,0 +1,185 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Byte → Nibble → Hex</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--hl: #d63384;
|
||||||
|
--dark: #1a1a2e;
|
||||||
|
--muted: #6b7280;
|
||||||
|
--border: #cbd5e1;
|
||||||
|
--bg-soft: #f8fafc;
|
||||||
|
}
|
||||||
|
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||||
|
body { padding: 28px 32px; }
|
||||||
|
h1 { text-align: center; margin: 0 0 4px; font-size: 1.55rem; }
|
||||||
|
.sub { text-align: center; color: var(--muted); margin-bottom: 22px; font-size: 0.95rem; }
|
||||||
|
|
||||||
|
.stage { display: flex; flex-direction: column; align-items: center; gap: 6px; }
|
||||||
|
|
||||||
|
.level { display: flex; flex-direction: column; align-items: center; }
|
||||||
|
.label { font-size: 0.78rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 6px; font-weight: 600; }
|
||||||
|
|
||||||
|
/* Level 1: whole byte */
|
||||||
|
.byte {
|
||||||
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 8px 14px;
|
||||||
|
border: 2px solid var(--dark);
|
||||||
|
border-radius: 8px;
|
||||||
|
background: var(--bg-soft);
|
||||||
|
}
|
||||||
|
.byte .bit { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 1.3rem; font-weight: 700; padding: 4px 8px; min-width: 22px; text-align: center; }
|
||||||
|
.byte .sep { width: 2px; background: var(--hl); margin: 2px 6px; border-radius: 2px; }
|
||||||
|
|
||||||
|
/* Split arrows */
|
||||||
|
.split { display: flex; justify-content: space-between; width: 360px; margin: 2px 0; }
|
||||||
|
.split .arrow {
|
||||||
|
width: 0; height: 0;
|
||||||
|
border-left: 9px solid transparent;
|
||||||
|
border-right: 9px solid transparent;
|
||||||
|
border-top: 12px solid var(--hl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Level 2: two nibbles */
|
||||||
|
.nibbles { display: flex; gap: 80px; }
|
||||||
|
.nibble {
|
||||||
|
display: flex; flex-direction: column; align-items: center; gap: 6px;
|
||||||
|
padding: 10px 14px;
|
||||||
|
border: 2px solid var(--hl);
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.nibble .bits { display: flex; gap: 4px; font-family: ui-monospace, monospace; font-size: 1.15rem; font-weight: 700; }
|
||||||
|
.nibble .bits span { padding: 2px 6px; min-width: 20px; text-align: center; }
|
||||||
|
.nibble .meta { font-size: 0.78rem; color: var(--muted); }
|
||||||
|
|
||||||
|
.single-arrow {
|
||||||
|
width: 0; height: 0;
|
||||||
|
border-left: 9px solid transparent;
|
||||||
|
border-right: 9px solid transparent;
|
||||||
|
border-top: 12px solid var(--hl);
|
||||||
|
margin: 2px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Level 3: hex digits */
|
||||||
|
.hex-digits { display: flex; gap: 80px; }
|
||||||
|
.hex-digit {
|
||||||
|
display: flex; flex-direction: column; align-items: center; gap: 4px;
|
||||||
|
padding: 8px 22px;
|
||||||
|
border: 2px solid var(--dark);
|
||||||
|
border-radius: 8px;
|
||||||
|
background: var(--dark);
|
||||||
|
color: var(--hl);
|
||||||
|
}
|
||||||
|
.hex-digit .digit { font-family: ui-monospace, monospace; font-size: 2rem; font-weight: 800; line-height: 1; }
|
||||||
|
.hex-digit .meta { font-size: 0.72rem; color: #f3f4f6; opacity: 0.7; }
|
||||||
|
|
||||||
|
/* Merge down to byte */
|
||||||
|
.merge {
|
||||||
|
display: flex; justify-content: center; margin-top: 2px;
|
||||||
|
}
|
||||||
|
.merge-v {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 60px 60px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.merge-v .line {
|
||||||
|
height: 20px;
|
||||||
|
border-right: 2px solid var(--hl);
|
||||||
|
}
|
||||||
|
.merge-v .line.l { border-right: none; border-left: 2px solid var(--hl); }
|
||||||
|
.bottom-bar { height: 2px; background: var(--hl); width: 120px; }
|
||||||
|
|
||||||
|
/* Final result */
|
||||||
|
.result {
|
||||||
|
margin-top: 14px;
|
||||||
|
padding: 14px 22px;
|
||||||
|
background: #fef3f8;
|
||||||
|
border-left: 4px solid var(--hl);
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
text-align: center;
|
||||||
|
max-width: 640px;
|
||||||
|
}
|
||||||
|
.result code { background: var(--dark); color: var(--hl); padding: 2px 8px; border-radius: 4px; font-family: ui-monospace, monospace; font-weight: 700; }
|
||||||
|
.result strong { color: var(--hl); }
|
||||||
|
|
||||||
|
.math {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: var(--dark);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.math .eq { font-family: ui-monospace, monospace; font-weight: 700; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>1 Byte → 2 Nibble → 2 Hex-Ziffern</h1>
|
||||||
|
<div class="sub">Jedes Byte lässt sich sauber halbieren – und 4 Bit passen exakt auf eine Hex-Ziffer.</div>
|
||||||
|
|
||||||
|
<div class="stage">
|
||||||
|
<!-- Level 1 -->
|
||||||
|
<div class="level">
|
||||||
|
<div class="label">1 Byte · 8 Bit · 2⁸ = 256 Werte</div>
|
||||||
|
<div class="byte">
|
||||||
|
<span class="bit">0</span><span class="bit">1</span><span class="bit">0</span><span class="bit">0</span>
|
||||||
|
<span class="sep"></span>
|
||||||
|
<span class="bit">1</span><span class="bit">1</span><span class="bit">0</span><span class="bit">1</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="split">
|
||||||
|
<div class="arrow"></div>
|
||||||
|
<div class="arrow"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Level 2 -->
|
||||||
|
<div class="level">
|
||||||
|
<div class="label">2 Nibble · je 4 Bit · 2⁴ = 16 Werte</div>
|
||||||
|
<div class="nibbles">
|
||||||
|
<div class="nibble">
|
||||||
|
<div class="bits"><span>0</span><span>1</span><span>0</span><span>0</span></div>
|
||||||
|
<div class="meta">= 4 (dez)</div>
|
||||||
|
</div>
|
||||||
|
<div class="nibble">
|
||||||
|
<div class="bits"><span>1</span><span>1</span><span>0</span><span>1</span></div>
|
||||||
|
<div class="meta">= 13 (dez)</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="split">
|
||||||
|
<div class="arrow"></div>
|
||||||
|
<div class="arrow"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Level 3 -->
|
||||||
|
<div class="level">
|
||||||
|
<div class="label">2 Hex-Ziffern · Symbole 0–F</div>
|
||||||
|
<div class="hex-digits">
|
||||||
|
<div class="hex-digit">
|
||||||
|
<div class="digit">4</div>
|
||||||
|
<div class="meta">Nibble → 1 Ziffer</div>
|
||||||
|
</div>
|
||||||
|
<div class="hex-digit">
|
||||||
|
<div class="digit">D</div>
|
||||||
|
<div class="meta">13 → D</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="result">
|
||||||
|
<code>01001101</code> (bin) = <code>4D</code> (hex) = <strong>77</strong> (dez) = <strong>"M"</strong> (ASCII)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="math">
|
||||||
|
<span class="eq">16 × 16 = 256</span> · <span class="eq">2⁴ × 2⁴ = 2⁸</span> · Darum passt Hex so gut zu Bytes.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</content>
|
||||||
|
</invoke>
|
||||||
|
After Width: | Height: | Size: 97 KiB |
@@ -0,0 +1,67 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Hex → Dezimal</title>
|
||||||
|
<style>
|
||||||
|
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; }
|
||||||
|
body { padding: 28px; }
|
||||||
|
h1 { text-align: center; margin: 0 0 4px; font-size: 1.6rem; color: #1a1a2e; }
|
||||||
|
.sub { text-align: center; color: #6b7280; margin-bottom: 18px; font-size: 0.95rem; }
|
||||||
|
table { border-collapse: collapse; margin: 0 auto; font-variant-numeric: tabular-nums; }
|
||||||
|
th, td { border: 1px solid #cbd5e1; padding: 7px 10px; text-align: center; font-size: 0.95rem; }
|
||||||
|
thead th { background: #1a1a2e; color: #fff; }
|
||||||
|
tbody th { background: #334155; color: #fff; font-weight: 600; }
|
||||||
|
tbody td.ascii { background: #f3f4f6; }
|
||||||
|
tbody td.nonascii { background: #fff; color: #6b7280; }
|
||||||
|
.corner { background: #0f0f23; color: #d63384; }
|
||||||
|
.legend { display: flex; justify-content: center; gap: 24px; margin-top: 16px; font-size: 0.9rem; color: #374151; }
|
||||||
|
.sw { display: inline-block; width: 14px; height: 14px; border: 1px solid #cbd5e1; vertical-align: middle; margin-right: 6px; }
|
||||||
|
.example { margin: 20px auto 0; max-width: 720px; padding: 14px 18px; background: #fef3f8; border-left: 4px solid #d63384; border-radius: 4px; font-size: 1rem; color: #1a1a2e; }
|
||||||
|
code { background: #1a1a2e; color: #d63384; padding: 2px 6px; border-radius: 3px; font-family: ui-monospace, monospace; font-weight: 700; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Hex → Dezimal</h1>
|
||||||
|
<div class="sub">Dezimalwert = (Zeile × 16) + Spalte</div>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="corner">×16 / +</th>
|
||||||
|
<th>0</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th>
|
||||||
|
<th>8</th><th>9</th><th>A <small style="opacity:.7;font-weight:400">(10)</small></th><th>B <small style="opacity:.7;font-weight:400">(11)</small></th><th>C <small style="opacity:.7;font-weight:400">(12)</small></th><th>D <small style="opacity:.7;font-weight:400">(13)</small></th><th>E <small style="opacity:.7;font-weight:400">(14)</small></th><th>F <small style="opacity:.7;font-weight:400">(15)</small></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="legend">
|
||||||
|
<span><span class="sw" style="background:#f3f4f6"></span>ASCII (0–127)</span>
|
||||||
|
<span><span class="sw" style="background:#fff"></span>Non-ASCII (128–255)</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="example">
|
||||||
|
<strong>Beispiel:</strong> <code>4D</code> → Zeile <code>4</code> × 16 + Spalte <code>D</code> = 64 + 13 = <strong>77</strong> (= "M" in ASCII)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const rows = '0123456789ABCDEF';
|
||||||
|
const tb = document.querySelector('tbody');
|
||||||
|
for (let r = 0; r < 16; r++) {
|
||||||
|
const tr = document.createElement('tr');
|
||||||
|
const th = document.createElement('th');
|
||||||
|
th.innerHTML = r >= 10 ? rows[r] + ' <small style="opacity:.7;font-weight:400">('+r+')</small>' : rows[r];
|
||||||
|
tr.appendChild(th);
|
||||||
|
for (let c = 0; c < 16; c++) {
|
||||||
|
const td = document.createElement('td');
|
||||||
|
const v = r*16 + c;
|
||||||
|
td.textContent = v;
|
||||||
|
td.className = v <= 127 ? 'ascii' : 'nonascii';
|
||||||
|
tr.appendChild(td);
|
||||||
|
}
|
||||||
|
tb.appendChild(tr);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
After Width: | Height: | Size: 275 KiB |
@@ -0,0 +1,120 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Dieselben Byte — drei Perspektiven</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--hl: #d63384;
|
||||||
|
--dark: #1a1a2e;
|
||||||
|
--muted: #6b7280;
|
||||||
|
--border: #cbd5e1;
|
||||||
|
--bg-soft: #f8fafc;
|
||||||
|
--magic: #ef4444;
|
||||||
|
--format: #2563eb;
|
||||||
|
--transport: #16a34a;
|
||||||
|
}
|
||||||
|
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||||
|
body { padding: 24px 28px; }
|
||||||
|
h1 { text-align: center; margin: 0 0 4px; font-size: 1.55rem; }
|
||||||
|
.sub { text-align: center; color: var(--muted); margin-bottom: 18px; font-size: 0.95rem; }
|
||||||
|
|
||||||
|
.stage { display: flex; flex-direction: column; gap: 14px; align-items: stretch; max-width: 1080px; margin: 0 auto; }
|
||||||
|
|
||||||
|
.row { display: grid; grid-template-columns: 200px 1fr; gap: 14px; align-items: center; }
|
||||||
|
.label { font-size: 0.8rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; text-align: right; white-space: nowrap; }
|
||||||
|
.label small { display: block; font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--muted); margin-top: 2px; font-size: 0.8em; white-space: nowrap; }
|
||||||
|
|
||||||
|
.panel { padding: 14px 16px; border: 2px solid var(--border); border-radius: 8px; background: var(--bg-soft); }
|
||||||
|
.panel.bin { background: #0f0f23; color: #fff; border-color: var(--dark); }
|
||||||
|
.panel.bin code { color: #e5e7eb; }
|
||||||
|
.mono { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 1.1rem; font-weight: 700; letter-spacing: 0.02em; word-break: break-all; line-height: 1.5; }
|
||||||
|
|
||||||
|
.hex-bytes { display: flex; flex-wrap: wrap; gap: 8px; }
|
||||||
|
.hex-byte { background: #fff; border: 1px solid var(--border); border-radius: 4px; padding: 4px 10px; font-family: ui-monospace, monospace; font-size: 1.15rem; font-weight: 700; }
|
||||||
|
|
||||||
|
.semantic { display: flex; gap: 6px; flex-wrap: wrap; align-items: stretch; }
|
||||||
|
.group { display: flex; flex-direction: column; gap: 4px; padding: 8px 10px; border-radius: 6px; min-width: 70px; }
|
||||||
|
.group .bytes { display: flex; gap: 4px; }
|
||||||
|
.group .b { background: #fff; border: 1px solid currentColor; border-radius: 3px; padding: 3px 7px; font-family: ui-monospace, monospace; font-size: 1rem; font-weight: 700; color: var(--dark); }
|
||||||
|
.group .tag { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; }
|
||||||
|
.group .meaning { font-size: 0.78rem; line-height: 1.3; color: var(--dark); }
|
||||||
|
.group.magic { background: #fee2e2; color: var(--magic); }
|
||||||
|
.group.format { background: #dbeafe; color: var(--format); }
|
||||||
|
.group.transport { background: #dcfce7; color: var(--transport); }
|
||||||
|
|
||||||
|
.arrow-row { display: flex; justify-content: center; }
|
||||||
|
.arrow {
|
||||||
|
width: 0; height: 0;
|
||||||
|
border-left: 11px solid transparent;
|
||||||
|
border-right: 11px solid transparent;
|
||||||
|
border-top: 14px solid var(--hl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footnote { margin-top: 16px; font-size: 0.88rem; color: var(--muted); text-align: center; max-width: 800px; margin-left: auto; margin-right: auto; }
|
||||||
|
.footnote strong { color: var(--dark); }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Dieselben 8 Byte — drei Perspektiven</h1>
|
||||||
|
<div class="sub">PNG-Datei-Anfang: <code style="font-family:ui-monospace,monospace">89 50 4E 47 0D 0A 1A 0A</code></div>
|
||||||
|
|
||||||
|
<div class="stage">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="label">1 · Bitstream<small>was wirklich gespeichert wird</small></div>
|
||||||
|
<div class="panel bin">
|
||||||
|
<code class="mono">10001001 01010000 01001110 01000111 00001101 00001010 00011010 00001010</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="arrow-row"><div class="arrow"></div></div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="label">2 · Hex<small>gruppiert in 8-Bit-Häppchen</small></div>
|
||||||
|
<div class="panel">
|
||||||
|
<div class="hex-bytes">
|
||||||
|
<span class="hex-byte">89</span>
|
||||||
|
<span class="hex-byte">50</span>
|
||||||
|
<span class="hex-byte">4E</span>
|
||||||
|
<span class="hex-byte">47</span>
|
||||||
|
<span class="hex-byte">0D</span>
|
||||||
|
<span class="hex-byte">0A</span>
|
||||||
|
<span class="hex-byte">1A</span>
|
||||||
|
<span class="hex-byte">0A</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="arrow-row"><div class="arrow"></div></div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="label">3 · Bedeutung<small>was die Byte sagen</small></div>
|
||||||
|
<div class="panel">
|
||||||
|
<div class="semantic">
|
||||||
|
<div class="group magic">
|
||||||
|
<div class="bytes"><span class="b">89</span></div>
|
||||||
|
<div class="tag">Magic Byte</div>
|
||||||
|
<div class="meaning">> 127 → "Ich bin Binär, kein Text"</div>
|
||||||
|
</div>
|
||||||
|
<div class="group format">
|
||||||
|
<div class="bytes"><span class="b">50</span><span class="b">4E</span><span class="b">47</span></div>
|
||||||
|
<div class="tag">Format-Kürzel</div>
|
||||||
|
<div class="meaning">P · N · G (ASCII) → "PNG-Datei"</div>
|
||||||
|
</div>
|
||||||
|
<div class="group transport">
|
||||||
|
<div class="bytes"><span class="b">0D</span><span class="b">0A</span><span class="b">1A</span><span class="b">0A</span></div>
|
||||||
|
<div class="tag">Transport-Schutz</div>
|
||||||
|
<div class="meaning">CR · LF · EOF · LF → erkennt kaputte Übertragung</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footnote">
|
||||||
|
Byte ändern sich nicht — nur unsere <strong>Brille</strong>. Bitstream zeigt das <em>was</em>, Hex das <em>wie kompakt</em>, Bedeutung das <em>warum</em>.
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
After Width: | Height: | Size: 58 KiB |
@@ -0,0 +1,135 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Warum 8 Bit? Adressierung im Speicher</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--hl: #d63384;
|
||||||
|
--dark: #1a1a2e;
|
||||||
|
--muted: #6b7280;
|
||||||
|
--border: #cbd5e1;
|
||||||
|
--bg-soft: #f8fafc;
|
||||||
|
--bad: #ef4444;
|
||||||
|
--good: #16a34a;
|
||||||
|
}
|
||||||
|
html, body { margin: 0; padding: 0; background: #fff; font-family: system-ui, -apple-system, sans-serif; color: var(--dark); }
|
||||||
|
body { padding: 24px 28px; }
|
||||||
|
h1 { text-align: center; margin: 0 0 4px; font-size: 1.55rem; }
|
||||||
|
.sub { text-align: center; color: var(--muted); margin-bottom: 22px; font-size: 0.95rem; }
|
||||||
|
|
||||||
|
.stage { display: flex; flex-direction: column; align-items: center; gap: 18px; max-width: 1100px; margin: 0 auto; }
|
||||||
|
|
||||||
|
.ram-wrap { display: flex; gap: 18px; align-items: stretch; }
|
||||||
|
|
||||||
|
.ram {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 90px 90px 230px;
|
||||||
|
border: 2px solid var(--dark);
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: var(--bg-soft);
|
||||||
|
}
|
||||||
|
.ram .head {
|
||||||
|
background: var(--dark); color: #fff; padding: 8px 10px;
|
||||||
|
font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; text-align: center;
|
||||||
|
}
|
||||||
|
.ram .cell {
|
||||||
|
border-top: 1px solid var(--border); padding: 10px 12px;
|
||||||
|
font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 1.05rem; font-weight: 700;
|
||||||
|
text-align: center; background: #fff;
|
||||||
|
}
|
||||||
|
.ram .cell.addr { color: var(--muted); background: var(--bg-soft); }
|
||||||
|
.ram .cell.bin { font-size: 0.95rem; letter-spacing: 0.05em; }
|
||||||
|
.ram .row.cur .cell { background: #fef3f8; color: var(--hl); }
|
||||||
|
|
||||||
|
.pointer-side { display: flex; flex-direction: column; gap: 12px; padding-top: 36px; }
|
||||||
|
.ptr-block { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-radius: 6px; font-family: ui-monospace, monospace; font-weight: 700; font-size: 0.95rem; }
|
||||||
|
.ptr-block.ok { background: #dcfce7; color: var(--good); border: 2px solid var(--good); }
|
||||||
|
.ptr-block.bad { background: #fee2e2; color: var(--bad); border: 2px dashed var(--bad); }
|
||||||
|
.ptr-block.between {
|
||||||
|
background: #fff; color: var(--bad); border: 2px dashed var(--bad);
|
||||||
|
margin: -12px 0 -12px 0;
|
||||||
|
transform: translateX(-10px);
|
||||||
|
}
|
||||||
|
.ptr-block .ico { font-size: 1.3rem; line-height: 1; }
|
||||||
|
|
||||||
|
.legend {
|
||||||
|
display: flex; gap: 22px; padding: 12px 16px; border-top: 1px solid var(--border);
|
||||||
|
font-size: 0.9rem; color: var(--dark);
|
||||||
|
}
|
||||||
|
.legend .row { display: flex; align-items: center; gap: 6px; }
|
||||||
|
.legend .swatch { width: 14px; height: 14px; border-radius: 3px; }
|
||||||
|
|
||||||
|
.conclusion {
|
||||||
|
margin-top: 6px;
|
||||||
|
padding: 14px 22px;
|
||||||
|
background: #fef3f8;
|
||||||
|
border-left: 4px solid var(--hl);
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 1rem;
|
||||||
|
text-align: center;
|
||||||
|
max-width: 760px;
|
||||||
|
}
|
||||||
|
.conclusion strong { color: var(--hl); }
|
||||||
|
.conclusion code { background: var(--dark); color: #f8f8f8; padding: 1px 6px; border-radius: 3px; font-family: ui-monospace, monospace; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Warum 8 Bit? Speicher-Adressierung</h1>
|
||||||
|
<div class="sub">CPU adressiert <strong>byteweise</strong> — halbe Byte existieren nicht.</div>
|
||||||
|
|
||||||
|
<div class="stage">
|
||||||
|
|
||||||
|
<div class="ram-wrap">
|
||||||
|
|
||||||
|
<div class="ram">
|
||||||
|
<div class="head">Adresse</div>
|
||||||
|
<div class="head">Hex</div>
|
||||||
|
<div class="head">Bit (was im Speicher steht)</div>
|
||||||
|
|
||||||
|
<div class="cell addr">0x0000</div>
|
||||||
|
<div class="cell">48</div>
|
||||||
|
<div class="cell bin">01001000</div>
|
||||||
|
|
||||||
|
<div class="cell addr">0x0001</div>
|
||||||
|
<div class="cell">65</div>
|
||||||
|
<div class="cell bin">01100101</div>
|
||||||
|
|
||||||
|
<div class="cell addr">0x0002</div>
|
||||||
|
<div class="cell">6C</div>
|
||||||
|
<div class="cell bin">01101100</div>
|
||||||
|
|
||||||
|
<div class="cell addr">0x0003</div>
|
||||||
|
<div class="cell">6C</div>
|
||||||
|
<div class="cell bin">01101100</div>
|
||||||
|
|
||||||
|
<div class="cell addr">0x0004</div>
|
||||||
|
<div class="cell">6F</div>
|
||||||
|
<div class="cell bin">01101111</div>
|
||||||
|
|
||||||
|
<div class="cell addr">0x0005</div>
|
||||||
|
<div class="cell">21</div>
|
||||||
|
<div class="cell bin">00100001</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pointer-side">
|
||||||
|
<div class="ptr-block ok"><span class="ico">→</span><span>read 0x0000 ✓</span></div>
|
||||||
|
<div class="ptr-block bad"><span class="ico">✗</span><span>read 0x0000.5 — gibt's nicht</span></div>
|
||||||
|
<div class="ptr-block ok"><span class="ico">→</span><span>read 0x0001 ✓</span></div>
|
||||||
|
<div class="ptr-block bad"><span class="ico">✗</span><span>read 0x0001.5 — gibt's nicht</span></div>
|
||||||
|
<div class="ptr-block ok"><span class="ico">→</span><span>read 0x0002 ✓</span></div>
|
||||||
|
<div class="ptr-block ok" style="opacity:0.4"><span class="ico">→</span><span>...</span></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="conclusion">
|
||||||
|
<strong>Byte = kleinste adressierbare Einheit.</strong><br>
|
||||||
|
Speichercontroller, Bus und CPU sind alle auf 8-Bit-Häppchen ausgelegt.<br>
|
||||||
|
Einzelne Bit lesen → muss erst <code>byte = mem[addr]</code>, dann mit <code>byte & 0b1000_0000</code> Bit isolieren.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 318 KiB |
@@ -0,0 +1,258 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2560 1440" preserveAspectRatio="none" shape-rendering="crispEdges">
|
||||||
|
<rect x="0" y="0" width="10" height="1440" fill="rgb(255,255,255)"/>
|
||||||
|
<rect x="10" y="0" width="10" height="1440" fill="rgb(254,254,254)"/>
|
||||||
|
<rect x="20" y="0" width="10" height="1440" fill="rgb(253,253,253)"/>
|
||||||
|
<rect x="30" y="0" width="10" height="1440" fill="rgb(252,252,252)"/>
|
||||||
|
<rect x="40" y="0" width="10" height="1440" fill="rgb(251,251,251)"/>
|
||||||
|
<rect x="50" y="0" width="10" height="1440" fill="rgb(250,250,250)"/>
|
||||||
|
<rect x="60" y="0" width="10" height="1440" fill="rgb(249,249,249)"/>
|
||||||
|
<rect x="70" y="0" width="10" height="1440" fill="rgb(248,248,248)"/>
|
||||||
|
<rect x="80" y="0" width="10" height="1440" fill="rgb(247,247,247)"/>
|
||||||
|
<rect x="90" y="0" width="10" height="1440" fill="rgb(246,246,246)"/>
|
||||||
|
<rect x="100" y="0" width="10" height="1440" fill="rgb(245,245,245)"/>
|
||||||
|
<rect x="110" y="0" width="10" height="1440" fill="rgb(244,244,244)"/>
|
||||||
|
<rect x="120" y="0" width="10" height="1440" fill="rgb(243,243,243)"/>
|
||||||
|
<rect x="130" y="0" width="10" height="1440" fill="rgb(242,242,242)"/>
|
||||||
|
<rect x="140" y="0" width="10" height="1440" fill="rgb(241,241,241)"/>
|
||||||
|
<rect x="150" y="0" width="10" height="1440" fill="rgb(240,240,240)"/>
|
||||||
|
<rect x="160" y="0" width="10" height="1440" fill="rgb(239,239,239)"/>
|
||||||
|
<rect x="170" y="0" width="10" height="1440" fill="rgb(238,238,238)"/>
|
||||||
|
<rect x="180" y="0" width="10" height="1440" fill="rgb(237,237,237)"/>
|
||||||
|
<rect x="190" y="0" width="10" height="1440" fill="rgb(236,236,236)"/>
|
||||||
|
<rect x="200" y="0" width="10" height="1440" fill="rgb(235,235,235)"/>
|
||||||
|
<rect x="210" y="0" width="10" height="1440" fill="rgb(234,234,234)"/>
|
||||||
|
<rect x="220" y="0" width="10" height="1440" fill="rgb(233,233,233)"/>
|
||||||
|
<rect x="230" y="0" width="10" height="1440" fill="rgb(232,232,232)"/>
|
||||||
|
<rect x="240" y="0" width="10" height="1440" fill="rgb(231,231,231)"/>
|
||||||
|
<rect x="250" y="0" width="10" height="1440" fill="rgb(230,230,230)"/>
|
||||||
|
<rect x="260" y="0" width="10" height="1440" fill="rgb(229,229,229)"/>
|
||||||
|
<rect x="270" y="0" width="10" height="1440" fill="rgb(228,228,228)"/>
|
||||||
|
<rect x="280" y="0" width="10" height="1440" fill="rgb(227,227,227)"/>
|
||||||
|
<rect x="290" y="0" width="10" height="1440" fill="rgb(226,226,226)"/>
|
||||||
|
<rect x="300" y="0" width="10" height="1440" fill="rgb(225,225,225)"/>
|
||||||
|
<rect x="310" y="0" width="10" height="1440" fill="rgb(224,224,224)"/>
|
||||||
|
<rect x="320" y="0" width="10" height="1440" fill="rgb(223,223,223)"/>
|
||||||
|
<rect x="330" y="0" width="10" height="1440" fill="rgb(222,222,222)"/>
|
||||||
|
<rect x="340" y="0" width="10" height="1440" fill="rgb(221,221,221)"/>
|
||||||
|
<rect x="350" y="0" width="10" height="1440" fill="rgb(220,220,220)"/>
|
||||||
|
<rect x="360" y="0" width="10" height="1440" fill="rgb(219,219,219)"/>
|
||||||
|
<rect x="370" y="0" width="10" height="1440" fill="rgb(218,218,218)"/>
|
||||||
|
<rect x="380" y="0" width="10" height="1440" fill="rgb(217,217,217)"/>
|
||||||
|
<rect x="390" y="0" width="10" height="1440" fill="rgb(216,216,216)"/>
|
||||||
|
<rect x="400" y="0" width="10" height="1440" fill="rgb(215,215,215)"/>
|
||||||
|
<rect x="410" y="0" width="10" height="1440" fill="rgb(214,214,214)"/>
|
||||||
|
<rect x="420" y="0" width="10" height="1440" fill="rgb(213,213,213)"/>
|
||||||
|
<rect x="430" y="0" width="10" height="1440" fill="rgb(212,212,212)"/>
|
||||||
|
<rect x="440" y="0" width="10" height="1440" fill="rgb(211,211,211)"/>
|
||||||
|
<rect x="450" y="0" width="10" height="1440" fill="rgb(210,210,210)"/>
|
||||||
|
<rect x="460" y="0" width="10" height="1440" fill="rgb(209,209,209)"/>
|
||||||
|
<rect x="470" y="0" width="10" height="1440" fill="rgb(208,208,208)"/>
|
||||||
|
<rect x="480" y="0" width="10" height="1440" fill="rgb(207,207,207)"/>
|
||||||
|
<rect x="490" y="0" width="10" height="1440" fill="rgb(206,206,206)"/>
|
||||||
|
<rect x="500" y="0" width="10" height="1440" fill="rgb(205,205,205)"/>
|
||||||
|
<rect x="510" y="0" width="10" height="1440" fill="rgb(204,204,204)"/>
|
||||||
|
<rect x="520" y="0" width="10" height="1440" fill="rgb(203,203,203)"/>
|
||||||
|
<rect x="530" y="0" width="10" height="1440" fill="rgb(202,202,202)"/>
|
||||||
|
<rect x="540" y="0" width="10" height="1440" fill="rgb(201,201,201)"/>
|
||||||
|
<rect x="550" y="0" width="10" height="1440" fill="rgb(200,200,200)"/>
|
||||||
|
<rect x="560" y="0" width="10" height="1440" fill="rgb(199,199,199)"/>
|
||||||
|
<rect x="570" y="0" width="10" height="1440" fill="rgb(198,198,198)"/>
|
||||||
|
<rect x="580" y="0" width="10" height="1440" fill="rgb(197,197,197)"/>
|
||||||
|
<rect x="590" y="0" width="10" height="1440" fill="rgb(196,196,196)"/>
|
||||||
|
<rect x="600" y="0" width="10" height="1440" fill="rgb(195,195,195)"/>
|
||||||
|
<rect x="610" y="0" width="10" height="1440" fill="rgb(194,194,194)"/>
|
||||||
|
<rect x="620" y="0" width="10" height="1440" fill="rgb(193,193,193)"/>
|
||||||
|
<rect x="630" y="0" width="10" height="1440" fill="rgb(192,192,192)"/>
|
||||||
|
<rect x="640" y="0" width="10" height="1440" fill="rgb(191,191,191)"/>
|
||||||
|
<rect x="650" y="0" width="10" height="1440" fill="rgb(190,190,190)"/>
|
||||||
|
<rect x="660" y="0" width="10" height="1440" fill="rgb(189,189,189)"/>
|
||||||
|
<rect x="670" y="0" width="10" height="1440" fill="rgb(188,188,188)"/>
|
||||||
|
<rect x="680" y="0" width="10" height="1440" fill="rgb(187,187,187)"/>
|
||||||
|
<rect x="690" y="0" width="10" height="1440" fill="rgb(186,186,186)"/>
|
||||||
|
<rect x="700" y="0" width="10" height="1440" fill="rgb(185,185,185)"/>
|
||||||
|
<rect x="710" y="0" width="10" height="1440" fill="rgb(184,184,184)"/>
|
||||||
|
<rect x="720" y="0" width="10" height="1440" fill="rgb(183,183,183)"/>
|
||||||
|
<rect x="730" y="0" width="10" height="1440" fill="rgb(182,182,182)"/>
|
||||||
|
<rect x="740" y="0" width="10" height="1440" fill="rgb(181,181,181)"/>
|
||||||
|
<rect x="750" y="0" width="10" height="1440" fill="rgb(180,180,180)"/>
|
||||||
|
<rect x="760" y="0" width="10" height="1440" fill="rgb(179,179,179)"/>
|
||||||
|
<rect x="770" y="0" width="10" height="1440" fill="rgb(178,178,178)"/>
|
||||||
|
<rect x="780" y="0" width="10" height="1440" fill="rgb(177,177,177)"/>
|
||||||
|
<rect x="790" y="0" width="10" height="1440" fill="rgb(176,176,176)"/>
|
||||||
|
<rect x="800" y="0" width="10" height="1440" fill="rgb(175,175,175)"/>
|
||||||
|
<rect x="810" y="0" width="10" height="1440" fill="rgb(174,174,174)"/>
|
||||||
|
<rect x="820" y="0" width="10" height="1440" fill="rgb(173,173,173)"/>
|
||||||
|
<rect x="830" y="0" width="10" height="1440" fill="rgb(172,172,172)"/>
|
||||||
|
<rect x="840" y="0" width="10" height="1440" fill="rgb(171,171,171)"/>
|
||||||
|
<rect x="850" y="0" width="10" height="1440" fill="rgb(170,170,170)"/>
|
||||||
|
<rect x="860" y="0" width="10" height="1440" fill="rgb(169,169,169)"/>
|
||||||
|
<rect x="870" y="0" width="10" height="1440" fill="rgb(168,168,168)"/>
|
||||||
|
<rect x="880" y="0" width="10" height="1440" fill="rgb(167,167,167)"/>
|
||||||
|
<rect x="890" y="0" width="10" height="1440" fill="rgb(166,166,166)"/>
|
||||||
|
<rect x="900" y="0" width="10" height="1440" fill="rgb(165,165,165)"/>
|
||||||
|
<rect x="910" y="0" width="10" height="1440" fill="rgb(164,164,164)"/>
|
||||||
|
<rect x="920" y="0" width="10" height="1440" fill="rgb(163,163,163)"/>
|
||||||
|
<rect x="930" y="0" width="10" height="1440" fill="rgb(162,162,162)"/>
|
||||||
|
<rect x="940" y="0" width="10" height="1440" fill="rgb(161,161,161)"/>
|
||||||
|
<rect x="950" y="0" width="10" height="1440" fill="rgb(160,160,160)"/>
|
||||||
|
<rect x="960" y="0" width="10" height="1440" fill="rgb(159,159,159)"/>
|
||||||
|
<rect x="970" y="0" width="10" height="1440" fill="rgb(158,158,158)"/>
|
||||||
|
<rect x="980" y="0" width="10" height="1440" fill="rgb(157,157,157)"/>
|
||||||
|
<rect x="990" y="0" width="10" height="1440" fill="rgb(156,156,156)"/>
|
||||||
|
<rect x="1000" y="0" width="10" height="1440" fill="rgb(155,155,155)"/>
|
||||||
|
<rect x="1010" y="0" width="10" height="1440" fill="rgb(154,154,154)"/>
|
||||||
|
<rect x="1020" y="0" width="10" height="1440" fill="rgb(153,153,153)"/>
|
||||||
|
<rect x="1030" y="0" width="10" height="1440" fill="rgb(152,152,152)"/>
|
||||||
|
<rect x="1040" y="0" width="10" height="1440" fill="rgb(151,151,151)"/>
|
||||||
|
<rect x="1050" y="0" width="10" height="1440" fill="rgb(150,150,150)"/>
|
||||||
|
<rect x="1060" y="0" width="10" height="1440" fill="rgb(149,149,149)"/>
|
||||||
|
<rect x="1070" y="0" width="10" height="1440" fill="rgb(148,148,148)"/>
|
||||||
|
<rect x="1080" y="0" width="10" height="1440" fill="rgb(147,147,147)"/>
|
||||||
|
<rect x="1090" y="0" width="10" height="1440" fill="rgb(146,146,146)"/>
|
||||||
|
<rect x="1100" y="0" width="10" height="1440" fill="rgb(145,145,145)"/>
|
||||||
|
<rect x="1110" y="0" width="10" height="1440" fill="rgb(144,144,144)"/>
|
||||||
|
<rect x="1120" y="0" width="10" height="1440" fill="rgb(143,143,143)"/>
|
||||||
|
<rect x="1130" y="0" width="10" height="1440" fill="rgb(142,142,142)"/>
|
||||||
|
<rect x="1140" y="0" width="10" height="1440" fill="rgb(141,141,141)"/>
|
||||||
|
<rect x="1150" y="0" width="10" height="1440" fill="rgb(140,140,140)"/>
|
||||||
|
<rect x="1160" y="0" width="10" height="1440" fill="rgb(139,139,139)"/>
|
||||||
|
<rect x="1170" y="0" width="10" height="1440" fill="rgb(138,138,138)"/>
|
||||||
|
<rect x="1180" y="0" width="10" height="1440" fill="rgb(137,137,137)"/>
|
||||||
|
<rect x="1190" y="0" width="10" height="1440" fill="rgb(136,136,136)"/>
|
||||||
|
<rect x="1200" y="0" width="10" height="1440" fill="rgb(135,135,135)"/>
|
||||||
|
<rect x="1210" y="0" width="10" height="1440" fill="rgb(134,134,134)"/>
|
||||||
|
<rect x="1220" y="0" width="10" height="1440" fill="rgb(133,133,133)"/>
|
||||||
|
<rect x="1230" y="0" width="10" height="1440" fill="rgb(132,132,132)"/>
|
||||||
|
<rect x="1240" y="0" width="10" height="1440" fill="rgb(131,131,131)"/>
|
||||||
|
<rect x="1250" y="0" width="10" height="1440" fill="rgb(130,130,130)"/>
|
||||||
|
<rect x="1260" y="0" width="10" height="1440" fill="rgb(129,129,129)"/>
|
||||||
|
<rect x="1270" y="0" width="10" height="1440" fill="rgb(128,128,128)"/>
|
||||||
|
<rect x="1280" y="0" width="10" height="1440" fill="rgb(127,127,127)"/>
|
||||||
|
<rect x="1290" y="0" width="10" height="1440" fill="rgb(126,126,126)"/>
|
||||||
|
<rect x="1300" y="0" width="10" height="1440" fill="rgb(125,125,125)"/>
|
||||||
|
<rect x="1310" y="0" width="10" height="1440" fill="rgb(124,124,124)"/>
|
||||||
|
<rect x="1320" y="0" width="10" height="1440" fill="rgb(123,123,123)"/>
|
||||||
|
<rect x="1330" y="0" width="10" height="1440" fill="rgb(122,122,122)"/>
|
||||||
|
<rect x="1340" y="0" width="10" height="1440" fill="rgb(121,121,121)"/>
|
||||||
|
<rect x="1350" y="0" width="10" height="1440" fill="rgb(120,120,120)"/>
|
||||||
|
<rect x="1360" y="0" width="10" height="1440" fill="rgb(119,119,119)"/>
|
||||||
|
<rect x="1370" y="0" width="10" height="1440" fill="rgb(118,118,118)"/>
|
||||||
|
<rect x="1380" y="0" width="10" height="1440" fill="rgb(117,117,117)"/>
|
||||||
|
<rect x="1390" y="0" width="10" height="1440" fill="rgb(116,116,116)"/>
|
||||||
|
<rect x="1400" y="0" width="10" height="1440" fill="rgb(115,115,115)"/>
|
||||||
|
<rect x="1410" y="0" width="10" height="1440" fill="rgb(114,114,114)"/>
|
||||||
|
<rect x="1420" y="0" width="10" height="1440" fill="rgb(113,113,113)"/>
|
||||||
|
<rect x="1430" y="0" width="10" height="1440" fill="rgb(112,112,112)"/>
|
||||||
|
<rect x="1440" y="0" width="10" height="1440" fill="rgb(111,111,111)"/>
|
||||||
|
<rect x="1450" y="0" width="10" height="1440" fill="rgb(110,110,110)"/>
|
||||||
|
<rect x="1460" y="0" width="10" height="1440" fill="rgb(109,109,109)"/>
|
||||||
|
<rect x="1470" y="0" width="10" height="1440" fill="rgb(108,108,108)"/>
|
||||||
|
<rect x="1480" y="0" width="10" height="1440" fill="rgb(107,107,107)"/>
|
||||||
|
<rect x="1490" y="0" width="10" height="1440" fill="rgb(106,106,106)"/>
|
||||||
|
<rect x="1500" y="0" width="10" height="1440" fill="rgb(105,105,105)"/>
|
||||||
|
<rect x="1510" y="0" width="10" height="1440" fill="rgb(104,104,104)"/>
|
||||||
|
<rect x="1520" y="0" width="10" height="1440" fill="rgb(103,103,103)"/>
|
||||||
|
<rect x="1530" y="0" width="10" height="1440" fill="rgb(102,102,102)"/>
|
||||||
|
<rect x="1540" y="0" width="10" height="1440" fill="rgb(101,101,101)"/>
|
||||||
|
<rect x="1550" y="0" width="10" height="1440" fill="rgb(100,100,100)"/>
|
||||||
|
<rect x="1560" y="0" width="10" height="1440" fill="rgb(99,99,99)"/>
|
||||||
|
<rect x="1570" y="0" width="10" height="1440" fill="rgb(98,98,98)"/>
|
||||||
|
<rect x="1580" y="0" width="10" height="1440" fill="rgb(97,97,97)"/>
|
||||||
|
<rect x="1590" y="0" width="10" height="1440" fill="rgb(96,96,96)"/>
|
||||||
|
<rect x="1600" y="0" width="10" height="1440" fill="rgb(95,95,95)"/>
|
||||||
|
<rect x="1610" y="0" width="10" height="1440" fill="rgb(94,94,94)"/>
|
||||||
|
<rect x="1620" y="0" width="10" height="1440" fill="rgb(93,93,93)"/>
|
||||||
|
<rect x="1630" y="0" width="10" height="1440" fill="rgb(92,92,92)"/>
|
||||||
|
<rect x="1640" y="0" width="10" height="1440" fill="rgb(91,91,91)"/>
|
||||||
|
<rect x="1650" y="0" width="10" height="1440" fill="rgb(90,90,90)"/>
|
||||||
|
<rect x="1660" y="0" width="10" height="1440" fill="rgb(89,89,89)"/>
|
||||||
|
<rect x="1670" y="0" width="10" height="1440" fill="rgb(88,88,88)"/>
|
||||||
|
<rect x="1680" y="0" width="10" height="1440" fill="rgb(87,87,87)"/>
|
||||||
|
<rect x="1690" y="0" width="10" height="1440" fill="rgb(86,86,86)"/>
|
||||||
|
<rect x="1700" y="0" width="10" height="1440" fill="rgb(85,85,85)"/>
|
||||||
|
<rect x="1710" y="0" width="10" height="1440" fill="rgb(84,84,84)"/>
|
||||||
|
<rect x="1720" y="0" width="10" height="1440" fill="rgb(83,83,83)"/>
|
||||||
|
<rect x="1730" y="0" width="10" height="1440" fill="rgb(82,82,82)"/>
|
||||||
|
<rect x="1740" y="0" width="10" height="1440" fill="rgb(81,81,81)"/>
|
||||||
|
<rect x="1750" y="0" width="10" height="1440" fill="rgb(80,80,80)"/>
|
||||||
|
<rect x="1760" y="0" width="10" height="1440" fill="rgb(79,79,79)"/>
|
||||||
|
<rect x="1770" y="0" width="10" height="1440" fill="rgb(78,78,78)"/>
|
||||||
|
<rect x="1780" y="0" width="10" height="1440" fill="rgb(77,77,77)"/>
|
||||||
|
<rect x="1790" y="0" width="10" height="1440" fill="rgb(76,76,76)"/>
|
||||||
|
<rect x="1800" y="0" width="10" height="1440" fill="rgb(75,75,75)"/>
|
||||||
|
<rect x="1810" y="0" width="10" height="1440" fill="rgb(74,74,74)"/>
|
||||||
|
<rect x="1820" y="0" width="10" height="1440" fill="rgb(73,73,73)"/>
|
||||||
|
<rect x="1830" y="0" width="10" height="1440" fill="rgb(72,72,72)"/>
|
||||||
|
<rect x="1840" y="0" width="10" height="1440" fill="rgb(71,71,71)"/>
|
||||||
|
<rect x="1850" y="0" width="10" height="1440" fill="rgb(70,70,70)"/>
|
||||||
|
<rect x="1860" y="0" width="10" height="1440" fill="rgb(69,69,69)"/>
|
||||||
|
<rect x="1870" y="0" width="10" height="1440" fill="rgb(68,68,68)"/>
|
||||||
|
<rect x="1880" y="0" width="10" height="1440" fill="rgb(67,67,67)"/>
|
||||||
|
<rect x="1890" y="0" width="10" height="1440" fill="rgb(66,66,66)"/>
|
||||||
|
<rect x="1900" y="0" width="10" height="1440" fill="rgb(65,65,65)"/>
|
||||||
|
<rect x="1910" y="0" width="10" height="1440" fill="rgb(64,64,64)"/>
|
||||||
|
<rect x="1920" y="0" width="10" height="1440" fill="rgb(63,63,63)"/>
|
||||||
|
<rect x="1930" y="0" width="10" height="1440" fill="rgb(62,62,62)"/>
|
||||||
|
<rect x="1940" y="0" width="10" height="1440" fill="rgb(61,61,61)"/>
|
||||||
|
<rect x="1950" y="0" width="10" height="1440" fill="rgb(60,60,60)"/>
|
||||||
|
<rect x="1960" y="0" width="10" height="1440" fill="rgb(59,59,59)"/>
|
||||||
|
<rect x="1970" y="0" width="10" height="1440" fill="rgb(58,58,58)"/>
|
||||||
|
<rect x="1980" y="0" width="10" height="1440" fill="rgb(57,57,57)"/>
|
||||||
|
<rect x="1990" y="0" width="10" height="1440" fill="rgb(56,56,56)"/>
|
||||||
|
<rect x="2000" y="0" width="10" height="1440" fill="rgb(55,55,55)"/>
|
||||||
|
<rect x="2010" y="0" width="10" height="1440" fill="rgb(54,54,54)"/>
|
||||||
|
<rect x="2020" y="0" width="10" height="1440" fill="rgb(53,53,53)"/>
|
||||||
|
<rect x="2030" y="0" width="10" height="1440" fill="rgb(52,52,52)"/>
|
||||||
|
<rect x="2040" y="0" width="10" height="1440" fill="rgb(51,51,51)"/>
|
||||||
|
<rect x="2050" y="0" width="10" height="1440" fill="rgb(50,50,50)"/>
|
||||||
|
<rect x="2060" y="0" width="10" height="1440" fill="rgb(49,49,49)"/>
|
||||||
|
<rect x="2070" y="0" width="10" height="1440" fill="rgb(48,48,48)"/>
|
||||||
|
<rect x="2080" y="0" width="10" height="1440" fill="rgb(47,47,47)"/>
|
||||||
|
<rect x="2090" y="0" width="10" height="1440" fill="rgb(46,46,46)"/>
|
||||||
|
<rect x="2100" y="0" width="10" height="1440" fill="rgb(45,45,45)"/>
|
||||||
|
<rect x="2110" y="0" width="10" height="1440" fill="rgb(44,44,44)"/>
|
||||||
|
<rect x="2120" y="0" width="10" height="1440" fill="rgb(43,43,43)"/>
|
||||||
|
<rect x="2130" y="0" width="10" height="1440" fill="rgb(42,42,42)"/>
|
||||||
|
<rect x="2140" y="0" width="10" height="1440" fill="rgb(41,41,41)"/>
|
||||||
|
<rect x="2150" y="0" width="10" height="1440" fill="rgb(40,40,40)"/>
|
||||||
|
<rect x="2160" y="0" width="10" height="1440" fill="rgb(39,39,39)"/>
|
||||||
|
<rect x="2170" y="0" width="10" height="1440" fill="rgb(38,38,38)"/>
|
||||||
|
<rect x="2180" y="0" width="10" height="1440" fill="rgb(37,37,37)"/>
|
||||||
|
<rect x="2190" y="0" width="10" height="1440" fill="rgb(36,36,36)"/>
|
||||||
|
<rect x="2200" y="0" width="10" height="1440" fill="rgb(35,35,35)"/>
|
||||||
|
<rect x="2210" y="0" width="10" height="1440" fill="rgb(34,34,34)"/>
|
||||||
|
<rect x="2220" y="0" width="10" height="1440" fill="rgb(33,33,33)"/>
|
||||||
|
<rect x="2230" y="0" width="10" height="1440" fill="rgb(32,32,32)"/>
|
||||||
|
<rect x="2240" y="0" width="10" height="1440" fill="rgb(31,31,31)"/>
|
||||||
|
<rect x="2250" y="0" width="10" height="1440" fill="rgb(30,30,30)"/>
|
||||||
|
<rect x="2260" y="0" width="10" height="1440" fill="rgb(29,29,29)"/>
|
||||||
|
<rect x="2270" y="0" width="10" height="1440" fill="rgb(28,28,28)"/>
|
||||||
|
<rect x="2280" y="0" width="10" height="1440" fill="rgb(27,27,27)"/>
|
||||||
|
<rect x="2290" y="0" width="10" height="1440" fill="rgb(26,26,26)"/>
|
||||||
|
<rect x="2300" y="0" width="10" height="1440" fill="rgb(25,25,25)"/>
|
||||||
|
<rect x="2310" y="0" width="10" height="1440" fill="rgb(24,24,24)"/>
|
||||||
|
<rect x="2320" y="0" width="10" height="1440" fill="rgb(23,23,23)"/>
|
||||||
|
<rect x="2330" y="0" width="10" height="1440" fill="rgb(22,22,22)"/>
|
||||||
|
<rect x="2340" y="0" width="10" height="1440" fill="rgb(21,21,21)"/>
|
||||||
|
<rect x="2350" y="0" width="10" height="1440" fill="rgb(20,20,20)"/>
|
||||||
|
<rect x="2360" y="0" width="10" height="1440" fill="rgb(19,19,19)"/>
|
||||||
|
<rect x="2370" y="0" width="10" height="1440" fill="rgb(18,18,18)"/>
|
||||||
|
<rect x="2380" y="0" width="10" height="1440" fill="rgb(17,17,17)"/>
|
||||||
|
<rect x="2390" y="0" width="10" height="1440" fill="rgb(16,16,16)"/>
|
||||||
|
<rect x="2400" y="0" width="10" height="1440" fill="rgb(15,15,15)"/>
|
||||||
|
<rect x="2410" y="0" width="10" height="1440" fill="rgb(14,14,14)"/>
|
||||||
|
<rect x="2420" y="0" width="10" height="1440" fill="rgb(13,13,13)"/>
|
||||||
|
<rect x="2430" y="0" width="10" height="1440" fill="rgb(12,12,12)"/>
|
||||||
|
<rect x="2440" y="0" width="10" height="1440" fill="rgb(11,11,11)"/>
|
||||||
|
<rect x="2450" y="0" width="10" height="1440" fill="rgb(10,10,10)"/>
|
||||||
|
<rect x="2460" y="0" width="10" height="1440" fill="rgb(9,9,9)"/>
|
||||||
|
<rect x="2470" y="0" width="10" height="1440" fill="rgb(8,8,8)"/>
|
||||||
|
<rect x="2480" y="0" width="10" height="1440" fill="rgb(7,7,7)"/>
|
||||||
|
<rect x="2490" y="0" width="10" height="1440" fill="rgb(6,6,6)"/>
|
||||||
|
<rect x="2500" y="0" width="10" height="1440" fill="rgb(5,5,5)"/>
|
||||||
|
<rect x="2510" y="0" width="10" height="1440" fill="rgb(4,4,4)"/>
|
||||||
|
<rect x="2520" y="0" width="10" height="1440" fill="rgb(3,3,3)"/>
|
||||||
|
<rect x="2530" y="0" width="10" height="1440" fill="rgb(2,2,2)"/>
|
||||||
|
<rect x="2540" y="0" width="10" height="1440" fill="rgb(1,1,1)"/>
|
||||||
|
<rect x="2550" y="0" width="10" height="1440" fill="rgb(0,0,0)"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,53 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 1080">
|
||||||
|
<rect width="1920" height="1080" fill="#ffffff"/>
|
||||||
|
<text x="960.0" y="100" text-anchor="middle" font-family="sans-serif" font-size="54" fill="#1a1a2e" font-weight="bold">Zoom: die 16 hellsten Abstufungen</text>
|
||||||
|
<rect x="60.00" y="220" width="101.25" height="500" fill="rgb(255,255,255)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="110.62" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">255</text>
|
||||||
|
<text x="110.62" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xFF</text>
|
||||||
|
<rect x="173.25" y="220" width="101.25" height="500" fill="rgb(254,254,254)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="223.88" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">254</text>
|
||||||
|
<text x="223.88" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xFE</text>
|
||||||
|
<rect x="286.50" y="220" width="101.25" height="500" fill="rgb(253,253,253)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="337.12" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">253</text>
|
||||||
|
<text x="337.12" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xFD</text>
|
||||||
|
<rect x="399.75" y="220" width="101.25" height="500" fill="rgb(252,252,252)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="450.38" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">252</text>
|
||||||
|
<text x="450.38" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xFC</text>
|
||||||
|
<rect x="513.00" y="220" width="101.25" height="500" fill="rgb(251,251,251)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="563.62" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">251</text>
|
||||||
|
<text x="563.62" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xFB</text>
|
||||||
|
<rect x="626.25" y="220" width="101.25" height="500" fill="rgb(250,250,250)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="676.88" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">250</text>
|
||||||
|
<text x="676.88" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xFA</text>
|
||||||
|
<rect x="739.50" y="220" width="101.25" height="500" fill="rgb(249,249,249)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="790.12" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">249</text>
|
||||||
|
<text x="790.12" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF9</text>
|
||||||
|
<rect x="852.75" y="220" width="101.25" height="500" fill="rgb(248,248,248)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="903.38" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">248</text>
|
||||||
|
<text x="903.38" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF8</text>
|
||||||
|
<rect x="966.00" y="220" width="101.25" height="500" fill="rgb(247,247,247)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="1016.62" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">247</text>
|
||||||
|
<text x="1016.62" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF7</text>
|
||||||
|
<rect x="1079.25" y="220" width="101.25" height="500" fill="rgb(246,246,246)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="1129.88" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">246</text>
|
||||||
|
<text x="1129.88" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF6</text>
|
||||||
|
<rect x="1192.50" y="220" width="101.25" height="500" fill="rgb(245,245,245)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="1243.12" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">245</text>
|
||||||
|
<text x="1243.12" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF5</text>
|
||||||
|
<rect x="1305.75" y="220" width="101.25" height="500" fill="rgb(244,244,244)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="1356.38" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">244</text>
|
||||||
|
<text x="1356.38" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF4</text>
|
||||||
|
<rect x="1419.00" y="220" width="101.25" height="500" fill="rgb(243,243,243)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="1469.62" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">243</text>
|
||||||
|
<text x="1469.62" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF3</text>
|
||||||
|
<rect x="1532.25" y="220" width="101.25" height="500" fill="rgb(242,242,242)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="1582.88" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">242</text>
|
||||||
|
<text x="1582.88" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF2</text>
|
||||||
|
<rect x="1645.50" y="220" width="101.25" height="500" fill="rgb(241,241,241)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="1696.12" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">241</text>
|
||||||
|
<text x="1696.12" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF1</text>
|
||||||
|
<rect x="1758.75" y="220" width="101.25" height="500" fill="rgb(240,240,240)" stroke="#1a1a2e" stroke-width="3"/>
|
||||||
|
<text x="1809.38" y="820" text-anchor="middle" font-family="monospace" font-size="42" fill="#1a1a2e" font-weight="bold">240</text>
|
||||||
|
<text x="1809.38" y="900" text-anchor="middle" font-family="monospace" font-size="36" fill="#4a4a6a">0xF0</text>
|
||||||
|
<text x="960.0" y="1020" text-anchor="middle" font-family="sans-serif" font-size="28" fill="#4a4a6a" font-style="italic">jede Stufe = Unterschied von 1/255 ≈ 0,4% Helligkeit</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 161 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 112 KiB |
@@ -0,0 +1,9 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80">
|
||||||
|
<defs>
|
||||||
|
<pattern id="diagonalStripes" patternUnits="userSpaceOnUse" width="80" height="80" patternTransform="rotate(135)">
|
||||||
|
<rect width="40" height="80" fill="#e3f2fd"/>
|
||||||
|
<rect x="40" width="40" height="80" fill="#ffffff"/>
|
||||||
|
</pattern>
|
||||||
|
</defs>
|
||||||
|
<rect width="100%" height="100%" fill="url(#diagonalStripes)"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 401 B |
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 38 KiB |