LabCodeHub öffentliche Ansicht
Anmelden
Küpper / Quildrop öffentlich

fix: new version with themes + multi arch builds

R Rüdiger Küpper <rpr@9it.de> committete am 17.08.2026 22:51
b56ed7e0c7d0a33fd6c702129c1fe0d9a7546a8f
699 geänderte Datei(en) +2684 −102
Kontextzeilen: 0 1 2 3 10
geändert .github/workflows/build-and-release.yml
+14 −0 Datei ansehen
@@ -87,34 +87,48 @@ jobs:
87 87
        uses: actions/upload-artifact@v7
88 88
        with:
89 89
          name: ${{ env.BINARY_NAME }}-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goarm && format('v{0}', matrix.goarm) || '' }}
90 90
          path: dist/*
91 91
          if-no-files-found: error
92 92
93 93
  release:
94 94
    needs: build
95 95
    runs-on: ubuntu-latest
96 96
    steps:
97 +
      - name: Checkout
98 +
        uses: actions/checkout@v6
99 +
        with:
100 +
          path: src
101 +
97 102
      - name: Download all artifacts
98 103
        uses: actions/download-artifact@v8
99 104
        with:
100 105
          path: artifacts
101 106
          merge-multiple: true
102 107
103 108
      - name: Merge checksums
104 109
        run: |
105 110
          cd artifacts
106 111
          cat checksums-*.txt > checksums.txt
107 112
          rm checksums-*.txt
108 113
          echo "=== checksums.txt ==="
109 114
          cat checksums.txt
110 115
116 +
      # Templates are no longer embedded in the binary — ship the default theme
117 +
      # so a new site can be bootstrapped without cloning the repository.
118 +
      - name: Package default theme
119 +
        run: |
120 +
          set -euo pipefail
121 +
          tar -czf artifacts/${BINARY_NAME}-theme-default.tar.gz -C src themes/default
122 +
          cd artifacts
123 +
          sha256sum ${BINARY_NAME}-theme-default.tar.gz >> checksums.txt
124 +
111 125
      - name: Determine tag
112 126
        id: tag
113 127
        run: |
114 128
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
115 129
            echo "version=${{ github.event.inputs.tag }}" >> "$GITHUB_OUTPUT"
116 130
          else
117 131
            echo "version=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
118 132
          fi
119 133
120 134
      - name: List release assets
geändert .gitignore
+1 −1 Datei ansehen
@@ -1,4 +1,4 @@
1 1
output/
2 2
newblog
3 3
.DS_Store
4 -
quilldrop
\ No newline at end of file
4 +
quilldrop
geändert Makefile
+82 −4 Datei ansehen
@@ -1,26 +1,104 @@
1 -
.PHONY: serve build docker-images docker-static docker-run
1 +
.PHONY: serve serve-dev generate build build-native build-macos build-linux \
2 +
	build-raspberry build-windows checksums new-theme clean \
3 +
	docker-images docker-static docker-run
2 4
3 5
GIT := $(shell git pull --quiet 2>/dev/null || true)
4 6
LATEST_TAG := $(shell git tag --sort=-version:refname | head -n 1)
5 7
6 8
tag:
7 9
	@echo "Latest tag: $(LATEST_TAG)"
8 10
9 11
serve:
10 12
	go run . serve
11 13
14 +
# Server mit Template-Live-Reload (Theme-Entwicklung), optional: make serve-dev THEME=newdesign
15 +
serve-dev:
16 +
	go run . serve -dev $(if $(THEME),-theme $(THEME))
17 +
12 18
generate:
13 19
	go run . generate
14 20
15 -
build:
16 -
	GOOS=linux GOARCH=arm64 go build -o quilldrop
21 +
# ---------------------------------------------------------------------------
22 +
# Builds
23 +
#
24 +
# Alle Binaries landen in $(DIST)/ und heissen quilldrop-<os>-<arch>[v<arm>].
25 +
# Einzelne Ziele: make build-linux, build-macos, build-windows, build-raspberry
26 +
# ---------------------------------------------------------------------------
27 +
28 +
BINARY_NAME := quilldrop
29 +
DIST        := dist
30 +
GOFLAGS_REL := -trimpath -ldflags=-s\ -w
31 +
32 +
# $(call go_build,GOOS,GOARCH[,GOARM][,Kommentar])
33 +
define go_build
34 +
	@mkdir -p $(DIST)
35 +
	@echo "  -> $(1)/$(2)$(if $(3),v$(3))$(if $(4),   [$(4)])"
36 +
	@GOOS=$(1) GOARCH=$(2) GOARM=$(3) CGO_ENABLED=0 \
37 +
		go build $(GOFLAGS_REL) \
38 +
		-o $(DIST)/$(BINARY_NAME)-$(1)-$(2)$(if $(3),v$(3))$(if $(filter windows,$(1)),.exe) .
39 +
endef
40 +
41 +
# Alle Plattformen
42 +
build: build-macos build-linux build-windows checksums
43 +
	@echo ""
44 +
	@ls -1 $(DIST)
45 +
46 +
# Nur fuer die aktuelle Maschine -> ./quilldrop
47 +
build-native:
48 +
	CGO_ENABLED=0 go build $(GOFLAGS_REL) -o $(BINARY_NAME) .
49 +
50 +
build-macos:
51 +
	@echo "macOS:"
52 +
	$(call go_build,darwin,amd64,,Intel)
53 +
	$(call go_build,darwin,arm64,,Apple Silicon M1-M4)
54 +
55 +
build-linux:
56 +
	@echo "Linux:"
57 +
	$(call go_build,linux,amd64,,x86_64)
58 +
	$(call go_build,linux,386,,x86 32-bit)
59 +
	$(call go_build,linux,arm64,,ARM 64-bit)
60 +
	$(call go_build,linux,arm,7,ARMv7 32-bit)
61 +
	$(call go_build,linux,arm,6,ARMv6 32-bit)
62 +
63 +
# Raspberry Pi (Teilmenge von build-linux, zum separaten Bauen)
64 +
#   armv6  : Pi 1, Pi Zero / Zero W, CM1
65 +
#   armv7  : Pi 2 und Pi 3/4/5 mit 32-bit OS
66 +
#   arm64  : Pi 3/4/5, Pi Zero 2 W, CM3/CM4/CM5 mit 64-bit OS (Raspberry Pi OS 64-bit)
67 +
build-raspberry:
68 +
	@echo "Raspberry Pi:"
69 +
	$(call go_build,linux,arm,6,Pi 1 / Zero / Zero W / CM1)
70 +
	$(call go_build,linux,arm,7,Pi 2 / Pi 3-5 mit 32-bit OS)
71 +
	$(call go_build,linux,arm64,,Pi 3-5 / Zero 2 W / CM3-CM5 mit 64-bit OS)
72 +
73 +
build-windows:
74 +
	@echo "Windows:"
75 +
	$(call go_build,windows,amd64,,x86_64)
76 +
	$(call go_build,windows,386,,x86 32-bit)
77 +
	$(call go_build,windows,arm64,,ARM 64-bit)
78 +
79 +
# SHA256-Summen ueber alle gebauten Binaries
80 +
checksums:
81 +
	@cd $(DIST) && \
82 +
		if command -v sha256sum >/dev/null 2>&1; then \
83 +
			sha256sum $(BINARY_NAME)-* > checksums.txt; \
84 +
		else \
85 +
			shasum -a 256 $(BINARY_NAME)-* > checksums.txt; \
86 +
		fi
87 +
	@echo "Checksums: $(DIST)/checksums.txt"
88 +
89 +
# Copy the default theme: make new-theme NAME=newdesign
90 +
new-theme:
91 +
	@test -n "$(NAME)" || { echo "Usage: make new-theme NAME=<theme>"; exit 1; }
92 +
	@test ! -d themes/$(NAME) || { echo "themes/$(NAME) already exists"; exit 1; }
93 +
	cp -r themes/default themes/$(NAME)
94 +
	@echo "Created themes/$(NAME) — activate with 'theme: $(NAME)' in config.yaml or 'go run . serve -theme $(NAME)'"
17 95
18 96
docker-static:
19 97
	podman build --platform linux/arm64 -t quilldrop -f ./Dockerfile-static .
20 98
21 99
docker-images:
22 100
	@echo "Building for tag: $(LATEST_TAG)"
23 101
	@echo "Building AMD64..."
24 102
	podman build --platform linux/amd64 \
25 103
		-t ghcr.io/9it-full-service/quilldrop:$(LATEST_TAG)-images-amd64 \
26 104
		-f ./Dockerfile-images .
@@ -48,21 +126,21 @@ docker-images:
48 126
# 		-f ./Dockerfile-images .
49 127
# 	podman manifest push --all ghcr.io/9it-full-service/quilldrop:$(LATEST_TAG)-images
50 128
51 129
docker-run:
52 130
	podman run --rm -i -p 8081:80 quilldrop:latest
53 131
54 132
test:
55 133
	go test ./...
56 134
57 135
clean:
58 -
	rm -rf bin/
136 +
	rm -rf bin/ $(DIST)/ $(BINARY_NAME)
59 137
60 138
docker-up:
61 139
	docker compose up -d
62 140
63 141
docker-down:
64 142
	docker compose down
65 143
66 144
generate-keys:
67 145
	@mkdir -p keys
68 146
	openssl genrsa -out keys/private.pem 2048
geändert README-de.md
+85 −21 Datei ansehen
@@ -200,117 +200,178 @@ quilldrop/
200 200
├── config.yaml                      # Konfiguration
201 201
├── content/                         # Blog-Posts (Markdown)
202 202
│   ├── 2025-11-06-mein-post.md
203 203
│   └── ...
204 204
├── sites/                           # Statische Seiten
205 205
│   ├── ueber-mich.md
206 206
│   ├── impressum.md
207 207
│   └── projekte/
208 208
│       └── mein-projekt/
209 209
│           └── index.md
210 -
├── static/                          # Statische Assets
211 -
│   ├── css/style.css
212 -
│   ├── js/
213 -
│   │   ├── theme.js                 # Dark/Light Toggle + TOC Generator
214 -
│   │   └── search.js                # Client-seitige Volltextsuche
210 +
├── static/                          # Seiten-Assets (Icons, Bilder, ...)
211 +
│   ├── icons/
215 212
│   └── images/
213 +
├── themes/                          # Themes — ein Verzeichnis je Theme
214 +
│   └── default/
215 +
│       ├── templates/
216 +
│       │   ├── base.html            # Base Layout + Navbar + Suche
217 +
│       │   ├── home.html            # Homepage + Pagination
218 +
│       │   ├── post.html            # Einzelner Post + Prev/Next Navigation
219 +
│       │   ├── page.html            # Statische Seite
220 +
│       │   ├── tags.html            # Tag-Übersicht
221 +
│       │   ├── tag.html             # Tag-Seite
222 +
│       │   ├── categories.html      # Kategorie-Übersicht
223 +
│       │   └── category.html        # Kategorie-Seite
224 +
│       └── static/                  # Theme-Assets (werden nach /static/ gemerged)
225 +
│           ├── css/style.css
226 +
│           └── js/
227 +
│               ├── theme.js         # Dark/Light Toggle + TOC Generator
228 +
│               └── search.js        # Client-seitige Volltextsuche
216 229
├── internal/
217 230
│   ├── config/config.go             # YAML Config Loader
218 231
│   ├── content/
219 232
│   │   ├── post.go                  # Post Struct + FlexTime + Tags/Categories
220 233
│   │   ├── parser.go                # Markdown + Frontmatter Parser
221 234
│   │   └── page.go                  # Statische Seiten Parser
222 235
│   ├── server/server.go             # HTTP Server
223 236
│   ├── generator/
224 237
│   │   ├── generator.go             # Static Site Generator
225 238
│   │   └── search.go                # Search-Index Generator (JSON)
226 239
│   └── templates/
227 -
│       ├── render.go                # Template Engine + Functions
228 -
│       ├── rss.go                   # RSS Feed Generator
229 -
│       ├── base.html                # Base Layout + Navbar + Suche
230 -
│       ├── home.html                # Homepage + Pagination
231 -
│       ├── post.html                # Einzelner Post + Prev/Next Navigation
232 -
│       ├── page.html                # Statische Seite
233 -
│       ├── tags.html                # Tag-Übersicht
234 -
│       ├── tag.html                 # Tag-Seite
235 -
│       ├── categories.html          # Kategorie-Übersicht
236 -
│       └── category.html            # Kategorie-Seite
240 +
│       ├── render.go                # Template Engine + Functions (lädt das Theme)
241 +
│       └── rss.go                   # RSS Feed Generator
237 242
└── output/                          # Generierte statische Dateien
238 243
```
239 244
240 245
### Technologie-Stack
241 246
242 247
| Komponente | Technologie |
243 248
|-----------|-------------|
244 249
| Sprache | Go (Standard Library + minimale Dependencies) |
245 250
| HTTP Server | `net/http` (Go Standard Library) |
246 -
| Templates | `html/template` mit `embed.FS` |
251 +
| Templates | `html/template`, zur Laufzeit aus `themes/<name>/templates/` geladen |
247 252
| Markdown | Goldmark + GFM + Emoji + Chroma |
248 253
| Konfiguration | YAML via `gopkg.in/yaml.v3` |
249 254
| Syntax Highlighting | Chroma (Dracula Theme) |
250 255
| Fonts | Inter + JetBrains Mono (Google Fonts) |
251 256
| CSS | Vanilla CSS mit Custom Properties |
252 257
| JavaScript | Vanilla JS — Theme Toggle, Suche, TOC (kein Framework) |
253 258
254 259
### Dependencies
255 260
256 261
QuillDrop hat bewusst minimale Abhängigkeiten - **kein Web-Framework**, **kein CSS-Framework**, **kein JS-Framework**:
257 262
258 263
- `github.com/yuin/goldmark` - Markdown Parser (CommonMark-konform)
259 264
- `github.com/yuin/goldmark-emoji` - Emoji Shortcodes
260 265
- `github.com/yuin/goldmark-highlighting/v2` - Syntax Highlighting
261 266
- `github.com/alecthomas/chroma/v2` - Syntax Highlighting Engine
262 267
- `gopkg.in/yaml.v3` - YAML Parser
263 268
264 -
### Embedded Assets
269 +
### Themes
265 270
266 -
Alle HTML-Templates werden via Go's `//go:embed` Directive direkt in das Binary eingebettet. Das bedeutet:
271 +
Templates und deren Assets liegen ausserhalb des Binaries in `themes/<name>/`. Dadurch
272 +
kann dasselbe QuillDrop-Binary beliebig viele Websites bedienen, jede mit eigenem Design:
267 273
268 -
- **Einzelnes Binary** - Keine externen Template-Dateien nötig
269 -
- **Schneller Start** - Kein Dateisystem-Zugriff für Templates
270 -
- **Einfaches Deployment** - Ein Binary + Config + Content = fertig
274 +
```
275 +
themes/
276 +
├── default/
277 +
│   ├── templates/       # Pflicht: base, home, post, page, tags, tag, categories, category
278 +
│   └── static/          # Optional: CSS, JS, Theme-Bilder
279 +
└── newdesign/
280 +
    ├── templates/
281 +
    └── static/
282 +
```
283 +
284 +
Das aktive Theme wird in der `config.yaml` gewählt:
285 +
286 +
```yaml
287 +
themesDir: "themes"   # Default
288 +
theme: "default"      # liest aus themes/default/
289 +
```
290 +
291 +
Oder temporär per Flag, z. B. um ein Redesign zu testen:
292 +
293 +
```bash
294 +
./quilldrop serve -theme newdesign
295 +
./quilldrop generate -theme newdesign
296 +
```
297 +
298 +
**Neues Theme anlegen:**
299 +
300 +
```bash
301 +
cp -r themes/default themes/newdesign      # oder: make new-theme NAME=newdesign
302 +
# themes/newdesign/templates/*.html und themes/newdesign/static/css/style.css anpassen
303 +
./quilldrop serve -theme newdesign -dev
304 +
```
305 +
306 +
**Live-Reload:** Mit `-dev` werden die Templates bei jedem Request neu aus dem
307 +
Theme-Verzeichnis gelesen — Änderungen an HTML, CSS und JS sind nach einem
308 +
Browser-Reload sichtbar, ohne den Server neu zu starten (im Dev-Modus wird
309 +
zusätzlich `Cache-Control: no-store` gesetzt, damit der Browser nichts
310 +
zwischenspeichert). Ein fehlerhaftes Template liefert eine 500 statt einer halb
311 +
gerenderten Seite; die genaue Fehlermeldung mit Datei und Zeile steht im
312 +
Server-Log. Ohne `-dev` werden die Templates wie bisher einmal beim Start
313 +
geparst. Neue oder geänderte Markdown-Dateien erfordern weiterhin einen Neustart.
314 +
315 +
Ein Theme muss alle acht Templates enthalten (`base.html`, `home.html`, `post.html`,
316 +
`page.html`, `tags.html`, `tag.html`, `categories.html`, `category.html`);
317 +
fehlt eines oder existiert das Theme nicht, bricht QuillDrop mit einer klaren
318 +
Fehlermeldung ab.
319 +
320 +
**Statische Assets** werden gemerged: zuerst `themes/<name>/static/`, danach das
321 +
eigene `static/` der Seite — gleichnamige Dateien der Seite gewinnen also
322 +
(z. B. `static/icons/favicon.ico`). Das Design gehört ins Theme (CSS, JS),
323 +
seitenspezifisches Material bleibt in `static/` (Icons, Bilder). Beides wird unter
324 +
`/static/` ausgeliefert; `static/images/` und `static/videos/` zusätzlich unter
325 +
`/images/` und `/videos/`.
271 326
272 327
## Konfiguration
273 328
274 329
Die gesamte Konfiguration erfolgt über eine einzige `config.yaml`:
275 330
276 331
```yaml
277 332
title: "Mein Blog"
278 333
description: "Tech Blog - DevOps, Kubernetes, Self-Hosted"
279 334
author: "Max Mustermann"
280 335
baseURL: "https://mein-blog.de"
281 336
port: 8080
282 337
postsPerPage: 5
283 338
contentDir: "content"
284 339
sitesDir: "sites"
340 +
staticDir: "static"
285 341
outputDir: "output"
342 +
themesDir: "themes"
343 +
theme: "default"
286 344
287 345
menu:
288 346
  - label: "Home"
289 347
    url: "/"
290 348
  - label: "Tags"
291 349
    url: "/tags"
292 350
  - label: "Über mich"
293 351
    url: "/sites/ueber-mich"
294 352
```
295 353
296 354
| Option | Default | Beschreibung |
297 355
|--------|---------|-------------|
298 356
| `title` | - | Titel der Website |
299 357
| `description` | - | Beschreibung (Meta-Tag + Hero) |
300 358
| `author` | - | Autor der Website |
301 359
| `baseURL` | - | Basis-URL für RSS und absolute Links |
302 360
| `port` | `8080` | Port für den dynamischen Server |
303 361
| `postsPerPage` | `5` | Anzahl Posts pro Seite |
304 362
| `contentDir` | `content` | Verzeichnis für Blog-Posts |
305 363
| `sitesDir` | `sites` | Verzeichnis für statische Seiten |
364 +
| `staticDir` | `static` | Verzeichnis für Seiten-Assets |
306 365
| `outputDir` | `output` | Ausgabeverzeichnis für statische Generierung |
366 +
| `themesDir` | `themes` | Verzeichnis mit allen Themes |
367 +
| `theme` | `default` | Aktives Theme, gelesen aus `<themesDir>/<theme>/` (Override: `-theme`) |
307 368
| `menu` | `[]` | Navigationsmenü mit optionalen Untermenüs |
308 369
309 370
## Schnellstart
310 371
311 372
### Installation
312 373
313 374
```bash
314 375
# Repository klonen
315 376
git clone https://github.com/ruedigerp/quilldrop.git
316 377
cd quilldrop
@@ -347,20 +408,23 @@ Das ist mein erster Post mit **QuillDrop**.
347 408
```
348 409
349 410
### Lokale Vorschau
350 411
351 412
```bash
352 413
# Dynamischen Server starten
353 414
./quilldrop serve
354 415
355 416
# Oder direkt mit Go
356 417
go run . serve
418 +
419 +
# Mit Live-Reload für Templates (Theme-Entwicklung)
420 +
./quilldrop serve -dev
357 421
```
358 422
359 423
Dann im Browser: [http://localhost:8080](http://localhost:8080)
360 424
361 425
### Statische Seite generieren
362 426
363 427
```bash
364 428
# HTML-Dateien generieren
365 429
./quilldrop generate
366 430
geändert README.md
+83 −21 Datei ansehen
@@ -202,117 +202,176 @@ quilldrop/
202 202
├── config.yaml                      # Configuration
203 203
├── content/                         # Blog posts (Markdown)
204 204
│   ├── 2025-11-06-my-post.md
205 205
│   └── ...
206 206
├── sites/                           # Static pages
207 207
│   ├── about.md
208 208
│   ├── legal.md
209 209
│   └── projects/
210 210
│       └── my-project/
211 211
│           └── index.md
212 -
├── static/                          # Static assets
213 -
│   ├── css/style.css
214 -
│   ├── js/
215 -
│   │   ├── theme.js                 # Dark/Light toggle + TOC generator
216 -
│   │   └── search.js                # Client-side full-text search
212 +
├── static/                          # Site assets (icons, images, ...)
213 +
│   ├── icons/
217 214
│   └── images/
215 +
├── themes/                          # Themes — one directory per theme
216 +
│   └── default/
217 +
│       ├── templates/
218 +
│       │   ├── base.html            # Base layout + navbar + search
219 +
│       │   ├── home.html            # Homepage + pagination
220 +
│       │   ├── post.html            # Single post + prev/next navigation
221 +
│       │   ├── page.html            # Static page
222 +
│       │   ├── tags.html            # Tag overview
223 +
│       │   ├── tag.html             # Tag page
224 +
│       │   ├── categories.html      # Category overview
225 +
│       │   └── category.html        # Category page
226 +
│       └── static/                  # Theme assets (merged into /static/)
227 +
│           ├── css/style.css
228 +
│           └── js/
229 +
│               ├── theme.js         # Dark/Light toggle + TOC generator
230 +
│               └── search.js        # Client-side full-text search
218 231
├── internal/
219 232
│   ├── config/config.go             # YAML config loader
220 233
│   ├── content/
221 234
│   │   ├── post.go                  # Post struct + FlexTime + Tags/Categories
222 235
│   │   ├── parser.go                # Markdown + frontmatter parser
223 236
│   │   └── page.go                  # Static pages parser
224 237
│   ├── server/server.go             # HTTP server
225 238
│   ├── generator/
226 239
│   │   ├── generator.go             # Static site generator
227 240
│   │   └── search.go                # Search index generator (JSON)
228 241
│   └── templates/
229 -
│       ├── render.go                # Template engine + functions
230 -
│       ├── rss.go                   # RSS feed generator
231 -
│       ├── base.html                # Base layout + navbar + search
232 -
│       ├── home.html                # Homepage + pagination
233 -
│       ├── post.html                # Single post + prev/next navigation
234 -
│       ├── page.html                # Static page
235 -
│       ├── tags.html                # Tag overview
236 -
│       ├── tag.html                 # Tag page
237 -
│       ├── categories.html          # Category overview
238 -
│       └── category.html            # Category page
242 +
│       ├── render.go                # Template engine + functions (loads the theme)
243 +
│       └── rss.go                   # RSS feed generator
239 244
└── output/                          # Generated static files
240 245
```
241 246
242 247
### Technology Stack
243 248
244 249
| Component | Technology |
245 250
|-----------|------------|
246 251
| Language | Go (standard library + minimal dependencies) |
247 252
| HTTP Server | `net/http` (Go standard library) |
248 -
| Templates | `html/template` with `embed.FS` |
253 +
| Templates | `html/template`, loaded from `themes/<name>/templates/` at runtime |
249 254
| Markdown | Goldmark + GFM + Emoji + Chroma |
250 255
| Configuration | YAML via `gopkg.in/yaml.v3` |
251 256
| Syntax Highlighting | Chroma (Dracula theme) |
252 257
| Fonts | Inter + JetBrains Mono (Google Fonts) |
253 258
| CSS | Vanilla CSS with custom properties |
254 259
| JavaScript | Vanilla JS — theme toggle, search, TOC (no framework) |
255 260
256 261
### Dependencies
257 262
258 263
QuillDrop intentionally has minimal dependencies — **no web framework**, **no CSS framework**, **no JS framework**:
259 264
260 265
- `github.com/yuin/goldmark` — Markdown parser (CommonMark compliant)
261 266
- `github.com/yuin/goldmark-emoji` — Emoji shortcodes
262 267
- `github.com/yuin/goldmark-highlighting/v2` — Syntax highlighting
263 268
- `github.com/alecthomas/chroma/v2` — Syntax highlighting engine
264 269
- `gopkg.in/yaml.v3` — YAML parser
265 270
266 -
### Embedded Assets
271 +
### Themes
267 272
268 -
All HTML templates are embedded directly into the binary via Go's `//go:embed` directive. This means:
273 +
Templates and their assets live outside the binary, in `themes/<name>/`. The same
274 +
QuillDrop binary can therefore drive any number of websites, each with its own look:
269 275
270 -
- **Single binary** — No external template files needed
271 -
- **Fast startup** — No filesystem access for templates
272 -
- **Easy deployment** — One binary + config + content = done
276 +
```
277 +
themes/
278 +
├── default/
279 +
│   ├── templates/       # required: base, home, post, page, tags, tag, categories, category
280 +
│   └── static/          # optional: CSS, JS, theme images
281 +
└── newdesign/
282 +
    ├── templates/
283 +
    └── static/
284 +
```
285 +
286 +
The active theme is selected in `config.yaml`:
287 +
288 +
```yaml
289 +
themesDir: "themes"   # default
290 +
theme: "default"      # reads from themes/default/
291 +
```
292 +
293 +
Or temporarily via flag, e.g. to preview a redesign:
294 +
295 +
```bash
296 +
./quilldrop serve -theme newdesign
297 +
./quilldrop generate -theme newdesign
298 +
```
299 +
300 +
**Creating a new theme:**
301 +
302 +
```bash
303 +
cp -r themes/default themes/newdesign      # or: make new-theme NAME=newdesign
304 +
# edit themes/newdesign/templates/*.html and themes/newdesign/static/css/style.css
305 +
./quilldrop serve -theme newdesign -dev
306 +
```
307 +
308 +
**Live reload:** With `-dev` the templates are re-read from the theme directory on
309 +
every request — changes to HTML, CSS and JS become visible after a browser reload,
310 +
without restarting the server (dev mode also sends `Cache-Control: no-store` so the
311 +
browser does not cache assets). A broken template returns a 500 instead of a
312 +
half-rendered page; the exact error with file and line is written to the server log.
313 +
Without `-dev` templates are parsed once at startup, as before. New or changed
314 +
Markdown files still require a restart.
315 +
316 +
A theme must provide all eight templates (`base.html`, `home.html`, `post.html`,
317 +
`page.html`, `tags.html`, `tag.html`, `categories.html`, `category.html`);
318 +
QuillDrop aborts with a clear error if one is missing or the theme does not exist.
319 +
320 +
**Static assets** are merged: `themes/<name>/static/` is copied first, then the
321 +
site's own `static/` on top — so site files (e.g. `static/icons/favicon.ico`)
322 +
override theme files of the same name. Design belongs to the theme (CSS, JS),
323 +
site-specific material stays in `static/` (icons, images). Both are served under
324 +
`/static/`; `static/images/` and `static/videos/` are additionally published at
325 +
`/images/` and `/videos/`.
273 326
274 327
## Configuration
275 328
276 329
All configuration is done via a single `config.yaml`:
277 330
278 331
```yaml
279 332
title: "My Blog"
280 333
description: "Tech Blog - DevOps, Kubernetes, Self-Hosted"
281 334
author: "Jane Doe"
282 335
baseURL: "https://my-blog.com"
283 336
port: 8080
284 337
postsPerPage: 5
285 338
contentDir: "content"
286 339
sitesDir: "sites"
340 +
staticDir: "static"
287 341
outputDir: "output"
342 +
themesDir: "themes"
343 +
theme: "default"
288 344
289 345
menu:
290 346
  - label: "Home"
291 347
    url: "/"
292 348
  - label: "Tags"
293 349
    url: "/tags"
294 350
  - label: "About"
295 351
    url: "/sites/about"
296 352
```
297 353
298 354
| Option | Default | Description |
299 355
|--------|---------|-------------|
300 356
| `title` | — | Website title |
301 357
| `description` | — | Description (meta tag + hero) |
302 358
| `author` | — | Website author |
303 359
| `baseURL` | — | Base URL for RSS and absolute links |
304 360
| `port` | `8080` | Port for the dynamic server |
305 361
| `postsPerPage` | `5` | Number of posts per page |
306 362
| `contentDir` | `content` | Directory for blog posts |
307 363
| `sitesDir` | `sites` | Directory for static pages |
364 +
| `staticDir` | `static` | Directory for site assets |
308 365
| `outputDir` | `output` | Output directory for static generation |
366 +
| `themesDir` | `themes` | Directory containing all themes |
367 +
| `theme` | `default` | Active theme, read from `<themesDir>/<theme>/` (override: `-theme`) |
309 368
| `menu` | `[]` | Navigation menu with optional submenus |
310 369
311 370
## Quick Start
312 371
313 372
### Installation
314 373
315 374
```bash
316 375
# Clone the repository
317 376
git clone https://github.com/ruedigerp/quilldrop.git
318 377
cd quilldrop
@@ -349,20 +408,23 @@ This is my first post with **QuillDrop**.
349 408
```
350 409
351 410
### Local Preview
352 411
353 412
```bash
354 413
# Start the dynamic server
355 414
./quilldrop serve
356 415
357 416
# Or run directly with Go
358 417
go run . serve
418 +
419 +
# With template live reload (theme development)
420 +
./quilldrop serve -dev
359 421
```
360 422
361 423
Then open in the browser: [http://localhost:8080](http://localhost:8080)
362 424
363 425
### Generate Static Site
364 426
365 427
```bash
366 428
# Generate HTML files
367 429
./quilldrop generate
368 430
geändert config.yaml
+6 −1 Datei ansehen
@@ -1,20 +1,25 @@
1 1
title: "Küpper Blog"
2 2
description: "Tech Blog - DevOps, Kubernetes, Self-Hosted"
3 3
author: "Rüdiger Küpper"
4 4
baseURL: "https://blog.kuepper.nrw"
5 -
port: 8080
5 +
port: 8180
6 6
postsPerPage: 5
7 7
contentDir: "content"
8 8
sitesDir: "sites"
9 +
staticDir: "static"
9 10
outputDir: "output"
10 11
12 +
# Theme: read from <themesDir>/<theme>/
13 +
themesDir: "themes"
14 +
theme: "ehc"
15 +
11 16
menu:
12 17
  - label: "Home"
13 18
    url: "/"
14 19
  - label: "Projekte"
15 20
    children:
16 21
      # - label: "VM-Manager"
17 22
      #   url: "/sites/projects/vm-manager/"
18 23
      - label: "VM-Tracker"
19 24
        url: "/sites/projects/vm-tracker/"
20 25
      - label: "QuillDrop"
geändert internal/config/config.go
+57 −0 Datei ansehen
@@ -1,44 +1,101 @@
1 1
package config
2 2
3 3
import (
4 4
	"os"
5 +
	"path/filepath"
5 6
6 7
	"gopkg.in/yaml.v3"
7 8
)
8 9
9 10
type MenuItem struct {
10 11
	Label    string     `yaml:"label"`
11 12
	URL      string     `yaml:"url,omitempty"`
12 13
	Children []MenuItem `yaml:"children,omitempty"`
13 14
}
14 15
16 +
// LLMsConfig toggles generation/serving of the llms.txt convention files.
17 +
// Both default to true so behaviour without the block stays unchanged.
18 +
type LLMsConfig struct {
19 +
	Enabled *bool `yaml:"enabled,omitempty"` // llms.txt
20 +
	Full    *bool `yaml:"full,omitempty"`    // llms-full.txt
21 +
}
22 +
23 +
// EnabledOrDefault returns whether llms.txt should be produced (default: true).
24 +
func (l LLMsConfig) EnabledOrDefault() bool {
25 +
	if l.Enabled == nil {
26 +
		return true
27 +
	}
28 +
	return *l.Enabled
29 +
}
30 +
31 +
// FullOrDefault returns whether llms-full.txt should be produced (default: true).
32 +
func (l LLMsConfig) FullOrDefault() bool {
33 +
	if l.Full == nil {
34 +
		return true
35 +
	}
36 +
	return *l.Full
37 +
}
38 +
15 39
type Config struct {
16 40
	Title        string     `yaml:"title"`
17 41
	Description  string     `yaml:"description"`
18 42
	Author       string     `yaml:"author"`
19 43
	BaseURL      string     `yaml:"baseURL"`
20 44
	Port         int        `yaml:"port"`
21 45
	PostsPerPage int        `yaml:"postsPerPage"`
22 46
	ContentDir   string     `yaml:"contentDir"`
23 47
	SitesDir     string     `yaml:"sitesDir"`
48 +
	StaticDir    string     `yaml:"staticDir"`
24 49
	OutputDir    string     `yaml:"outputDir"`
50 +
	ThemesDir    string     `yaml:"themesDir"`
51 +
	Theme        string     `yaml:"theme"`
25 52
	Menu         []MenuItem `yaml:"menu"`
53 +
	LLMs         LLMsConfig `yaml:"llms"`
54 +
}
55 +
56 +
// ThemeDir returns the directory of the active theme, e.g. "themes/default".
57 +
func (c *Config) ThemeDir() string {
58 +
	return filepath.Join(c.ThemesDir, c.Theme)
59 +
}
60 +
61 +
// ThemeTemplatesDir returns the template directory of the active theme.
62 +
func (c *Config) ThemeTemplatesDir() string {
63 +
	return filepath.Join(c.ThemeDir(), "templates")
64 +
}
65 +
66 +
// ThemeStaticDir returns the static asset directory of the active theme.
67 +
// The directory is optional; a theme may ship without own assets.
68 +
func (c *Config) ThemeStaticDir() string {
69 +
	return filepath.Join(c.ThemeDir(), "static")
26 70
}
27 71
28 72
func Load(path string) (*Config, error) {
29 73
	data, err := os.ReadFile(path)
30 74
	if err != nil {
31 75
		return nil, err
32 76
	}
33 77
	cfg := &Config{
34 78
		Port:         8080,
35 79
		PostsPerPage: 5,
36 80
		ContentDir:   "content",
37 81
		SitesDir:     "sites",
82 +
		StaticDir:    "static",
38 83
		OutputDir:    "output",
84 +
		ThemesDir:    "themes",
85 +
		Theme:        "default",
39 86
	}
40 87
	if err := yaml.Unmarshal(data, cfg); err != nil {
41 88
		return nil, err
42 89
	}
90 +
	// Empty values in config.yaml must not override the defaults.
91 +
	if cfg.StaticDir == "" {
92 +
		cfg.StaticDir = "static"
93 +
	}
94 +
	if cfg.ThemesDir == "" {
95 +
		cfg.ThemesDir = "themes"
96 +
	}
97 +
	if cfg.Theme == "" {
98 +
		cfg.Theme = "default"
99 +
	}
43 100
	return cfg, nil
44 101
}
geändert internal/generator/generator.go
+14 −4 Datei ansehen
@@ -7,23 +7,24 @@ import (
7 7
	"os"
8 8
	"path/filepath"
9 9
	"strings"
10 10
11 11
	"github.com/ruedigerp/newblog/internal/config"
12 12
	"github.com/ruedigerp/newblog/internal/content"
13 13
	"github.com/ruedigerp/newblog/internal/templates"
14 14
)
15 15
16 16
func Generate(cfg *config.Config, posts []*content.Post, pages []*content.Page) {
17 -
	if err := templates.Init(); err != nil {
17 +
	if err := templates.Init(cfg.ThemeDir()); err != nil {
18 18
		log.Fatalf("Failed to init templates: %v", err)
19 19
	}
20 +
	log.Printf("Using theme %q from %s", cfg.Theme, cfg.ThemeDir())
20 21
21 22
	out := cfg.OutputDir
22 23
23 24
	// Clean and recreate output directory
24 25
	os.RemoveAll(out)
25 26
	os.MkdirAll(out, 0755)
26 27
27 28
	site := templates.SiteData{
28 29
		Title:       cfg.Title,
29 30
		Description: cfg.Description,
@@ -137,26 +138,35 @@ func Generate(cfg *config.Config, posts []*content.Post, pages []*content.Page)
137 138
	if rssCount > len(posts) {
138 139
		rssCount = len(posts)
139 140
	}
140 141
	writeTemplate(filepath.Join(out, "index.xml"), func(f *os.File) error {
141 142
		return templates.RenderRSS(f, site, posts[:rssCount])
142 143
	})
143 144
144 145
	// 9. Search index
145 146
	GenerateSearchIndex(posts, filepath.Join(out, "search-index.json"))
146 147
147 -
	// 10. Copy static assets (skip images/ subdirectory — handled separately)
148 -
	copyStaticDir("static", filepath.Join(out, "static"), []string{"images", "videos"})
148 +
	// 9b. llms.txt / llms-full.txt for LLM ingestion (https://llmstxt.org/)
149 +
	GenerateLLMsFiles(cfg, posts, pages, out)
150 +
151 +
	// 10. Copy static assets: theme assets first, site assets afterwards so
152 +
	// files in the site's static/ override the ones shipped with the theme.
153 +
	// (skip images/ subdirectory — handled separately)
154 +
	// Theme assets are copied as-is: a theme's own images belong to /static/images/.
155 +
	if _, err := os.Stat(cfg.ThemeStaticDir()); err == nil {
156 +
		copyStaticDir(cfg.ThemeStaticDir(), filepath.Join(out, "static"), nil)
157 +
	}
158 +
	copyStaticDir(cfg.StaticDir, filepath.Join(out, "static"), []string{"images", "videos"})
149 159
150 160
	// 11. Copy images + videos to root /images/ and /videos/ (cover paths use /images/...)
151 161
	for _, dir := range []string{"images", "videos"} {
152 -
		src := filepath.Join("static", dir)
162 +
		src := filepath.Join(cfg.StaticDir, dir)
153 163
		dst := filepath.Join(out, dir)
154 164
		if _, err := os.Stat(src); err == nil {
155 165
			copyStaticDir(src, dst, nil)
156 166
		}
157 167
	}
158 168
159 169
	log.Printf("Generated %d posts, %d pages, %d tag pages, %d category pages, RSS feed into %s/",
160 170
		len(posts), len(pages), len(tagMap), len(catMap), out)
161 171
}
162 172
hinzugefügt internal/generator/llms.go
+159 −0 Datei ansehen
@@ -0,0 +1,159 @@
1 +
package generator
2 +
3 +
import (
4 +
	"fmt"
5 +
	"io"
6 +
	"log"
7 +
	"os"
8 +
	"strings"
9 +
10 +
	"github.com/ruedigerp/newblog/internal/config"
11 +
	"github.com/ruedigerp/newblog/internal/content"
12 +
)
13 +
14 +
// RenderLLMsTxt writes an llms.txt index pointing LLMs at the site's resources.
15 +
// Follows the proposal at https://llmstxt.org/ — H1 title, blockquote summary,
16 +
// then H2 sections with markdown link lists.
17 +
func RenderLLMsTxt(w io.Writer, cfg *config.Config, posts []*content.Post, pages []*content.Page) error {
18 +
	bw := &errWriter{w: w}
19 +
20 +
	bw.printf("# %s\n\n", cfg.Title)
21 +
	bw.printf("> %s\n\n", cfg.Description)
22 +
	if cfg.Author != "" {
23 +
		bw.printf("Author: %s\n", cfg.Author)
24 +
	}
25 +
	bw.printf("Site: %s\n\n", cfg.BaseURL)
26 +
	bw.printf("Diese Datei folgt der llms.txt-Konvention (https://llmstxt.org/) und listet "+
27 +
		"alle Inhalte des Blogs, damit Sprachmodelle sie effizient finden und einordnen können. "+
28 +
		"Die vollständigen Texte liegen unter %s/llms-full.txt.\n\n", strings.TrimRight(cfg.BaseURL, "/"))
29 +
30 +
	// Blog posts
31 +
	bw.printf("## Blogposts\n\n")
32 +
	for _, p := range posts {
33 +
		url := strings.TrimRight(cfg.BaseURL, "/") + "/posts/" + p.Slug + "/"
34 +
		preview := strings.TrimSpace(p.GetPreview())
35 +
		date := p.Date.Format("2006-01-02")
36 +
		if preview != "" {
37 +
			bw.printf("- [%s](%s) — %s (%s)\n", p.Title, url, preview, date)
38 +
		} else {
39 +
			bw.printf("- [%s](%s) (%s)\n", p.Title, url, date)
40 +
		}
41 +
	}
42 +
	bw.printf("\n")
43 +
44 +
	// Static pages
45 +
	if len(pages) > 0 {
46 +
		bw.printf("## Seiten\n\n")
47 +
		for _, pg := range pages {
48 +
			url := strings.TrimRight(cfg.BaseURL, "/") + "/sites/" + pg.Slug + "/"
49 +
			if pg.Description != "" {
50 +
				bw.printf("- [%s](%s) — %s\n", pg.Title, url, pg.Description)
51 +
			} else {
52 +
				bw.printf("- [%s](%s)\n", pg.Title, url)
53 +
			}
54 +
		}
55 +
		bw.printf("\n")
56 +
	}
57 +
58 +
	// Optional resources
59 +
	base := strings.TrimRight(cfg.BaseURL, "/")
60 +
	bw.printf("## Optional\n\n")
61 +
	bw.printf("- [Tags](%s/tags/) — Übersicht aller Tags\n", base)
62 +
	bw.printf("- [Kategorien](%s/categories/) — Übersicht aller Kategorien\n", base)
63 +
	bw.printf("- [RSS Feed](%s/index.xml) — RSS-Feed mit den neuesten Posts\n", base)
64 +
	if cfg.LLMs.FullOrDefault() {
65 +
		bw.printf("- [Volltext](%s/llms-full.txt) — Alle Blogposts als Markdown in einer Datei\n", base)
66 +
	}
67 +
68 +
	return bw.err
69 +
}
70 +
71 +
// RenderLLMsFullTxt writes llms-full.txt — every post's full markdown content
72 +
// concatenated with metadata headers, suitable for LLM ingestion.
73 +
func RenderLLMsFullTxt(w io.Writer, cfg *config.Config, posts []*content.Post) error {
74 +
	bw := &errWriter{w: w}
75 +
76 +
	bw.printf("# %s\n\n", cfg.Title)
77 +
	bw.printf("> %s\n\n", cfg.Description)
78 +
	if cfg.Author != "" {
79 +
		bw.printf("Author: %s\n", cfg.Author)
80 +
	}
81 +
	bw.printf("Site: %s\n\n", cfg.BaseURL)
82 +
	if cfg.LLMs.EnabledOrDefault() {
83 +
		bw.printf("Dies ist der konsolidierte Volltext aller Blogposts (neueste zuerst). "+
84 +
			"Eine knappe Übersicht steht unter %s/llms.txt.\n\n", strings.TrimRight(cfg.BaseURL, "/"))
85 +
	} else {
86 +
		bw.printf("Dies ist der konsolidierte Volltext aller Blogposts (neueste zuerst).\n\n")
87 +
	}
88 +
89 +
	base := strings.TrimRight(cfg.BaseURL, "/")
90 +
	for i, p := range posts {
91 +
		if i > 0 {
92 +
			bw.printf("\n---\n\n")
93 +
		}
94 +
		url := base + "/posts/" + p.Slug + "/"
95 +
		bw.printf("## %s\n\n", p.Title)
96 +
		bw.printf("- URL: %s\n", url)
97 +
		bw.printf("- Datum: %s\n", p.Date.Format("2006-01-02"))
98 +
		if !p.Update.Time.IsZero() {
99 +
			bw.printf("- Aktualisiert: %s\n", p.Update.Format("2006-01-02"))
100 +
		}
101 +
		if p.Author != "" {
102 +
			bw.printf("- Autor: %s\n", p.Author)
103 +
		}
104 +
		if len(p.Tags) > 0 {
105 +
			bw.printf("- Tags: %s\n", strings.Join(p.Tags, ", "))
106 +
		}
107 +
		if len(p.Categories) > 0 {
108 +
			bw.printf("- Kategorien: %s\n", strings.Join(p.Categories, ", "))
109 +
		}
110 +
		bw.printf("\n")
111 +
		// Body is the preprocessed markdown (Hugo shortcodes already stripped).
112 +
		body := strings.TrimSpace(p.Content)
113 +
		bw.printf("%s\n", body)
114 +
	}
115 +
116 +
	return bw.err
117 +
}
118 +
119 +
// errWriter swallows repeated writes after the first error so callers don't
120 +
// have to check every Fprintf.
121 +
type errWriter struct {
122 +
	w   io.Writer
123 +
	err error
124 +
}
125 +
126 +
func (e *errWriter) printf(format string, args ...interface{}) {
127 +
	if e.err != nil {
128 +
		return
129 +
	}
130 +
	_, e.err = fmt.Fprintf(e.w, format, args...)
131 +
}
132 +
133 +
// GenerateLLMsFiles writes llms.txt and llms-full.txt into outDir,
134 +
// honoring cfg.LLMs.Enabled / cfg.LLMs.Full (both default to true).
135 +
func GenerateLLMsFiles(cfg *config.Config, posts []*content.Post, pages []*content.Page, outDir string) {
136 +
	if cfg.LLMs.EnabledOrDefault() {
137 +
		if err := writeFile(outDir+"/llms.txt", func(f *os.File) error {
138 +
			return RenderLLMsTxt(f, cfg, posts, pages)
139 +
		}); err != nil {
140 +
			log.Printf("Error writing llms.txt: %v", err)
141 +
		}
142 +
	}
143 +
	if cfg.LLMs.FullOrDefault() {
144 +
		if err := writeFile(outDir+"/llms-full.txt", func(f *os.File) error {
145 +
			return RenderLLMsFullTxt(f, cfg, posts)
146 +
		}); err != nil {
147 +
			log.Printf("Error writing llms-full.txt: %v", err)
148 +
		}
149 +
	}
150 +
}
151 +
152 +
func writeFile(path string, render func(f *os.File) error) error {
153 +
	f, err := os.Create(path)
154 +
	if err != nil {
155 +
		return err
156 +
	}
157 +
	defer f.Close()
158 +
	return render(f)
159 +
}
geändert internal/server/server.go
+70 −5 Datei ansehen
@@ -1,29 +1,34 @@
1 1
package server
2 2
3 3
import (
4 4
	"encoding/json"
5 5
	"fmt"
6 6
	"log"
7 7
	"net/http"
8 +
	"os"
9 +
	"path"
10 +
	"path/filepath"
8 11
	"strconv"
9 12
	"strings"
10 13
11 14
	"github.com/ruedigerp/newblog/internal/config"
12 15
	"github.com/ruedigerp/newblog/internal/content"
16 +
	"github.com/ruedigerp/newblog/internal/generator"
13 17
	"github.com/ruedigerp/newblog/internal/templates"
14 18
)
15 19
16 20
func Start(cfg *config.Config, posts []*content.Post, pages []*content.Page) {
17 -
	if err := templates.Init(); err != nil {
21 +
	if err := templates.Init(cfg.ThemeDir()); err != nil {
18 22
		log.Fatalf("Failed to init templates: %v", err)
19 23
	}
24 +
	log.Printf("Using theme %q from %s", cfg.Theme, cfg.ThemeDir())
20 25
21 26
	tagMap := content.CollectTags(posts)
22 27
	catMap := content.CollectCategories(posts)
23 28
	postMap := make(map[string]*content.Post)
24 29
	postIndex := make(map[string]int)
25 30
	for i, p := range posts {
26 31
		postMap[p.Slug] = p
27 32
		postIndex[p.Slug] = i
28 33
	}
29 34
	pageMap := make(map[string]*content.Page)
@@ -34,39 +39,64 @@ func Start(cfg *config.Config, posts []*content.Post, pages []*content.Page) {
34 39
	site := templates.SiteData{
35 40
		Title:       cfg.Title,
36 41
		Description: cfg.Description,
37 42
		Author:      cfg.Author,
38 43
		BaseURL:     cfg.BaseURL,
39 44
		Menu:        cfg.Menu,
40 45
	}
41 46
42 47
	mux := http.NewServeMux()
43 48
44 -
	// Static files
45 -
	mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
49 +
	// Static files: the site's static/ wins, the theme's static/ is the fallback.
50 +
	// Mirrors the merge order used by the generator.
51 +
	mux.Handle("/static/", http.StripPrefix("/static/",
52 +
		staticHandler(cfg.StaticDir, cfg.ThemeStaticDir())))
46 53
47 54
	// Images (served from static/images, so /images/... paths in posts work directly)
48 -
	mux.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir("static/images"))))
55 +
	mux.Handle("/images/", http.StripPrefix("/images/",
56 +
		http.FileServer(http.Dir(filepath.Join(cfg.StaticDir, "images")))))
49 57
50 58
	// RSS Feed
51 59
	mux.HandleFunc("/index.xml", func(w http.ResponseWriter, r *http.Request) {
52 60
		w.Header().Set("Content-Type", "application/rss+xml; charset=utf-8")
53 61
		rssCount := 20
54 62
		if rssCount > len(posts) {
55 63
			rssCount = len(posts)
56 64
		}
57 65
		if err := templates.RenderRSS(w, site, posts[:rssCount]); err != nil {
58 66
			log.Printf("Error rendering RSS: %v", err)
59 67
			http.Error(w, "Internal Server Error", 500)
60 68
		}
61 69
	})
62 70
71 +
	// llms.txt — concise index for LLMs (https://llmstxt.org/)
72 +
	if cfg.LLMs.EnabledOrDefault() {
73 +
		mux.HandleFunc("/llms.txt", func(w http.ResponseWriter, r *http.Request) {
74 +
			w.Header().Set("Content-Type", "text/markdown; charset=utf-8")
75 +
			if err := generator.RenderLLMsTxt(w, cfg, posts, pages); err != nil {
76 +
				log.Printf("Error rendering llms.txt: %v", err)
77 +
				http.Error(w, "Internal Server Error", 500)
78 +
			}
79 +
		})
80 +
	}
81 +
82 +
	// llms-full.txt — full markdown of every post
83 +
	if cfg.LLMs.FullOrDefault() {
84 +
		mux.HandleFunc("/llms-full.txt", func(w http.ResponseWriter, r *http.Request) {
85 +
			w.Header().Set("Content-Type", "text/markdown; charset=utf-8")
86 +
			if err := generator.RenderLLMsFullTxt(w, cfg, posts); err != nil {
87 +
				log.Printf("Error rendering llms-full.txt: %v", err)
88 +
				http.Error(w, "Internal Server Error", 500)
89 +
			}
90 +
		})
91 +
	}
92 +
63 93
	// Search index
64 94
	mux.HandleFunc("/search-index.json", func(w http.ResponseWriter, r *http.Request) {
65 95
		w.Header().Set("Content-Type", "application/json; charset=utf-8")
66 96
67 97
		months := []string{
68 98
			"", "Januar", "Februar", "März", "April", "Mai", "Juni",
69 99
			"Juli", "August", "September", "Oktober", "November", "Dezember",
70 100
		}
71 101
72 102
		type searchEntry struct {
@@ -249,23 +279,58 @@ func Start(cfg *config.Config, posts []*content.Post, pages []*content.Page) {
249 279
	mux.HandleFunc("/categories/", func(w http.ResponseWriter, r *http.Request) {
250 280
		cat := strings.TrimPrefix(r.URL.Path, "/categories/")
251 281
		cat = strings.TrimSuffix(cat, "/")
252 282
		if cat == "" {
253 283
			renderCategoriesIndex(w)
254 284
			return
255 285
		}
256 286
		handleCategory(w, r, site, catMap)
257 287
	})
258 288
289 +
	var handler http.Handler = mux
290 +
	if templates.DevMode() {
291 +
		// Templates are re-parsed per request; keep the browser from caching
292 +
		// the theme's CSS/JS so edits show up on reload.
293 +
		handler = noCache(mux)
294 +
		log.Printf("Dev mode: templates in %s are reloaded on every request", cfg.ThemeTemplatesDir())
295 +
	}
296 +
259 297
	addr := fmt.Sprintf(":%d", cfg.Port)
260 298
	log.Printf("Blog server starting on http://localhost%s", addr)
261 -
	log.Fatal(http.ListenAndServe(addr, mux))
299 +
	log.Fatal(http.ListenAndServe(addr, handler))
300 +
}
301 +
302 +
// noCache disables browser caching — used in dev mode only.
303 +
func noCache(next http.Handler) http.Handler {
304 +
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
305 +
		w.Header().Set("Cache-Control", "no-store, max-age=0")
306 +
		next.ServeHTTP(w, r)
307 +
	})
308 +
}
309 +
310 +
// staticHandler serves static assets from several directories: the first
311 +
// directory that contains the requested file wins.
312 +
func staticHandler(dirs ...string) http.Handler {
313 +
	servers := make([]http.Handler, len(dirs))
314 +
	for i, d := range dirs {
315 +
		servers[i] = http.FileServer(http.Dir(d))
316 +
	}
317 +
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
318 +
		rel := filepath.FromSlash(path.Clean("/" + r.URL.Path))
319 +
		for i, d := range dirs {
320 +
			if info, err := os.Stat(filepath.Join(d, rel)); err == nil && !info.IsDir() {
321 +
				servers[i].ServeHTTP(w, r)
322 +
				return
323 +
			}
324 +
		}
325 +
		http.NotFound(w, r)
326 +
	})
262 327
}
263 328
264 329
func handleTag(w http.ResponseWriter, r *http.Request, site templates.SiteData, tagMap map[string][]*content.Post) {
265 330
	tag := strings.TrimPrefix(r.URL.Path, "/tags/")
266 331
	tag = strings.TrimSuffix(tag, "/")
267 332
	if tag == "" {
268 333
		http.Redirect(w, r, "/tags", http.StatusFound)
269 334
		return
270 335
	}
271 336
	for t, tagPosts := range tagMap {
geändert internal/templates/render.go
+94 −28 Datei ansehen
@@ -1,27 +1,26 @@
1 1
package templates
2 2
3 3
import (
4 -
	"embed"
4 +
	"bytes"
5 5
	"fmt"
6 6
	"html/template"
7 7
	"io"
8 +
	"os"
9 +
	"path/filepath"
8 10
	"strings"
9 11
	"time"
10 12
11 13
	"github.com/ruedigerp/newblog/internal/config"
12 14
	"github.com/ruedigerp/newblog/internal/content"
13 15
)
14 16
15 -
//go:embed *.html
16 -
var templateFS embed.FS
17 -
18 17
type SiteData struct {
19 18
	Title       string
20 19
	Description string
21 20
	Author      string
22 21
	BaseURL     string
23 22
	Menu        []config.MenuItem
24 23
}
25 24
26 25
type HomeData struct {
27 26
	Site       SiteData
@@ -135,83 +134,150 @@ var funcMap = template.FuncMap{
135 134
			}
136 135
		}
137 136
		return result
138 137
	},
139 138
	"isEllipsis": func(n int) bool {
140 139
		return n == -1
141 140
	},
142 141
}
143 142
144 143
var (
145 -
	homeTmpl       *template.Template
146 -
	postTmpl       *template.Template
147 -
	tagsTmpl       *template.Template
148 -
	tagTmpl        *template.Template
149 -
	categoriesTmpl *template.Template
150 -
	categoryTmpl   *template.Template
151 -
	pageTmpl       *template.Template
144 +
	homeTmpl       *view
145 +
	postTmpl       *view
146 +
	tagsTmpl       *view
147 +
	tagTmpl        *view
148 +
	categoriesTmpl *view
149 +
	categoryTmpl   *view
150 +
	pageTmpl       *view
152 151
)
153 152
153 +
// templateDir holds the directory the templates of the active theme were
154 +
// loaded from (e.g. "themes/default/templates").
155 +
var templateDir string
156 +
157 +
// devMode re-parses templates on every render, so theme edits become visible
158 +
// without restarting the server.
159 +
var devMode bool
160 +
161 +
// SetDevMode enables or disables template live reload. Must be called before
162 +
// serving requests.
163 +
func SetDevMode(enabled bool) {
164 +
	devMode = enabled
165 +
}
166 +
167 +
// DevMode reports whether template live reload is enabled.
168 +
func DevMode() bool {
169 +
	return devMode
170 +
}
171 +
172 +
// view is a page template together with the theme files it was built from,
173 +
// so it can be re-parsed on demand in dev mode.
174 +
type view struct {
175 +
	files []string
176 +
	tmpl  *template.Template
177 +
}
178 +
179 +
func newView(files ...string) (*view, error) {
180 +
	tmpl, err := parseTemplate(files...)
181 +
	if err != nil {
182 +
		return nil, err
183 +
	}
184 +
	return &view{files: files, tmpl: tmpl}, nil
185 +
}
186 +
187 +
func (v *view) execute(w io.Writer, data any) error {
188 +
	if !devMode {
189 +
		return v.tmpl.ExecuteTemplate(w, "base", data)
190 +
	}
191 +
	// Live reload: parse the theme files again and render into a buffer first,
192 +
	// so a broken template does not emit half a page.
193 +
	tmpl, err := parseTemplate(v.files...)
194 +
	if err != nil {
195 +
		return err
196 +
	}
197 +
	var buf bytes.Buffer
198 +
	if err := tmpl.ExecuteTemplate(&buf, "base", data); err != nil {
199 +
		return err
200 +
	}
201 +
	_, err = w.Write(buf.Bytes())
202 +
	return err
203 +
}
204 +
154 205
func parseTemplate(files ...string) (*template.Template, error) {
155 -
	return template.New("").Funcs(funcMap).ParseFS(templateFS, files...)
206 +
	paths := make([]string, 0, len(files))
207 +
	for _, f := range files {
208 +
		path := filepath.Join(templateDir, f)
209 +
		if _, err := os.Stat(path); err != nil {
210 +
			return nil, fmt.Errorf("missing template %s in theme: %w", f, err)
211 +
		}
212 +
		paths = append(paths, path)
213 +
	}
214 +
	return template.New("").Funcs(funcMap).ParseFiles(paths...)
156 215
}
157 216
158 -
func Init() error {
159 -
	var err error
160 -
	homeTmpl, err = parseTemplate("base.html", "home.html")
217 +
// Init loads all templates of the theme located in themeDir
218 +
// (e.g. "themes/default"). The templates are expected in themeDir/templates.
219 +
func Init(themeDir string) error {
220 +
	templateDir = filepath.Join(themeDir, "templates")
221 +
	info, err := os.Stat(templateDir)
222 +
	if err != nil || !info.IsDir() {
223 +
		return fmt.Errorf("theme templates not found in %s (check 'theme' and 'themesDir' in config.yaml)", templateDir)
224 +
	}
225 +
226 +
	homeTmpl, err = newView("base.html", "home.html")
161 227
	if err != nil {
162 228
		return fmt.Errorf("home template: %w", err)
163 229
	}
164 -
	postTmpl, err = parseTemplate("base.html", "post.html")
230 +
	postTmpl, err = newView("base.html", "post.html")
165 231
	if err != nil {
166 232
		return fmt.Errorf("post template: %w", err)
167 233
	}
168 -
	tagsTmpl, err = parseTemplate("base.html", "tags.html")
234 +
	tagsTmpl, err = newView("base.html", "tags.html")
169 235
	if err != nil {
170 236
		return fmt.Errorf("tags template: %w", err)
171 237
	}
172 -
	tagTmpl, err = parseTemplate("base.html", "tag.html")
238 +
	tagTmpl, err = newView("base.html", "tag.html")
173 239
	if err != nil {
174 240
		return fmt.Errorf("tag template: %w", err)
175 241
	}
176 -
	categoriesTmpl, err = parseTemplate("base.html", "categories.html")
242 +
	categoriesTmpl, err = newView("base.html", "categories.html")
177 243
	if err != nil {
178 244
		return fmt.Errorf("categories template: %w", err)
179 245
	}
180 -
	categoryTmpl, err = parseTemplate("base.html", "category.html")
246 +
	categoryTmpl, err = newView("base.html", "category.html")
181 247
	if err != nil {
182 248
		return fmt.Errorf("category template: %w", err)
183 249
	}
184 -
	pageTmpl, err = parseTemplate("base.html", "page.html")
250 +
	pageTmpl, err = newView("base.html", "page.html")
185 251
	if err != nil {
186 252
		return fmt.Errorf("page template: %w", err)
187 253
	}
188 254
	return nil
189 255
}
190 256
191 257
func RenderHome(w io.Writer, data HomeData) error {
192 -
	return homeTmpl.ExecuteTemplate(w, "base", data)
258 +
	return homeTmpl.execute(w, data)
193 259
}
194 260
195 261
func RenderPost(w io.Writer, data PostData) error {
196 -
	return postTmpl.ExecuteTemplate(w, "base", data)
262 +
	return postTmpl.execute(w, data)
197 263
}
198 264
199 265
func RenderTags(w io.Writer, data TagsData) error {
200 -
	return tagsTmpl.ExecuteTemplate(w, "base", data)
266 +
	return tagsTmpl.execute(w, data)
201 267
}
202 268
203 269
func RenderTag(w io.Writer, data TagData) error {
204 -
	return tagTmpl.ExecuteTemplate(w, "base", data)
270 +
	return tagTmpl.execute(w, data)
205 271
}
206 272
207 273
func RenderCategories(w io.Writer, data CategoriesData) error {
208 -
	return categoriesTmpl.ExecuteTemplate(w, "base", data)
274 +
	return categoriesTmpl.execute(w, data)
209 275
}
210 276
211 277
func RenderCategory(w io.Writer, data CategoryData) error {
212 -
	return categoryTmpl.ExecuteTemplate(w, "base", data)
278 +
	return categoryTmpl.execute(w, data)
213 279
}
214 280
215 281
func RenderPage(w io.Writer, data PageData) error {
216 -
	return pageTmpl.ExecuteTemplate(w, "base", data)
282 +
	return pageTmpl.execute(w, data)
217 283
}
geändert main.go
+77 −11 Datei ansehen
@@ -1,51 +1,117 @@
1 1
package main
2 2
3 3
import (
4 +
	"flag"
4 5
	"fmt"
5 6
	"log"
6 7
	"os"
8 +
	"path/filepath"
9 +
	"sort"
10 +
	"strings"
7 11
8 12
	"github.com/ruedigerp/newblog/internal/config"
9 13
	"github.com/ruedigerp/newblog/internal/content"
10 14
	"github.com/ruedigerp/newblog/internal/generator"
11 15
	"github.com/ruedigerp/newblog/internal/server"
16 +
	"github.com/ruedigerp/newblog/internal/templates"
12 17
)
13 18
19 +
func usage() {
20 +
	fmt.Println("Usage: quilldrop <serve|generate> [flags]")
21 +
	fmt.Println()
22 +
	fmt.Println("Commands:")
23 +
	fmt.Println("  serve      Start the dynamic HTTP server")
24 +
	fmt.Println("  generate   Generate static HTML files")
25 +
	fmt.Println()
26 +
	fmt.Println("Flags:")
27 +
	fmt.Println("  -config <path>   Config file (default: config.yaml)")
28 +
	fmt.Println("  -theme <name>    Theme to use, overrides 'theme' from the config")
29 +
	fmt.Println("  -dev             serve: reload templates on every request (live reload)")
30 +
}
31 +
14 32
func main() {
15 33
	if len(os.Args) < 2 {
16 -
		fmt.Println("Usage: newblog <serve|generate>")
17 -
		fmt.Println()
18 -
		fmt.Println("Commands:")
19 -
		fmt.Println("  serve      Start the dynamic HTTP server")
20 -
		fmt.Println("  generate   Generate static HTML files")
34 +
		usage()
35 +
		os.Exit(1)
36 +
	}
37 +
38 +
	cmd := os.Args[1]
39 +
	if cmd != "serve" && cmd != "generate" {
40 +
		fmt.Printf("Unknown command: %s\n", cmd)
41 +
		usage()
21 42
		os.Exit(1)
22 43
	}
23 44
24 -
	cfg, err := config.Load("config.yaml")
45 +
	fs := flag.NewFlagSet(cmd, flag.ExitOnError)
46 +
	configPath := fs.String("config", "config.yaml", "path to the config file")
47 +
	theme := fs.String("theme", "", "theme to use, overrides 'theme' from the config")
48 +
	dev := fs.Bool("dev", false, "serve: reload templates on every request")
49 +
	if err := fs.Parse(os.Args[2:]); err != nil {
50 +
		os.Exit(1)
51 +
	}
52 +
	if *dev && cmd != "serve" {
53 +
		log.Fatalf("-dev is only supported for 'serve'")
54 +
	}
55 +
	templates.SetDevMode(*dev)
56 +
57 +
	cfg, err := config.Load(*configPath)
25 58
	if err != nil {
26 59
		log.Fatalf("Failed to load config: %v", err)
27 60
	}
61 +
	if *theme != "" {
62 +
		cfg.Theme = *theme
63 +
	}
64 +
	if err := checkTheme(cfg); err != nil {
65 +
		log.Fatalf("%v", err)
66 +
	}
28 67
29 68
	posts, err := content.LoadAll(cfg.ContentDir)
30 69
	if err != nil {
31 70
		log.Fatalf("Failed to load posts: %v", err)
32 71
	}
33 72
	log.Printf("Loaded %d posts", len(posts))
34 73
35 74
	pages, err := content.LoadAllPages(cfg.SitesDir)
36 75
	if err != nil {
37 76
		log.Fatalf("Failed to load pages: %v", err)
38 77
	}
39 78
	log.Printf("Loaded %d pages", len(pages))
40 79
41 -
	switch os.Args[1] {
80 +
	switch cmd {
42 81
	case "serve":
43 82
		server.Start(cfg, posts, pages)
44 83
	case "generate":
45 84
		generator.Generate(cfg, posts, pages)
46 -
	default:
47 -
		fmt.Printf("Unknown command: %s\n", os.Args[1])
48 -
		fmt.Println("Usage: newblog <serve|generate>")
49 -
		os.Exit(1)
50 85
	}
51 86
}
87 +
88 +
// checkTheme verifies the configured theme exists and reports the available
89 +
// themes otherwise.
90 +
func checkTheme(cfg *config.Config) error {
91 +
	if info, err := os.Stat(cfg.ThemeTemplatesDir()); err == nil && info.IsDir() {
92 +
		return nil
93 +
	}
94 +
	msg := fmt.Sprintf("Theme %q not found: %s is missing", cfg.Theme, cfg.ThemeTemplatesDir())
95 +
	if available := availableThemes(cfg.ThemesDir); len(available) > 0 {
96 +
		msg += fmt.Sprintf(" (available themes: %s)", strings.Join(available, ", "))
97 +
	}
98 +
	return fmt.Errorf("%s", msg)
99 +
}
100 +
101 +
func availableThemes(themesDir string) []string {
102 +
	entries, err := os.ReadDir(themesDir)
103 +
	if err != nil {
104 +
		return nil
105 +
	}
106 +
	var themes []string
107 +
	for _, e := range entries {
108 +
		if !e.IsDir() {
109 +
			continue
110 +
		}
111 +
		if info, err := os.Stat(filepath.Join(themesDir, e.Name(), "templates")); err == nil && info.IsDir() {
112 +
			themes = append(themes, e.Name())
113 +
		}
114 +
	}
115 +
	sort.Strings(themes)
116 +
	return themes
117 +
}
umbenannt static/images/posts/thumbs/movie_v4.gif → qd-darwin
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/data/partners.json
+24 −0 Datei ansehen
@@ -0,0 +1,24 @@
1 +
[
2 +
  { "src": "/images/partner/Kolling.webp",                       "name": "Kolling",                       "url": "https://www.kfz-kolling.de" },
3 +
  { "src": "/images/partner/Marcus-Vandamme.webp",               "name": "Marcus Vandamme",               "url": "https://www.dvag.de/marcus.vandamme/ueber-uns.html" },
4 +
  { "src": "/images/partner/albo-tec.png.avif",                 "name": "Albo-Tec",                      "url": "https://www.umweltanalytik-bodenmechanik.de" },
5 +
  { "src": "/images/partner/alte-waschfabrik.webp",              "name": "Alte Waschfabrik",              "url": "https://altewaschfabrik.de" },
6 +
  { "src": "/images/partner/arbeitsschutzmanagement-rohde.webp", "name": "Arbeitsschutzmanagement Rohde", "url": "https://agz-sbh.de/" },
7 +
  { "src": "/images/partner/grizzly-bee-honig.webp",             "name": "Grizzly Bee Honig",             "url": "https://grizzlybee-honig.de" },
8 +
  { "src": "/images/partner/hansa-fliesen-depot.webp",           "name": "Hansa Fliesen Depot",           "url": "https://hansa-fliesen-depot.de/" },
9 +
  { "src": "/images/partner/harmuth.webp",                       "name": "Harmuth",                       "url": "https://www.harmuth-entsorgung.de" },
10 +
  { "src": "/images/partner/muenstermann.webp",                  "name": "Münstermann",                   "url": "https://fenstertechnik-muenstermann.de/" },
11 +
  { "src": "/images/partner/schlenkhoff.webp",                   "name": "Schlenkhoff",                   "url": "https://www.schlenkhoff.de" },
12 +
  { "src": "/images/partner/tankstelle-peters.webp",             "name": "Tankstelle Peters",             "url": "https://tankstelle-peters.de/" },
13 +
  { "src": "/images/partner/utz.webp",                           "name": "Utz",                           "url": "https://www.bauunternehmen-utz.de" },
14 +
  { "src": "/images/partner/vepa-baumbach.webp",                 "name": "Vepa Baumbach",                 "url": "https://vepa-baumbach.de" },
15 +
  { "src": "/images/partner/dsl-schweisstechnik.webp",           "name": "DSL Schweisstechnik GmbH",      "url": "https://www.dsl-schweisstechnik.de" },
16 +
  { "src": "/images/partner/amecko-gmbh.webp",                   "name": "AMECKO GmbH",                   "url": "https://www.amecko.com/de" },
17 +
  { "src": "/images/partner/trautmann-gmbh.webp",                "name": "Trautmann Garten- & Landschaftsbeu GmbH",   "url": "https://www.trautmann-essen.de" },
18 +
  { "src": "/images/partner/joerg-tinnefeld.webp",               "name": "Jörg Tinnefeld Außen- und Innenbegrünung",  "url": "https://tinnefeld-gruen.de" },
19 +
  { "src": "/images/partner/reise-genie.webp",                   "name": "Reisegenie.de Thorsten Haske",  "url": "https://reisegenie.de" },
20 +
  { "src": "/images/partner/phillip-doermann-physio.webp",       "name": "Phillip Dörmann Physiotherapie",  "url": "https://www.physiotherapie-doermann.de" },
21 +
  { "src": "/images/partner/LogoCarlundCarla.gif",               "name": "CarlundCarla.de Transportervermietung",  "url": "https://carlundcarla.de/transporter-mieten-essen" },
22 +
  { "src": "/images/partner/solar-richter.webp",                 "name": "Solar Richter",                 "url": "https://www.solar-richter.com" },
23 +
  { "src": "/images/partner/wohnbau-eg.webp",                    "name": "Wohnbau eG",                    "url": "https://www.wohnbau-eg.de" }
24 +
]
hinzugefügt static/images/ehc/EHC_Logo-bak.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/ehc/EHC_Logo.png
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/ehc/EHC_Logo.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/ehc/ehc-logo-v2..png
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/ehc/ehc-logo-v2..webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/ehc/ehc-steelers-bg.png
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/ehc/ehc-steelers-bg.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/ehc/we-are-family-team-short.png
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/ehc/we-are-family-team-short.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/ehc/we-are-family-v2.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/ehc/we-are-family.png
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/ehc/we-are-family.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/generate-thumbs copy.sh
+241 −0 Datei ansehen
@@ -0,0 +1,241 @@
1 +
#!/bin/bash
2 +
3 +
# Option 1: PNG zu JPEG konvertieren (meist dramatische Größenreduktion)
4 +
for i in `find posts -type f ! -name "thumb-*.png" -name "*.png" | grep -v thumbs`;
5 +
do
6 +
  filefull="${i##*/}"
7 +
  file="${filefull%.[^.]*}"
8 +
  ext="${filefull:${#file} + 1}"
9 +
  dir=$(echo ${i} | sed -e "s/${file}\.${ext}//")
10 +
  source="${dir}${file}.${ext}"
11 +
  
12 +
  if [ ! -d ${dir}thumbs/ ];
13 +
  then
14 +
    mkdir ${dir}thumbs/
15 +
  fi
16 +
  
17 +
  # Als JPEG speichern für dramatische Größenreduktion
18 +
  dest="${dir}thumbs/${file}.jpg"
19 +
  
20 +
  if [ -f ${dest} ];
21 +
  then
22 +
    continue;
23 +
  fi;
24 +
  
25 +
  # PNG zu JPEG mit weißem Hintergrund (für Transparenz)
26 +
  convert ${source} -background white -flatten -quality 85 -strip ${dest};
27 +
  echo "convert ${source} -background white -flatten -quality 85 -strip ${dest};"
28 +
done
29 +
30 +
echo -e "\n=== webp Konvertierung ==="
31 +
# for i in posts/**/*.{jpg,jpeg,png,JPG,JPEG,PNG}; do
32 +
for i in `find posts -type f ! -name "*.svg" ! -name "*.webp" ! -name "*.gif" | grep -v thumbs`; do 
33 +
  # echo "i: $i"
34 +
  [ ! -f "$i" ] && continue
35 +
  
36 +
  filename=$(basename "$i")
37 +
  name="${filename%.*}"
38 +
  dir=$(dirname "$i")
39 +
  output="${dir}/${name}.webp"
40 +
  
41 +
  [ -f "$output" ] && continue
42 +
  
43 +
  # Dateigröße prüfen
44 +
  size=$(stat -f%z "$i" 2>/dev/null || stat -c%s "$i" 2>/dev/null)
45 +
  
46 +
  # Qualität basierend auf Dateigröße anpassen
47 +
  if [ "$size" -gt 1000000 ]; then  # > 1MB
48 +
    quality=75
49 +
  elif [ "$size" -gt 500000 ]; then # > 500KB
50 +
    quality=80
51 +
  else
52 +
    quality=85
53 +
  fi
54 +
  
55 +
  echo "Konvertiere: $i (${size} bytes) -> $output (quality: $quality)"
56 +
  cwebp -q $quality "$i" -o "$output"
57 +
done
58 +
59 +
# echo "Generate Thumbnails" 
60 +
# for i in `find posts -type f ! -name "*.svg" ! -name "*.webp" | grep -v thumbs`;
61 +
# do
62 +
#   # echo $i;
63 +
#   filefull="${i##*/}"
64 +
#   file="${filefull%.[^.]*}"
65 +
#   ext="${filefull:${#file} + 1}"
66 +
#   dir=$(echo ${i} | sed -e "s/${file}\.${ext}//")
67 +
#   source="${dir}${file}.${ext}"
68 +
#   if [ ! -d ${dir}thumbs/ ];
69 +
#   then
70 +
#     mkdir ${dir}thumbs/
71 +
#   fi
72 +
#   dest="${dir}thumbs/${file}-600x600.${ext}"
73 +
#   if [ -f ${dest} ];
74 +
#   then
75 +
#     continue;
76 +
#   fi;
77 +
#   convert ${source} -thumbnail 600x600 ${dest}
78 +
#   echo "convert ${source} -thumbnail 600x600 ${dest}";
79 +
# done
80 +
81 +
82 +
# Option 2: Wenn Sie PNG behalten möchten - mit pngquant (installieren mit: sudo apt install pngquant)
83 +
# for i in `find posts -type f ! -name "thumb-*.png" -name "*.png" | grep -v thumbs`;
84 +
# do
85 +
#   filefull="${i##*/}"
86 +
#   file="${filefull%.[^.]*}"
87 +
#   ext="${filefull:${#file} + 1}"
88 +
#   dir=$(echo ${i} | sed -e "s/${file}\.${ext}//")
89 +
#   source="${dir}${file}.${ext}"
90 +
#   
91 +
#   if [ ! -d ${dir}thumbs/ ];
92 +
#   then
93 +
#     mkdir ${dir}thumbs/
94 +
#   fi
95 +
#   dest="${dir}thumbs/${file}.${ext}"
96 +
#   
97 +
#   if [ -f ${dest} ];
98 +
#   then
99 +
#     continue;
100 +
#   fi;
101 +
#   
102 +
#   # PNG verlustbehaftet komprimieren (kann 50-80% Größenreduktion bringen)
103 +
#   pngquant --quality=65-80 --output ${dest} ${source};
104 +
# done
105 +
106 +
# Option 3: Moderne WebP Format (beste Komprimierung)
107 +
# for i in `find posts -type f ! -name "thumb-*.png" -name "*.png" | grep -v thumbs`;
108 +
# do
109 +
#   filefull="${i##*/}"
110 +
#   file="${filefull%.[^.]*}"
111 +
#   ext="${filefull:${#file} + 1}"
112 +
#   dir=$(echo ${i} | sed -e "s/${file}\.${ext}//")
113 +
#   source="${dir}${file}.${ext}"
114 +
#   
115 +
#   if [ ! -d ${dir}thumbs/ ];
116 +
#   then
117 +
#     mkdir ${dir}thumbs/
118 +
#   fi
119 +
#   dest="${dir}thumbs/${file}.webp"
120 +
#   
121 +
#   if [ -f ${dest} ];
122 +
#   then
123 +
#     continue;
124 +
#   fi;
125 +
#   
126 +
#   # Als WebP mit hoher Komprimierung
127 +
#   convert ${source} -quality 80 -define webp:lossless=false ${dest};
128 +
# done
129 +
130 +
# # Option 1: Einfache Qualitätsreduzierung (empfohlen für die meisten Fälle)
131 +
# for i in `find posts -type f ! -name "thumb-*.png" -name "*.png" | grep -v thumbs`;
132 +
# do
133 +
#   filefull="${i##*/}"
134 +
#   file="${filefull%.[^.]*}"
135 +
#   ext="${filefull:${#file} + 1}"
136 +
#   dir=$(echo ${i} | sed -e "s/${file}\.${ext}//")
137 +
#   source="${dir}${file}.${ext}"
138 +
  
139 +
#   if [ ! -d ${dir}thumbs/ ];
140 +
#   then
141 +
#     mkdir ${dir}thumbs/
142 +
#   fi
143 +
  
144 +
#   dest="${dir}thumbs/${file}.${ext}"
145 +
  
146 +
#   # if [ -f ${dest} ];
147 +
#   # then
148 +
#   #   continue;
149 +
#   # fi;
150 +
  
151 +
#   # Komprimierung mit reduzierter Qualität (80% ist ein guter Startwert)
152 +
#   echo "convert ${source} -quality 80 -strip ${dest};"
153 +
#   # convert ${source} -quality 60 -strip ${dest};
154 +
#   convert ${source} -quality 30 -strip -interlace Plane -resize '1000x1000>' ${dest};
155 +
#   # convert ${source} -strip -define png:compression-level=9 ${dest};
156 +
# done
157 +
158 +
# Option 2: Aggressivere Komprimierung
159 +
# convert ${source} -quality 60 -strip -interlace Plane ${dest};
160 +
161 +
# Option 3: Für PNG spezifisch optimiert
162 +
# convert ${source} -strip -define png:compression-level=9 ${dest};
163 +
164 +
# Option 4: Automatische Optimierung basierend auf Dateigröße
165 +
# convert ${source} -quality 85 -strip -resize '2000x2000>' ${dest};
166 +
167 +
####################################################################################################
168 +
169 +
# for i in `find posts -type f ! -name "thumb-*.png" -name "*.png" | grep -v thumbs`;
170 +
# do
171 +
#   filefull="${i##*/}"
172 +
#   file="${filefull%.[^.]*}"
173 +
#   ext="${filefull:${#file} + 1}"
174 +
#   dir=$(echo ${i} | sed -e "s/${file}\.${ext}//")
175 +
#   source="${dir}${file}.${ext}"
176 +
#   if [ ! -d ${dir}thumbs/ ];
177 +
#   then
178 +
#     mkdir ${dir}thumbs/
179 +
#   fi
180 +
#   dest="${dir}thumbs/${file}.${ext}"
181 +
#   if [ -f ${dest} ];
182 +
#   then
183 +
#     continue;
184 +
#   fi;
185 +
#   convert ${source} -thumbnail 200x200 ${dest};
186 +
# done
187 +
188 +
189 +
190 +
#################
191 +
192 +
193 +
#for i in `find static/images/galleries -type f ! -name "*-thumb.jpg" -name "*.jpg"`;
194 +
#do
195 +
#  echo $i;
196 +
#  if [ -f ${i%.*}-thumb.jpg ];
197 +
#  then
198 +
#    continue;
199 +
#  fi;
200 +
#  convert $i -thumbnail 300x300 ${i%.*}-thumb.jpg;
201 +
#done
202 +
203 +
# for i in `find static/images/galleries -type f ! -name "thumb-*.jpg" -name "*.jpg" | grep -v thumbs`;
204 +
# do
205 +
#   filefull="${i##*/}"
206 +
#   file="${filefull%.[^.]*}"
207 +
#   ext="${filefull:${#file} + 1}"
208 +
#   dir=$(echo ${i} | sed -e "s/${file}\.${ext}//")
209 +
#   source="${dir}${file}.${ext}"
210 +
#   if [ ! -d ${dir}thumbs/ ];
211 +
#   then
212 +
#     mkdir ${dir}thumbs/
213 +
#   fi
214 +
#   dest="${dir}thumbs/${file}.${ext}"
215 +
#   if [ -f ${dest} ];
216 +
#   then
217 +
#     continue;
218 +
#   fi;
219 +
#   convert ${source} -thumbnail 300x300 ${dest};
220 +
# done
221 +
222 +
# for i in `find static/img/posts -type f ! -name "*.svg" | grep -v thumbs`;
223 +
# do
224 +
#   # echo $i;
225 +
#   filefull="${i##*/}"
226 +
#   file="${filefull%.[^.]*}"
227 +
#   ext="${filefull:${#file} + 1}"
228 +
#   dir=$(echo ${i} | sed -e "s/${file}\.${ext}//")
229 +
#   source="${dir}${file}.${ext}"
230 +
#   if [ ! -d ${dir}thumbs/ ];
231 +
#   then
232 +
#     mkdir ${dir}thumbs/
233 +
#   fi
234 +
#   dest="${dir}thumbs/${file}.${ext}"
235 +
#   if [ -f ${dest} ];
236 +
#   then
237 +
#     continue;
238 +
#   fi;
239 +
#   convert ${source} -thumbnail 600x600 ${dest}
240 +
#   echo "convert ${source} -thumbnail 300x300 ${dest}";
241 +
# done
hinzugefügt static/images/news/05/30-jahre-eje.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/GrizzlyBee.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/Hansa-Fliesen-Depot.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/albo-tec.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/alte-waschfabrik.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/arbeitsschutz-rohde.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/bauunternehmen-utz.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/bosch-service-kolling.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/harmuth.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/muenstermann.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/schlenkhoff.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/sportlicher-leiter.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/tankstelle-peters.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/vandamme.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/05/we-are-family.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/amecko-gmbh.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/die-zukunft-hat-begonnen.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/dsl-schweisstechnik.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/du-fehlst-uns-noch.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/ehc-intern.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/it-ruediger-kuepper.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/joerg-tinnefeld.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/reise-genie.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/trainer-marvin-storb.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/trainer-matthias-michalowicz.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/trainer_lia-koepfer.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/trainer_tim-koziol.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/trautmann-gmbh.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/06/vepa-baumbach.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/alexander-abi-birakis.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/andrii-ibraiev.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/bastian-samel.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/carlundcarla-kleinbus-mieten-carla-9-sitzer.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/christian-sohlmann.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/daniel-breves.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/daniil-pogireichik.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/danke.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/fanclub-seite.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/filip-moruzgala.jpg
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/filip-moruzgala.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/jan-ildenberg.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/joshua-schwindenhammer.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/luisa-petrich.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/materialspende-danke-nobby.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/neuer-partner-phillip-doermann-physiotherapie.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/nikita-maer.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/platon-bulat.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/rick-bieling.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/sergej-hatkevitch.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/silke-hoepken.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/solar-richter.jpg
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/solar-richter.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/spielplan-bezirksliga-2026-2027.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/sponsorenbeauftragter-marcus-vandamme.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/testspiele-gegen-den-herner-ev-1b.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/trainer-frederic-schulte.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/trainer-robert-brune.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/trainer-sascha-kuhn.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/vorbereitung-dinslakener-kobras-vs-ehc-essen.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/vorbereitung-ehc-essen-vs-soester-eg.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/vorbereitungsspiele.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/vorstand.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/wir-stellen-vor-unser-neuer-torwart-leon-frensel.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/wir-suchen-dich.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/07/wohnbau-eg.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/16-10-2026-essen-vs-neusser-ev-1b.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/andre-schrader.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/christian-willi-vogel.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/claus-bauti-bagterp.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/da-ist-das-ding.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/david-safenreider.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/der-sport-geht-weiter-2.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/der-sport-geht-weiter.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/ehc-intern-08.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/fanbeauftragte-treffen-dortmund.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/jendrik-allendorf.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/maurice-nawrotzki.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/maxim-beck.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/ruffs-burger.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/08/spielplan-vorrunde.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/news/LogoCarlundCarla.gif
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/60ea24ab-0297-45bd-99c9-299c4e6a10fb.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/Kolling.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/LogoCarlundCarla.gif
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/Marcus-Vandamme.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/albo-tec.png.avif
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/alte-waschfabrik.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/amecko-gmbh.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/arbeitsschutzmanagement-rohde.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/dsl-schweisstechnik.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/grizzly-bee-honig.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/hansa-fliesen-depot.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/harmuth.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/joerg-tinnefeld.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/muenstermann.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/phillip-doermann-physio.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/reise-genie.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/schlenkhoff.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/solar-richter.png
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/solar-richter.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/tankstelle-peters.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/trautmann-gmbh.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/utz.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/vepa-baumbach.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/partner/wohnbau-eg.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019-08-10-Netzwerkumbau-VLANs-und-Firewall-1.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019-08-10-Netzwerkumbau-VLANs-und-Firewall-1.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/01/27/programming.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/01/27/programming.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/01/27/thumbs/programming.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/01/27/thumbs/programming.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/01/27/thumbs/programming.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/03/30/thumbs/webmail.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/03/30/thumbs/webmail.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/03/30/thumbs/webmail.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/03/30/webmail.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/03/30/webmail.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/03/banner-1.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/03/banner-1.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/03/network.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/03/network.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/03/thumbs/network.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/03/thumbs/network.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/03/thumbs/network.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/04/programming.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/04/programming.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/04/thumbs/programming.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/04/thumbs/programming.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/04/thumbs/programming.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/05/network.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/05/network.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/05/programming.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/05/programming.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/05/thumbs/network.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/05/thumbs/network.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/05/thumbs/network.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/05/thumbs/programming.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/05/thumbs/programming.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/05/thumbs/programming.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/07/thumbs/vpn.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/07/thumbs/vpn.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/07/thumbs/vpn.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/07/vpn.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/07/vpn.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/09/network.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/09/network.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/09/thumbs/network.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/09/thumbs/network.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/09/thumbs/network.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/10/thumbs/wifi.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/10/thumbs/wifi.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/10/thumbs/wifi.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/10/wifi.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/10/wifi.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/12/thumbs/vpn.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/12/thumbs/vpn.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/12/thumbs/vpn.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/12/thumbs/vpn_.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/12/thumbs/vpn_.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/12/thumbs/vpn_.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/12/vpn.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/12/vpn.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/12/vpn_.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/12/vpn_.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/13/multimedia.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/13/multimedia.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/13/thumbs/multimedia.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/13/thumbs/multimedia.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/13/thumbs/multimedia.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/18/serverofdeath.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/18/serverofdeath.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/18/thumbs/serverofdeath.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/18/thumbs/serverofdeath.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/18/thumbs/serverofdeath.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/19/thumbs/wifi.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/19/thumbs/wifi.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/19/thumbs/wifi.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/19/wifi.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/19/wifi.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/28/movie_v4.gif
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/28/ping_pane_title.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/28/ping_pane_title.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/28/thumbs/ping_pane_title.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/28/thumbs/ping_pane_title.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/28/thumbs/ping_pane_title.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/29/caddyserver.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/29/caddyserver.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/29/thumbs/caddyserver.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/29/thumbs/caddyserver.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2019/08/29/thumbs/caddyserver.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2023/09/kubernetes-netpol.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2023/09/kubernetes-netpol.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2023/09/thumbs/kubernetes-netpol.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/adblocker-pihole-protection.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/adblocker-pihole-protection.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/gaming-howto-sudo.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/gaming-howto-sudo.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/static-blog.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/static-blog.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/adblocker-pihole-protection.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/adblocker-pihole-protection.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/adblocker-pihole-protection.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/gaming-howto-sudo.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/gaming-howto-sudo.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/gaming-howto-sudo.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/static-blog.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/static-blog.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/static-blog.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/warp-editor.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/warp-editor.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/warp-editor.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/young-seo-casper.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/young-seo-casper.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/thumbs/young-seo-casper.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/warp-editor.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/warp-editor.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/young-seo-casper.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/01/young-seo-casper.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/02/cms.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/02/cms.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/github.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/github.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/iterm-colors.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/iterm-colors.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/neovim.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/neovim.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/p10k.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/p10k.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/thumbs/github.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/thumbs/github.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/thumbs/iterm-colors.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/thumbs/iterm-colors.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/thumbs/neovim.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/thumbs/neovim.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/thumbs/p10k.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/thumbs/p10k.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/thumbs/tmux.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/thumbs/tmux.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/thumbs/zsh.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/thumbs/zsh.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/tmux.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/tmux.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/zsh.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2024/12/zsh.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/01/pihole-local-dns.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/01/pihole-local-dns.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/01/thumbs/pihole-local-dns.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/01/thumbs/pihole-local-dns.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/02/minio.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/deltachat-mail-settings.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/deltachat-mail-settings.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/deltachat.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/deltachat.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/deltachat_own_server.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/deltachat_own_server.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/haproxy.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/haproxy.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/thumbs/deltachat-mail-settings.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/thumbs/deltachat-mail-settings.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/thumbs/deltachat.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/thumbs/deltachat.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/thumbs/deltachat_own_server.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/thumbs/deltachat_own_server.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/thumbs/haproxy.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/03/thumbs/haproxy.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/04/dex-sso.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/04/dex-sso.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/04/thumbs/dex-sso.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/04/thumbs/dex-sso.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/IMG_0971.jpeg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/IMG_0971.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/aws-els-console-kubeconfig.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/aws-els-console-kubeconfig.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/build-pipeline.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/build-pipeline.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/comments-1.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/comments-1.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/comments-2.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/comments-2.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/comments.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/comments.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/fix-problem.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/fluxcd-image-update-automation.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/fluxcd-image-update-automation.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/git-merge-script.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/git-merge-script.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/k8s-pv-backup.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/k8s-pv-backup.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/links-of-the-week.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/links-of-the-week.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/sops-secret-encryption.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/sops-secret-encryption.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/thumbs/aws-els-console-kubeconfig.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/thumbs/build-pipeline.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/thumbs/comments-1.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/thumbs/comments-2.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/thumbs/comments.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/thumbs/fluxcd-image-update-automation.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/thumbs/fluxcd-image-update-automation.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/thumbs/git-merge-script.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/thumbs/k8s-pv-backup.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/thumbs/links-of-the-week.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/06/thumbs/sops-secret-encryption.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/BC13E6DB-AC08-4445-A5E3-65CA6C1A2EE4.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/BC13E6DB-AC08-4445-A5E3-65CA6C1A2EE4.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/container-registry-cleanup.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/container-registry-cleanup.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/linkwarden-karakeep.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/linkwarden-karakeep.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/microsoft-rant.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/microsoft-rant.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/mutt-30-years.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/mutt-30-years.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/thumbs/BC13E6DB-AC08-4445-A5E3-65CA6C1A2EE4.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/thumbs/container-registry-cleanup.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/thumbs/image.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/thumbs/linkwarden-karakeep.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/thumbs/microsoft-rant.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/thumbs/mutt-30-years.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/thumbs/unifi-dashboard.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/unifi-dashboard.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/07/unifi-dashboard.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/08/telekom-mail-fail.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/08/telekom-mail-fail.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/08/thumbs/telekom-mail-fail.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/10/debugging-von-distroless-containern-in-kubernetes.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/10/debugging-von-distroless-containern-in-kubernetes.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/10/der-ultimative-guide-zum-caffeinate-befehl-auf-dem-mac.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/10/der-ultimative-guide-zum-caffeinate-befehl-auf-dem-mac.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/10/fluxcd-globale-vars-fuer-gethomepage.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/10/fluxcd-globale-vars-fuer-gethomepage.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/10/k3s-fluxcd-k3s.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/10/k3s-fluxcd-k3s.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/10/thumbs/debugging-von-distroless-containern-in-kubernetes.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/10/thumbs/der-ultimative-guide-zum-caffeinate-befehl-auf-dem-mac.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/10/thumbs/fluxcd-globale-vars-fuer-gethomepage.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/10/thumbs/k3s-fluxcd-k3s.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/11/thumbs/vm-tracker-overview.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/11/thumbs/vm-tracker-shelly.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/11/thumbs/vm-tracker.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/11/vm-tracker-overview.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/11/vm-tracker-overview.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/11/vm-tracker-shelly.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/11/vm-tracker-shelly.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/11/vm-tracker.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2025/11/vm-tracker.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2factor-1024x312.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/2factor-1024x312.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Compressor-Dyna-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Compressor-Dyna-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Compressor-Dyna-300x225.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Compressor-Dyna-300x225.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/DB-Wifi-1-300x255.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/DB-Wifi-1-300x255.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/DB-Wifi-1.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/DB-Wifi-1.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/DB-Wifi-2.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/DB-Wifi-2.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/DB-Wifi-3.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/DB-Wifi-3.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Der-Compressor-Dyna-Compressor-Bausatz.jpg-300x300.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Der-Compressor-Dyna-Compressor-Bausatz.jpg-300x300.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Der-Compressor-Dyna-Compressor-Bausatz.jpg.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Der-Compressor-Dyna-Compressor-Bausatz.jpg.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1116-300x203.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1116-300x203.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1116.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1116.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1121-1-e1454456497787-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1121-1-e1454456497787-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1122-e1454456449498-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1122-e1454456449498-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1123-e1455287450903-150x150.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1123-e1455287450903-150x150.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1123-e1455287450903.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1123-e1455287450903.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1127-e1455234520305-150x150.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1127-e1455234520305-150x150.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1127-e1455234520305-768x1024.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1127-e1455234520305-768x1024.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1128-e1455234629727-150x150.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1128-e1455234629727-150x150.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1128-e1455234629727-768x1024.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1128-e1455234629727-768x1024.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1129-e1455234758942-150x150.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1129-e1455234758942-150x150.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1129-e1455234758942-768x1024.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1129-e1455234758942-768x1024.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1131-e1455234812127-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1131-e1455234812127-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1131-e1455234812127-150x150.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1131-e1455234812127-150x150.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1435-e1455138449549-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_1435-e1455138449549-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_7208-e1455138417739-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_7208-e1455138417739-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_7260-e1454339420251-225x300.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_7260-e1454339420251-225x300.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_7260-e1454339420251-768x1024.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_7260-e1454339420251-768x1024.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_9117-e1454339397491-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/IMG_9117-e1454339397491-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Mpow-Magneto-1-300x180.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Mpow-Magneto-1-300x180.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Mpow-Magneto-1.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Mpow-Magneto-1.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Mpow-Magneto-2-300x169.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Mpow-Magneto-2-300x169.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Mpow-Magneto-3-300x288.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/Mpow-Magneto-3-300x288.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/burger-n-truck.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/burger-n-truck.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/earpods-1-300x225.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/earpods-1-300x225.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/earpods-2-300x300.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/earpods-2-300x300.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/folders.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/folders.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/fuzzy-300x240.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/fuzzy-300x240.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/fuzzy.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/fuzzy.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/github-actions-banner.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/github-actions-banner.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/goodmans.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/goodmans.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/high-sierra-install-screen-300x255.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/high-sierra-install-screen-300x255.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/high-sierra-install-screen.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/high-sierra-install-screen.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0150.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0150.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0154.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0154.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0156.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0156.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0157-1.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0157-1.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0159.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0159.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0161-225x300.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0161-225x300.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0161.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_0161.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_1062-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_1062-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_1062-300x225.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_1062-300x225.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_1074.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_1074.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_1075.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_1075.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_5073-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_5073-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_5073-300x225.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_5073-300x225.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_5078-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_5078-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_5078-300x225.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/img_5078-300x225.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/incomming.svg
+0 −1
@@ -1 +0,0 @@
1 -
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" id="chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a" class="pygal-chart" viewBox="0 0 800 600"> <!--Generated with pygal 2.4.0 (lxml) ©Kozea 2012-2016 on 2018-01-02--> <!--http://pygal.org--> <!--http://github.com/Kozea/pygal--> <defs> <style type="text/css">#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a{-webkit-user-select:none;-webkit-font-smoothing:antialiased;font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .title{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .legends .legend text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis text.major{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .text-overlay text.value{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .text-overlay text.label{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .tooltip{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a text.no_data{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:64px} #chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a{background-color:rgba(249,249,249,1)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a path,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a line,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a rect,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a circle{-webkit-transition:150ms;-moz-transition:150ms;transition:150ms}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .graph &gt; .background{fill:rgba(249,249,249,1)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .plot &gt; .background{fill:rgba(255,255,255,1)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .graph{fill:rgba(0,0,0,.87)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a text.no_data{fill:rgba(0,0,0,1)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .title{fill:rgba(0,0,0,1)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .legends .legend text{fill:rgba(0,0,0,.87)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .legends .legend:hover text{fill:rgba(0,0,0,1)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis .line{stroke:rgba(0,0,0,1)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis .guide.line{stroke:rgba(0,0,0,.54)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis .major.line{stroke:rgba(0,0,0,.87)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis text.major{fill:rgba(0,0,0,1)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis.y .guides:hover .guide.line,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .line-graph .axis.x .guides:hover .guide.line,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .stackedline-graph .axis.x .guides:hover .guide.line,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .xy-graph .axis.x .guides:hover .guide.line{stroke:rgba(0,0,0,1)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis .guides:hover text{fill:rgba(0,0,0,1)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .reactive{fill-opacity:.7;stroke-opacity:.8}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .ci{stroke:rgba(0,0,0,.87)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .reactive.active,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .active .reactive{fill-opacity:.8;stroke-opacity:.9;stroke-width:4}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .ci .reactive.active{stroke-width:1.5}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .series text{fill:rgba(0,0,0,1)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .tooltip rect{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,1);-webkit-transition:opacity 150ms;-moz-transition:opacity 150ms;transition:opacity 150ms}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .tooltip .label{fill:rgba(0,0,0,.87)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .tooltip .label{fill:rgba(0,0,0,.87)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .tooltip .legend{font-size:.8em;fill:rgba(0,0,0,.54)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .tooltip .x_label{font-size:.6em;fill:rgba(0,0,0,1)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .tooltip .xlink{font-size:.5em;text-decoration:underline}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .tooltip .value{font-size:1.5em}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .bound{font-size:.5em}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .max-value{font-size:.75em;fill:rgba(0,0,0,.54)}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .map-element{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,.54) !important}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .map-element .reactive{fill-opacity:inherit;stroke-opacity:inherit}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .color-0,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .color-0 a:visited{stroke:#F44336;fill:#F44336}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .text-overlay .color-0 text{fill:black} #chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a text.no_data{text-anchor:middle}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .guide.line{fill:none}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .centered{text-anchor:middle}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .title{text-anchor:middle}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .legends .legend text{fill-opacity:1}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis.x text{text-anchor:middle}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis.x:not(.web) text[transform]{text-anchor:start}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis.x:not(.web) text[transform].backwards{text-anchor:end}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis.y text{text-anchor:end}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis.y text[transform].backwards{text-anchor:start}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis.y2 text{text-anchor:start}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis.y2 text[transform].backwards{text-anchor:end}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis .guide.line{stroke-dasharray:4,4}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis .major.guide.line{stroke-dasharray:6,6}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .horizontal .axis.y .guide.line,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .horizontal .axis.y2 .guide.line,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .vertical .axis.x .guide.line{opacity:0}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .horizontal .axis.always_show .guide.line,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .vertical .axis.always_show .guide.line{opacity:1 !important}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis.y .guides:hover .guide.line,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis.y2 .guides:hover .guide.line,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis.x .guides:hover .guide.line{opacity:1}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .axis .guides:hover text{opacity:1}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .nofill{fill:none}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .subtle-fill{fill-opacity:.2}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .dot{stroke-width:1px;fill-opacity:1}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .dot.active{stroke-width:5px}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .dot.negative{fill:transparent}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a text,#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a tspan{stroke:none !important}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .series text.active{opacity:1}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .tooltip rect{fill-opacity:.95;stroke-width:.5}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .tooltip text{fill-opacity:1}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .showable{visibility:hidden}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .showable.shown{visibility:visible}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .gauge-background{fill:rgba(229,229,229,1);stroke:none}#chart-5e7b250e-3170-4c20-bc5f-c832d2d5b55a .bg-lines{stroke:rgba(249,249,249,1);stroke-width:2px}</style> </defs> <title>Pygal</title> <g class="graph bar-graph vertical"> <rect class="background" height="600" width="800" x="0" y="0"></rect> <g class="plot" transform="translate(169, 20)"> <rect class="background" height="540" width="610.4" x="0" y="0"></rect> <g class="axis y always_show"> <g class="guides"> <path class="axis major line" d="M0.000000 529.615385 h610.400000"></path> <text class="major" x="-5" y="533.115384615">0</text> <title>0</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 484.136605 h610.400000"></path> <text class="" x="-5" y="487.63660525">100000</text> <title>100000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 438.657826 h610.400000"></path> <text class="" x="-5" y="442.157825884">200000</text> <title>200000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 393.179047 h610.400000"></path> <text class="" x="-5" y="396.679046518">300000</text> <title>300000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 347.700267 h610.400000"></path> <text class="" x="-5" y="351.200267152">400000</text> <title>400000</title> </g> <g class="guides"> <path class="major guide line" d="M0.000000 302.221488 h610.400000"></path> <text class="major" x="-5" y="305.721487787">500000</text> <title>500000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 256.742708 h610.400000"></path> <text class="" x="-5" y="260.242708421">600000</text> <title>600000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 211.263929 h610.400000"></path> <text class="" x="-5" y="214.763929055">700000</text> <title>700000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 165.785150 h610.400000"></path> <text class="" x="-5" y="169.28514969">800000</text> <title>800000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 120.306370 h610.400000"></path> <text class="" x="-5" y="123.806370324">900000</text> <title>900000</title> </g> <g class="guides"> <path class="major guide line" d="M0.000000 74.827591 h610.400000"></path> <text class="major" x="-5" y="78.3275909581">1000000</text> <title>1000000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 29.348812 h610.400000"></path> <text class="" x="-5" y="32.8488115923">1100000</text> <title>1100000</title> </g> </g> <g class="axis x"> <path class="line" d="M0.000000 0.000000 v540.000000"></path> <g class="guides"> <path class="guide line" d="M36.193590 0.000000 v540.000000"></path> <text class="" x="36.1935897436" y="555.0">Jan</text> </g> <g class="guides"> <path class="guide line" d="M85.103846 0.000000 v540.000000"></path> <text class="" x="85.1038461538" y="555.0">Feb</text> </g> <g class="guides"> <path class="guide line" d="M134.014103 0.000000 v540.000000"></path> <text class="" x="134.014102564" y="555.0">Mar</text> </g> <g class="guides"> <path class="guide line" d="M182.924359 0.000000 v540.000000"></path> <text class="" x="182.924358974" y="555.0">Apr</text> </g> <g class="guides"> <path class="guide line" d="M231.834615 0.000000 v540.000000"></path> <text class="" x="231.834615385" y="555.0">Mai</text> </g> <g class="guides"> <path class="guide line" d="M280.744872 0.000000 v540.000000"></path> <text class="" x="280.744871795" y="555.0">Jun</text> </g> <g class="guides"> <path class="guide line" d="M329.655128 0.000000 v540.000000"></path> <text class="" x="329.655128205" y="555.0">Jul</text> </g> <g class="guides"> <path class="guide line" d="M378.565385 0.000000 v540.000000"></path> <text class="" x="378.565384615" y="555.0">Aug</text> </g> <g class="guides"> <path class="guide line" d="M427.475641 0.000000 v540.000000"></path> <text class="" x="427.475641026" y="555.0">Sep</text> </g> <g class="guides"> <path class="guide line" d="M476.385897 0.000000 v540.000000"></path> <text class="" x="476.385897436" y="555.0">Okt</text> </g> <g class="guides"> <path class="guide line" d="M525.296154 0.000000 v540.000000"></path> <text class="" x="525.296153846" y="555.0">Nov</text> </g> <g class="guides"> <path class="guide line" d="M574.206410 0.000000 v540.000000"></path> <text class="" x="574.206410256" y="555.0">Dez</text> </g> </g> <g class="series serie-0 color-0"> <g class="bars"> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="7.64725675035" rx="0" ry="0" width="37.8761025641" x="17.2555384615" y="521.968127865"></rect> <desc class="value">16815</desc> <desc class="x centered">36.1935897436</desc> <desc class="y centered">525.79175624</desc> <desc class="x_label">Jan</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.183279480844" rx="0" ry="0" width="37.8761025641" x="66.1657948718" y="529.432105135"></rect> <desc class="value">403</desc> <desc class="x centered">85.1038461538</desc> <desc class="y centered">529.523744875</desc> <desc class="x_label">Feb</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.202835355971" rx="0" ry="0" width="37.8761025641" x="115.076051282" y="529.412549259"></rect> <desc class="value">446</desc> <desc class="x centered">134.014102564</desc> <desc class="y centered">529.513966937</desc> <desc class="x_label">Mar</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="16.5888395614" rx="0" ry="0" width="37.8761025641" x="163.986307692" y="513.026545054"></rect> <desc class="value">36476</desc> <desc class="x centered">182.924358974</desc> <desc class="y centered">521.320964835</desc> <desc class="x_label">Apr</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="279.816376228" rx="0" ry="0" width="37.8761025641" x="212.896564103" y="249.799008387"></rect> <desc class="value">615268</desc> <desc class="x centered">231.834615385</desc> <desc class="y centered">389.707196501</desc> <desc class="x_label">Mai</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="302.317002319" rx="0" ry="0" width="37.8761025641" x="261.806820513" y="227.298382296"></rect> <desc class="value">664743</desc> <desc class="x centered">280.744871795</desc> <desc class="y centered">378.456883456</desc> <desc class="x_label">Jun</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="230.647903492" rx="0" ry="0" width="37.8761025641" x="310.717076923" y="298.967481123"></rect> <desc class="value">507155</desc> <desc class="x centered">329.655128205</desc> <desc class="y centered">414.291432869</desc> <desc class="x_label">Jul</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="214.573428925" rx="0" ry="0" width="37.8761025641" x="359.627333333" y="315.04195569"></rect> <desc class="value">471810</desc> <desc class="x centered">378.565384615</desc> <desc class="y centered">422.328670153</desc> <desc class="x_label">Aug</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="194.831090803" rx="0" ry="0" width="37.8761025641" x="408.537589744" y="334.784293813"></rect> <desc class="value">428400</desc> <desc class="x centered">427.475641026</desc> <desc class="y centered">432.199839214</desc> <desc class="x_label">Sep</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="250.100087003" rx="0" ry="0" width="37.8761025641" x="457.447846154" y="279.515297613"></rect> <desc class="value">549927</desc> <desc class="x centered">476.385897436</desc> <desc class="y centered">404.565341114</desc> <desc class="x_label">Okt</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="415.840676584" rx="0" ry="0" width="37.8761025641" x="506.358102564" y="113.774708031"></rect> <desc class="value">914362</desc> <desc class="x centered">525.296153846</desc> <desc class="y centered">321.695046323</desc> <desc class="x_label">Nov</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="519.230769231" rx="0" ry="0" width="37.8761025641" x="555.268358974" y="10.3846153846"></rect> <desc class="value">1141699</desc> <desc class="x centered">574.206410256</desc> <desc class="y centered">270.0</desc> <desc class="x_label">Dez</desc> </g> </g> </g> </g> <g class="titles"></g> <g class="plot overlay" transform="translate(169, 20)"> <g class="series serie-0 color-0"></g> </g> <g class="plot text-overlay" transform="translate(169, 20)"> <g class="series serie-0 color-0"></g> </g> <g class="plot tooltip-overlay" transform="translate(169, 20)"> <g class="tooltip" style="opacity: 0" transform="translate(0 0)"> <rect class="tooltip-box" height="0" rx="0" ry="0" width="0"></rect> <g class="text"></g> </g> </g> <g class="legends" transform="translate(10, 30)"> <g class="legend reactive activate-serie" id="activate-serie-0"> <rect class="color-0 reactive" height="12" width="12" x="0.0" y="1.0"></rect> <text x="17.0" y="11.2">Incomming</text> </g> </g> <g class="legends" transform="translate(790, 30)"></g> </g> </svg> 
\ No newline at end of file
gelöscht static/images/posts/inout.svg
+0 −1
@@ -1 +0,0 @@
1 -
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" id="chart-9709354d-7015-48f2-b031-eadeaa28582c" class="pygal-chart" viewBox="0 0 800 600"> <!--Generated with pygal 2.4.0 (lxml) ©Kozea 2012-2016 on 2018-01-02--> <!--http://pygal.org--> <!--http://github.com/Kozea/pygal--> <defs> <style type="text/css">#chart-9709354d-7015-48f2-b031-eadeaa28582c{-webkit-user-select:none;-webkit-font-smoothing:antialiased;font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace}#chart-9709354d-7015-48f2-b031-eadeaa28582c .title{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-9709354d-7015-48f2-b031-eadeaa28582c .legends .legend text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis text.major{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-9709354d-7015-48f2-b031-eadeaa28582c .text-overlay text.value{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-9709354d-7015-48f2-b031-eadeaa28582c .text-overlay text.label{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-9709354d-7015-48f2-b031-eadeaa28582c .tooltip{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-9709354d-7015-48f2-b031-eadeaa28582c text.no_data{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:64px} #chart-9709354d-7015-48f2-b031-eadeaa28582c{background-color:rgba(249,249,249,1)}#chart-9709354d-7015-48f2-b031-eadeaa28582c path,#chart-9709354d-7015-48f2-b031-eadeaa28582c line,#chart-9709354d-7015-48f2-b031-eadeaa28582c rect,#chart-9709354d-7015-48f2-b031-eadeaa28582c circle{-webkit-transition:150ms;-moz-transition:150ms;transition:150ms}#chart-9709354d-7015-48f2-b031-eadeaa28582c .graph &gt; .background{fill:rgba(249,249,249,1)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .plot &gt; .background{fill:rgba(255,255,255,1)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .graph{fill:rgba(0,0,0,.87)}#chart-9709354d-7015-48f2-b031-eadeaa28582c text.no_data{fill:rgba(0,0,0,1)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .title{fill:rgba(0,0,0,1)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .legends .legend text{fill:rgba(0,0,0,.87)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .legends .legend:hover text{fill:rgba(0,0,0,1)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis .line{stroke:rgba(0,0,0,1)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis .guide.line{stroke:rgba(0,0,0,.54)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis .major.line{stroke:rgba(0,0,0,.87)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis text.major{fill:rgba(0,0,0,1)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis.y .guides:hover .guide.line,#chart-9709354d-7015-48f2-b031-eadeaa28582c .line-graph .axis.x .guides:hover .guide.line,#chart-9709354d-7015-48f2-b031-eadeaa28582c .stackedline-graph .axis.x .guides:hover .guide.line,#chart-9709354d-7015-48f2-b031-eadeaa28582c .xy-graph .axis.x .guides:hover .guide.line{stroke:rgba(0,0,0,1)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis .guides:hover text{fill:rgba(0,0,0,1)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .reactive{fill-opacity:.7;stroke-opacity:.8}#chart-9709354d-7015-48f2-b031-eadeaa28582c .ci{stroke:rgba(0,0,0,.87)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .reactive.active,#chart-9709354d-7015-48f2-b031-eadeaa28582c .active .reactive{fill-opacity:.8;stroke-opacity:.9;stroke-width:4}#chart-9709354d-7015-48f2-b031-eadeaa28582c .ci .reactive.active{stroke-width:1.5}#chart-9709354d-7015-48f2-b031-eadeaa28582c .series text{fill:rgba(0,0,0,1)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .tooltip rect{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,1);-webkit-transition:opacity 150ms;-moz-transition:opacity 150ms;transition:opacity 150ms}#chart-9709354d-7015-48f2-b031-eadeaa28582c .tooltip .label{fill:rgba(0,0,0,.87)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .tooltip .label{fill:rgba(0,0,0,.87)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .tooltip .legend{font-size:.8em;fill:rgba(0,0,0,.54)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .tooltip .x_label{font-size:.6em;fill:rgba(0,0,0,1)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .tooltip .xlink{font-size:.5em;text-decoration:underline}#chart-9709354d-7015-48f2-b031-eadeaa28582c .tooltip .value{font-size:1.5em}#chart-9709354d-7015-48f2-b031-eadeaa28582c .bound{font-size:.5em}#chart-9709354d-7015-48f2-b031-eadeaa28582c .max-value{font-size:.75em;fill:rgba(0,0,0,.54)}#chart-9709354d-7015-48f2-b031-eadeaa28582c .map-element{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,.54) !important}#chart-9709354d-7015-48f2-b031-eadeaa28582c .map-element .reactive{fill-opacity:inherit;stroke-opacity:inherit}#chart-9709354d-7015-48f2-b031-eadeaa28582c .color-0,#chart-9709354d-7015-48f2-b031-eadeaa28582c .color-0 a:visited{stroke:#F44336;fill:#F44336}#chart-9709354d-7015-48f2-b031-eadeaa28582c .color-1,#chart-9709354d-7015-48f2-b031-eadeaa28582c .color-1 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-9709354d-7015-48f2-b031-eadeaa28582c .text-overlay .color-0 text{fill:black}#chart-9709354d-7015-48f2-b031-eadeaa28582c .text-overlay .color-1 text{fill:black} #chart-9709354d-7015-48f2-b031-eadeaa28582c text.no_data{text-anchor:middle}#chart-9709354d-7015-48f2-b031-eadeaa28582c .guide.line{fill:none}#chart-9709354d-7015-48f2-b031-eadeaa28582c .centered{text-anchor:middle}#chart-9709354d-7015-48f2-b031-eadeaa28582c .title{text-anchor:middle}#chart-9709354d-7015-48f2-b031-eadeaa28582c .legends .legend text{fill-opacity:1}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis.x text{text-anchor:middle}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis.x:not(.web) text[transform]{text-anchor:start}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis.x:not(.web) text[transform].backwards{text-anchor:end}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis.y text{text-anchor:end}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis.y text[transform].backwards{text-anchor:start}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis.y2 text{text-anchor:start}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis.y2 text[transform].backwards{text-anchor:end}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis .guide.line{stroke-dasharray:4,4}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis .major.guide.line{stroke-dasharray:6,6}#chart-9709354d-7015-48f2-b031-eadeaa28582c .horizontal .axis.y .guide.line,#chart-9709354d-7015-48f2-b031-eadeaa28582c .horizontal .axis.y2 .guide.line,#chart-9709354d-7015-48f2-b031-eadeaa28582c .vertical .axis.x .guide.line{opacity:0}#chart-9709354d-7015-48f2-b031-eadeaa28582c .horizontal .axis.always_show .guide.line,#chart-9709354d-7015-48f2-b031-eadeaa28582c .vertical .axis.always_show .guide.line{opacity:1 !important}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis.y .guides:hover .guide.line,#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis.y2 .guides:hover .guide.line,#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis.x .guides:hover .guide.line{opacity:1}#chart-9709354d-7015-48f2-b031-eadeaa28582c .axis .guides:hover text{opacity:1}#chart-9709354d-7015-48f2-b031-eadeaa28582c .nofill{fill:none}#chart-9709354d-7015-48f2-b031-eadeaa28582c .subtle-fill{fill-opacity:.2}#chart-9709354d-7015-48f2-b031-eadeaa28582c .dot{stroke-width:1px;fill-opacity:1}#chart-9709354d-7015-48f2-b031-eadeaa28582c .dot.active{stroke-width:5px}#chart-9709354d-7015-48f2-b031-eadeaa28582c .dot.negative{fill:transparent}#chart-9709354d-7015-48f2-b031-eadeaa28582c text,#chart-9709354d-7015-48f2-b031-eadeaa28582c tspan{stroke:none !important}#chart-9709354d-7015-48f2-b031-eadeaa28582c .series text.active{opacity:1}#chart-9709354d-7015-48f2-b031-eadeaa28582c .tooltip rect{fill-opacity:.95;stroke-width:.5}#chart-9709354d-7015-48f2-b031-eadeaa28582c .tooltip text{fill-opacity:1}#chart-9709354d-7015-48f2-b031-eadeaa28582c .showable{visibility:hidden}#chart-9709354d-7015-48f2-b031-eadeaa28582c .showable.shown{visibility:visible}#chart-9709354d-7015-48f2-b031-eadeaa28582c .gauge-background{fill:rgba(229,229,229,1);stroke:none}#chart-9709354d-7015-48f2-b031-eadeaa28582c .bg-lines{stroke:rgba(249,249,249,1);stroke-width:2px}</style> </defs> <title>Pygal</title> <g class="graph bar-graph vertical"> <rect class="background" height="600" width="800" x="0" y="0"></rect> <g class="plot" transform="translate(169, 20)"> <rect class="background" height="540" width="610.4" x="0" y="0"></rect> <g class="axis y always_show"> <g class="guides"> <path class="axis major line" d="M0.000000 529.615385 h610.400000"></path> <text class="major" x="-5" y="533.115384615">0</text> <title>0</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 484.136605 h610.400000"></path> <text class="" x="-5" y="487.63660525">100000</text> <title>100000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 438.657826 h610.400000"></path> <text class="" x="-5" y="442.157825884">200000</text> <title>200000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 393.179047 h610.400000"></path> <text class="" x="-5" y="396.679046518">300000</text> <title>300000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 347.700267 h610.400000"></path> <text class="" x="-5" y="351.200267152">400000</text> <title>400000</title> </g> <g class="guides"> <path class="major guide line" d="M0.000000 302.221488 h610.400000"></path> <text class="major" x="-5" y="305.721487787">500000</text> <title>500000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 256.742708 h610.400000"></path> <text class="" x="-5" y="260.242708421">600000</text> <title>600000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 211.263929 h610.400000"></path> <text class="" x="-5" y="214.763929055">700000</text> <title>700000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 165.785150 h610.400000"></path> <text class="" x="-5" y="169.28514969">800000</text> <title>800000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 120.306370 h610.400000"></path> <text class="" x="-5" y="123.806370324">900000</text> <title>900000</title> </g> <g class="guides"> <path class="major guide line" d="M0.000000 74.827591 h610.400000"></path> <text class="major" x="-5" y="78.3275909581">1000000</text> <title>1000000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 29.348812 h610.400000"></path> <text class="" x="-5" y="32.8488115923">1100000</text> <title>1100000</title> </g> </g> <g class="axis x"> <path class="line" d="M0.000000 0.000000 v540.000000"></path> <g class="guides"> <path class="guide line" d="M36.193590 0.000000 v540.000000"></path> <text class="" x="36.1935897436" y="555.0">Jan</text> </g> <g class="guides"> <path class="guide line" d="M85.103846 0.000000 v540.000000"></path> <text class="" x="85.1038461538" y="555.0">Feb</text> </g> <g class="guides"> <path class="guide line" d="M134.014103 0.000000 v540.000000"></path> <text class="" x="134.014102564" y="555.0">Mar</text> </g> <g class="guides"> <path class="guide line" d="M182.924359 0.000000 v540.000000"></path> <text class="" x="182.924358974" y="555.0">Apr</text> </g> <g class="guides"> <path class="guide line" d="M231.834615 0.000000 v540.000000"></path> <text class="" x="231.834615385" y="555.0">Mai</text> </g> <g class="guides"> <path class="guide line" d="M280.744872 0.000000 v540.000000"></path> <text class="" x="280.744871795" y="555.0">Jun</text> </g> <g class="guides"> <path class="guide line" d="M329.655128 0.000000 v540.000000"></path> <text class="" x="329.655128205" y="555.0">Jul</text> </g> <g class="guides"> <path class="guide line" d="M378.565385 0.000000 v540.000000"></path> <text class="" x="378.565384615" y="555.0">Aug</text> </g> <g class="guides"> <path class="guide line" d="M427.475641 0.000000 v540.000000"></path> <text class="" x="427.475641026" y="555.0">Sep</text> </g> <g class="guides"> <path class="guide line" d="M476.385897 0.000000 v540.000000"></path> <text class="" x="476.385897436" y="555.0">Okt</text> </g> <g class="guides"> <path class="guide line" d="M525.296154 0.000000 v540.000000"></path> <text class="" x="525.296153846" y="555.0">Nov</text> </g> <g class="guides"> <path class="guide line" d="M574.206410 0.000000 v540.000000"></path> <text class="" x="574.206410256" y="555.0">Dez</text> </g> </g> <g class="series serie-0 color-0"> <g class="bars"> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="7.64725675035" rx="0" ry="0" width="18.9380512821" x="15.9643076923" y="521.968127865"></rect> <desc class="value">16815</desc> <desc class="x centered">25.4333333333</desc> <desc class="y centered">525.79175624</desc> <desc class="x_label">Jan</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.183279480844" rx="0" ry="0" width="18.9380512821" x="64.8745641026" y="529.432105135"></rect> <desc class="value">403</desc> <desc class="x centered">74.3435897436</desc> <desc class="y centered">529.523744875</desc> <desc class="x_label">Feb</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.202835355971" rx="0" ry="0" width="18.9380512821" x="113.784820513" y="529.412549259"></rect> <desc class="value">446</desc> <desc class="x centered">123.253846154</desc> <desc class="y centered">529.513966937</desc> <desc class="x_label">Mar</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="16.5888395614" rx="0" ry="0" width="18.9380512821" x="162.695076923" y="513.026545054"></rect> <desc class="value">36476</desc> <desc class="x centered">172.164102564</desc> <desc class="y centered">521.320964835</desc> <desc class="x_label">Apr</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="279.816376228" rx="0" ry="0" width="18.9380512821" x="211.605333333" y="249.799008387"></rect> <desc class="value">615268</desc> <desc class="x centered">221.074358974</desc> <desc class="y centered">389.707196501</desc> <desc class="x_label">Mai</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="302.317002319" rx="0" ry="0" width="18.9380512821" x="260.515589744" y="227.298382296"></rect> <desc class="value">664743</desc> <desc class="x centered">269.984615385</desc> <desc class="y centered">378.456883456</desc> <desc class="x_label">Jun</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="230.647903492" rx="0" ry="0" width="18.9380512821" x="309.425846154" y="298.967481123"></rect> <desc class="value">507155</desc> <desc class="x centered">318.894871795</desc> <desc class="y centered">414.291432869</desc> <desc class="x_label">Jul</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="214.573428925" rx="0" ry="0" width="18.9380512821" x="358.336102564" y="315.04195569"></rect> <desc class="value">471810</desc> <desc class="x centered">367.805128205</desc> <desc class="y centered">422.328670153</desc> <desc class="x_label">Aug</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="194.831090803" rx="0" ry="0" width="18.9380512821" x="407.246358974" y="334.784293813"></rect> <desc class="value">428400</desc> <desc class="x centered">416.715384615</desc> <desc class="y centered">432.199839214</desc> <desc class="x_label">Sep</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="250.100087003" rx="0" ry="0" width="18.9380512821" x="456.156615385" y="279.515297613"></rect> <desc class="value">549927</desc> <desc class="x centered">465.625641026</desc> <desc class="y centered">404.565341114</desc> <desc class="x_label">Okt</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="415.840676584" rx="0" ry="0" width="18.9380512821" x="505.066871795" y="113.774708031"></rect> <desc class="value">914362</desc> <desc class="x centered">514.535897436</desc> <desc class="y centered">321.695046323</desc> <desc class="x_label">Nov</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="519.230769231" rx="0" ry="0" width="18.9380512821" x="553.977128205" y="10.3846153846"></rect> <desc class="value">1141699</desc> <desc class="x centered">563.446153846</desc> <desc class="y centered">270.0</desc> <desc class="x_label">Dez</desc> </g> </g> </g> <g class="series serie-1 color-1"> <g class="bars"> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="1.87554486104" rx="0" ry="0" width="18.9380512821" x="37.4848205128" y="527.739839754"></rect> <desc class="value">4124</desc> <desc class="x centered">46.9538461538</desc> <desc class="y centered">528.677612185</desc> <desc class="x_label">Jan</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.490261241563" rx="0" ry="0" width="18.9380512821" x="86.3950769231" y="529.125123374"></rect> <desc class="value">1078</desc> <desc class="x centered">95.8641025641</desc> <desc class="y centered">529.370253995</desc> <desc class="x_label">Feb</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.545290564595" rx="0" ry="0" width="18.9380512821" x="135.305333333" y="529.070094051"></rect> <desc class="value">1199</desc> <desc class="x centered">144.774358974</desc> <desc class="y centered">529.342739333</desc> <desc class="x_label">Mar</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="1.12059712357" rx="0" ry="0" width="18.9380512821" x="184.215589744" y="528.494787492"></rect> <desc class="value">2464</desc> <desc class="x centered">193.684615385</desc> <desc class="y centered">529.055086054</desc> <desc class="x_label">Apr</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="42.2857142665" rx="0" ry="0" width="18.9380512821" x="233.125846154" y="487.329670349"></rect> <desc class="value">92979</desc> <desc class="x centered">242.594871795</desc> <desc class="y centered">508.472527482</desc> <desc class="x_label">Mai</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="62.9435402178" rx="0" ry="0" width="18.9380512821" x="282.036102564" y="466.671844398"></rect> <desc class="value">138402</desc> <desc class="x centered">291.505128205</desc> <desc class="y centered">498.143614507</desc> <desc class="x_label">Jun</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="52.9400279085" rx="0" ry="0" width="18.9380512821" x="330.946358974" y="476.675356707"></rect> <desc class="value">116406</desc> <desc class="x centered">340.415384615</desc> <desc class="y centered">503.145370661</desc> <desc class="x_label">Jul</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="16.2150039951" rx="0" ry="0" width="18.9380512821" x="379.856615385" y="513.40038062"></rect> <desc class="value">35654</desc> <desc class="x centered">389.325641026</desc> <desc class="y centered">521.507882618</desc> <desc class="x_label">Aug</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="14.2630547847" rx="0" ry="0" width="18.9380512821" x="428.766871795" y="515.352329831"></rect> <desc class="value">31362</desc> <desc class="x centered">438.235897436</desc> <desc class="y centered">522.483857223</desc> <desc class="x_label">Sep</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="10.9476517689" rx="0" ry="0" width="18.9380512821" x="477.677128205" y="518.667732846"></rect> <desc class="value">24072</desc> <desc class="x centered">487.146153846</desc> <desc class="y centered">524.141558731</desc> <desc class="x_label">Okt</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="20.0538677613" rx="0" ry="0" width="18.9380512821" x="526.587384615" y="509.561516854"></rect> <desc class="value">44095</desc> <desc class="x centered">536.056410256</desc> <desc class="y centered">519.588450735</desc> <desc class="x_label">Nov</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="26.327210587" rx="0" ry="0" width="18.9380512821" x="575.497641026" y="503.288174028"></rect> <desc class="value">57889</desc> <desc class="x centered">584.966666667</desc> <desc class="y centered">516.451779322</desc> <desc class="x_label">Dez</desc> </g> </g> </g> </g> <g class="titles"></g> <g class="plot overlay" transform="translate(169, 20)"> <g class="series serie-0 color-0"></g> <g class="series serie-1 color-1"></g> </g> <g class="plot text-overlay" transform="translate(169, 20)"> <g class="series serie-0 color-0"></g> <g class="series serie-1 color-1"></g> </g> <g class="plot tooltip-overlay" transform="translate(169, 20)"> <g class="tooltip" style="opacity: 0" transform="translate(0 0)"> <rect class="tooltip-box" height="0" rx="0" ry="0" width="0"></rect> <g class="text"></g> </g> </g> <g class="legends" transform="translate(10, 30)"> <g class="legend reactive activate-serie" id="activate-serie-0"> <rect class="color-0 reactive" height="12" width="12" x="0.0" y="1.0"></rect> <text x="17.0" y="11.2">Incomming</text> </g> <g class="legend reactive activate-serie" id="activate-serie-1"> <rect class="color-1 reactive" height="12" width="12" x="0.0" y="22.0"></rect> <text x="17.0" y="32.2">Outgoing</text> </g> </g> <g class="legends" transform="translate(790, 30)"></g> </g> </svg> 
\ No newline at end of file
gelöscht static/images/posts/inoutstacked.svg
+0 −1
@@ -1 +0,0 @@
1 -
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" id="chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c" class="pygal-chart" viewBox="0 0 800 600"> <!--Generated with pygal 2.4.0 (lxml) ©Kozea 2012-2016 on 2018-01-02--> <!--http://pygal.org--> <!--http://github.com/Kozea/pygal--> <defs> <style type="text/css">#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c{-webkit-user-select:none;-webkit-font-smoothing:antialiased;font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .title{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .legends .legend text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis text.major{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .text-overlay text.value{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .text-overlay text.label{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .tooltip{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c text.no_data{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:64px} #chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c{background-color:rgba(249,249,249,1)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c path,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c line,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c rect,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c circle{-webkit-transition:150ms;-moz-transition:150ms;transition:150ms}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .graph &gt; .background{fill:rgba(249,249,249,1)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .plot &gt; .background{fill:rgba(255,255,255,1)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .graph{fill:rgba(0,0,0,.87)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c text.no_data{fill:rgba(0,0,0,1)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .title{fill:rgba(0,0,0,1)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .legends .legend text{fill:rgba(0,0,0,.87)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .legends .legend:hover text{fill:rgba(0,0,0,1)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis .line{stroke:rgba(0,0,0,1)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis .guide.line{stroke:rgba(0,0,0,.54)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis .major.line{stroke:rgba(0,0,0,.87)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis text.major{fill:rgba(0,0,0,1)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis.y .guides:hover .guide.line,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .line-graph .axis.x .guides:hover .guide.line,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .stackedline-graph .axis.x .guides:hover .guide.line,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .xy-graph .axis.x .guides:hover .guide.line{stroke:rgba(0,0,0,1)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis .guides:hover text{fill:rgba(0,0,0,1)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .reactive{fill-opacity:.7;stroke-opacity:.8}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .ci{stroke:rgba(0,0,0,.87)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .reactive.active,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .active .reactive{fill-opacity:.8;stroke-opacity:.9;stroke-width:4}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .ci .reactive.active{stroke-width:1.5}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .series text{fill:rgba(0,0,0,1)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .tooltip rect{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,1);-webkit-transition:opacity 150ms;-moz-transition:opacity 150ms;transition:opacity 150ms}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .tooltip .label{fill:rgba(0,0,0,.87)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .tooltip .label{fill:rgba(0,0,0,.87)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .tooltip .legend{font-size:.8em;fill:rgba(0,0,0,.54)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .tooltip .x_label{font-size:.6em;fill:rgba(0,0,0,1)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .tooltip .xlink{font-size:.5em;text-decoration:underline}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .tooltip .value{font-size:1.5em}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .bound{font-size:.5em}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .max-value{font-size:.75em;fill:rgba(0,0,0,.54)}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .map-element{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,.54) !important}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .map-element .reactive{fill-opacity:inherit;stroke-opacity:inherit}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .color-0,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .color-0 a:visited{stroke:#F44336;fill:#F44336}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .color-1,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .color-1 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .text-overlay .color-0 text{fill:black}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .text-overlay .color-1 text{fill:black} #chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c text.no_data{text-anchor:middle}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .guide.line{fill:none}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .centered{text-anchor:middle}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .title{text-anchor:middle}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .legends .legend text{fill-opacity:1}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis.x text{text-anchor:middle}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis.x:not(.web) text[transform]{text-anchor:start}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis.x:not(.web) text[transform].backwards{text-anchor:end}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis.y text{text-anchor:end}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis.y text[transform].backwards{text-anchor:start}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis.y2 text{text-anchor:start}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis.y2 text[transform].backwards{text-anchor:end}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis .guide.line{stroke-dasharray:4,4}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis .major.guide.line{stroke-dasharray:6,6}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .horizontal .axis.y .guide.line,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .horizontal .axis.y2 .guide.line,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .vertical .axis.x .guide.line{opacity:0}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .horizontal .axis.always_show .guide.line,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .vertical .axis.always_show .guide.line{opacity:1 !important}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis.y .guides:hover .guide.line,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis.y2 .guides:hover .guide.line,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis.x .guides:hover .guide.line{opacity:1}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .axis .guides:hover text{opacity:1}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .nofill{fill:none}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .subtle-fill{fill-opacity:.2}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .dot{stroke-width:1px;fill-opacity:1}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .dot.active{stroke-width:5px}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .dot.negative{fill:transparent}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c text,#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c tspan{stroke:none !important}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .series text.active{opacity:1}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .tooltip rect{fill-opacity:.95;stroke-width:.5}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .tooltip text{fill-opacity:1}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .showable{visibility:hidden}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .showable.shown{visibility:visible}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .gauge-background{fill:rgba(229,229,229,1);stroke:none}#chart-cb0298f6-7d64-42e6-a487-cfc5dc76aa8c .bg-lines{stroke:rgba(249,249,249,1);stroke-width:2px}</style> </defs> <title>Pygal</title> <g class="graph stackedbar-graph vertical"> <rect class="background" height="600" width="800" x="0" y="0"></rect> <g class="plot" transform="translate(169, 20)"> <rect class="background" height="540" width="610.4" x="0" y="0"></rect> <g class="axis y always_show"> <g class="guides"> <path class="axis major line" d="M0.000000 529.615385 h610.400000"></path> <text class="major" x="-5" y="533.115384615">0</text> <title>0</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 486.331293 h610.400000"></path> <text class="" x="-5" y="489.831292975">100000</text> <title>100000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 443.047201 h610.400000"></path> <text class="" x="-5" y="446.547201334">200000</text> <title>200000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 399.763110 h610.400000"></path> <text class="" x="-5" y="403.263109693">300000</text> <title>300000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 356.479018 h610.400000"></path> <text class="" x="-5" y="359.979018053">400000</text> <title>400000</title> </g> <g class="guides"> <path class="major guide line" d="M0.000000 313.194926 h610.400000"></path> <text class="major" x="-5" y="316.694926412">500000</text> <title>500000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 269.910835 h610.400000"></path> <text class="" x="-5" y="273.410834771">600000</text> <title>600000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 226.626743 h610.400000"></path> <text class="" x="-5" y="230.126743131">700000</text> <title>700000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 183.342651 h610.400000"></path> <text class="" x="-5" y="186.84265149">800000</text> <title>800000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 140.058560 h610.400000"></path> <text class="" x="-5" y="143.558559849">900000</text> <title>900000</title> </g> <g class="guides"> <path class="major guide line" d="M0.000000 96.774468 h610.400000"></path> <text class="major" x="-5" y="100.274468208">1000000</text> <title>1000000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 53.490377 h610.400000"></path> <text class="" x="-5" y="56.9903765677">1100000</text> <title>1100000</title> </g> </g> <g class="axis x"> <path class="line" d="M0.000000 0.000000 v540.000000"></path> <g class="guides"> <path class="guide line" d="M36.193590 0.000000 v540.000000"></path> <text class="" x="36.1935897436" y="555.0">Jan</text> </g> <g class="guides"> <path class="guide line" d="M85.103846 0.000000 v540.000000"></path> <text class="" x="85.1038461538" y="555.0">Feb</text> </g> <g class="guides"> <path class="guide line" d="M134.014103 0.000000 v540.000000"></path> <text class="" x="134.014102564" y="555.0">Mar</text> </g> <g class="guides"> <path class="guide line" d="M182.924359 0.000000 v540.000000"></path> <text class="" x="182.924358974" y="555.0">Apr</text> </g> <g class="guides"> <path class="guide line" d="M231.834615 0.000000 v540.000000"></path> <text class="" x="231.834615385" y="555.0">Mai</text> </g> <g class="guides"> <path class="guide line" d="M280.744872 0.000000 v540.000000"></path> <text class="" x="280.744871795" y="555.0">Jun</text> </g> <g class="guides"> <path class="guide line" d="M329.655128 0.000000 v540.000000"></path> <text class="" x="329.655128205" y="555.0">Jul</text> </g> <g class="guides"> <path class="guide line" d="M378.565385 0.000000 v540.000000"></path> <text class="" x="378.565384615" y="555.0">Aug</text> </g> <g class="guides"> <path class="guide line" d="M427.475641 0.000000 v540.000000"></path> <text class="" x="427.475641026" y="555.0">Sep</text> </g> <g class="guides"> <path class="guide line" d="M476.385897 0.000000 v540.000000"></path> <text class="" x="476.385897436" y="555.0">Okt</text> </g> <g class="guides"> <path class="guide line" d="M525.296154 0.000000 v540.000000"></path> <text class="" x="525.296153846" y="555.0">Nov</text> </g> <g class="guides"> <path class="guide line" d="M574.206410 0.000000 v540.000000"></path> <text class="" x="574.206410256" y="555.0">Dez</text> </g> </g> <g class="series serie-0 color-0"> <g class="bars"> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="7.27822000938" rx="0" ry="0" width="43.041025641" x="14.6730769231" y="522.337164606"></rect> <desc class="value">16815</desc> <desc class="x centered">36.1935897436</desc> <desc class="y centered">525.976274611</desc> <desc class="x_label">Jan</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.174434889312" rx="0" ry="0" width="43.041025641" x="63.5833333333" y="529.440949726"></rect> <desc class="value">403</desc> <desc class="x centered">85.1038461538</desc> <desc class="y centered">529.528167171</desc> <desc class="x_label">Feb</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.193047048718" rx="0" ry="0" width="43.041025641" x="112.493589744" y="529.422337567"></rect> <desc class="value">446</desc> <desc class="x centered">134.014102564</desc> <desc class="y centered">529.518861091</desc> <desc class="x_label">Mar</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="15.7883052669" rx="0" ry="0" width="43.041025641" x="161.403846154" y="513.827079349"></rect> <desc class="value">36476</desc> <desc class="x centered">182.924358974</desc> <desc class="y centered">521.721231982</desc> <desc class="x_label">Apr</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="266.313164956" rx="0" ry="0" width="43.041025641" x="210.314102564" y="263.30221966"></rect> <desc class="value">615268</desc> <desc class="x centered">231.834615385</desc> <desc class="y centered">396.458802137</desc> <desc class="x_label">Mai</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="287.727969295" rx="0" ry="0" width="43.041025641" x="259.224358974" y="241.88741532"></rect> <desc class="value">664743</desc> <desc class="x centered">280.744871795</desc> <desc class="y centered">385.751399968</desc> <desc class="x_label">Jun</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="219.51743496" rx="0" ry="0" width="43.041025641" x="308.134615385" y="310.097949655"></rect> <desc class="value">507155</desc> <desc class="x centered">329.655128205</desc> <desc class="y centered">419.856667135</desc> <desc class="x_label">Jul</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="204.21867277" rx="0" ry="0" width="43.041025641" x="357.044871795" y="325.396711845"></rect> <desc class="value">471810</desc> <desc class="x centered">378.565384615</desc> <desc class="y centered">427.50604823</desc> <desc class="x_label">Aug</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="185.429048589" rx="0" ry="0" width="43.041025641" x="405.955128205" y="344.186336027"></rect> <desc class="value">428400</desc> <desc class="x centered">427.475641026</desc> <desc class="y centered">436.900860321</desc> <desc class="x_label">Sep</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="238.030906637" rx="0" ry="0" width="43.041025641" x="454.865384615" y="291.584477978"></rect> <desc class="value">549927</desc> <desc class="x centered">476.385897436</desc> <desc class="y centered">410.599931297</desc> <desc class="x_label">Okt</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="395.773286008" rx="0" ry="0" width="43.041025641" x="503.775641026" y="133.842098608"></rect> <desc class="value">914362</desc> <desc class="x centered">525.296153846</desc> <desc class="y centered">331.728741612</desc> <desc class="x_label">Nov</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="494.174041421" rx="0" ry="0" width="43.041025641" x="552.685897436" y="35.4413431945"></rect> <desc class="value">1141699</desc> <desc class="x centered">574.206410256</desc> <desc class="y centered">282.528363905</desc> <desc class="x_label">Dez</desc> </g> </g> </g> <g class="series serie-1 color-1"> <g class="bars"> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="1.78503593926" rx="0" ry="0" width="43.041025641" x="14.6730769231" y="520.552128667"></rect> <desc class="value">4124</desc> <desc class="x centered">36.1935897436</desc> <desc class="y centered">521.444646636</desc> <desc class="x_label">Jan</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.466602507887" rx="0" ry="0" width="43.041025641" x="63.5833333333" y="528.974347218"></rect> <desc class="value">1078</desc> <desc class="x centered">85.1038461538</desc> <desc class="y centered">529.207648472</desc> <desc class="x_label">Feb</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.518976258772" rx="0" ry="0" width="43.041025641" x="112.493589744" y="528.903361308"></rect> <desc class="value">1199</desc> <desc class="x centered">134.014102564</desc> <desc class="y centered">529.162849437</desc> <desc class="x_label">Mar</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="1.06652001803" rx="0" ry="0" width="43.041025641" x="161.403846154" y="512.76055933"></rect> <desc class="value">2464</desc> <desc class="x centered">182.924358974</desc> <desc class="y centered">513.29381934</desc> <desc class="x_label">Apr</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="40.2451155666" rx="0" ry="0" width="43.041025641" x="210.314102564" y="223.057104093"></rect> <desc class="value">92979</desc> <desc class="x centered">231.834615385</desc> <desc class="y centered">243.179661876</desc> <desc class="x_label">Mai</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="59.9060485126" rx="0" ry="0" width="43.041025641" x="259.224358974" y="181.981366808"></rect> <desc class="value">138402</desc> <desc class="x centered">280.744871795</desc> <desc class="y centered">211.934391064</desc> <desc class="x_label">Jun</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="50.3852797153" rx="0" ry="0" width="43.041025641" x="308.134615385" y="259.71266994"></rect> <desc class="value">116406</desc> <desc class="x centered">329.655128205</desc> <desc class="y centered">284.905309797</desc> <desc class="x_label">Jul</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="15.4325100336" rx="0" ry="0" width="43.041025641" x="357.044871795" y="309.964201812"></rect> <desc class="value">35654</desc> <desc class="x centered">378.565384615</desc> <desc class="y centered">317.680456829</desc> <desc class="x_label">Aug</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="13.5747568204" rx="0" ry="0" width="43.041025641" x="405.955128205" y="330.611579206"></rect> <desc class="value">31362</desc> <desc class="x centered">427.475641026</desc> <desc class="y centered">337.398957616</desc> <desc class="x_label">Sep</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="10.4193465397" rx="0" ry="0" width="43.041025641" x="454.865384615" y="281.165131439"></rect> <desc class="value">24072</desc> <desc class="x centered">476.385897436</desc> <desc class="y centered">286.374804709</desc> <desc class="x_label">Okt</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="19.086120209" rx="0" ry="0" width="43.041025641" x="503.775641026" y="114.755978399"></rect> <desc class="value">44095</desc> <desc class="x centered">525.296153846</desc> <desc class="y centered">124.299038503</desc> <desc class="x_label">Nov</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="25.0567278099" rx="0" ry="0" width="43.041025641" x="552.685897436" y="10.3846153846"></rect> <desc class="value">57889</desc> <desc class="x centered">574.206410256</desc> <desc class="y centered">22.9129792896</desc> <desc class="x_label">Dez</desc> </g> </g> </g> </g> <g class="titles"></g> <g class="plot overlay" transform="translate(169, 20)"> <g class="series serie-0 color-0"></g> <g class="series serie-1 color-1"></g> </g> <g class="plot text-overlay" transform="translate(169, 20)"> <g class="series serie-0 color-0"></g> <g class="series serie-1 color-1"></g> </g> <g class="plot tooltip-overlay" transform="translate(169, 20)"> <g class="tooltip" style="opacity: 0" transform="translate(0 0)"> <rect class="tooltip-box" height="0" rx="0" ry="0" width="0"></rect> <g class="text"></g> </g> </g> <g class="legends" transform="translate(10, 30)"> <g class="legend reactive activate-serie" id="activate-serie-0"> <rect class="color-0 reactive" height="12" width="12" x="0.0" y="1.0"></rect> <text x="17.0" y="11.2">Incomming</text> </g> <g class="legend reactive activate-serie" id="activate-serie-1"> <rect class="color-1 reactive" height="12" width="12" x="0.0" y="22.0"></rect> <text x="17.0" y="32.2">Outgoing</text> </g> </g> <g class="legends" transform="translate(790, 30)"></g> </g> </svg> 
\ No newline at end of file
gelöscht static/images/posts/ioBroker-keller.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/ioBroker-keller.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/ioBroker-kueche.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/ioBroker-kueche.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/ioBroker-wohnzimmer.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/ioBroker-wohnzimmer.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/movie_v4.gif
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/outgoing.svg
+0 −1
@@ -1 +0,0 @@
1 -
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" id="chart-81cac860-bc94-4923-a62e-2662a0dd99e1" class="pygal-chart" viewBox="0 0 800 600"> <!--Generated with pygal 2.4.0 (lxml) ©Kozea 2012-2016 on 2018-01-02--> <!--http://pygal.org--> <!--http://github.com/Kozea/pygal--> <defs> <style type="text/css">#chart-81cac860-bc94-4923-a62e-2662a0dd99e1{-webkit-user-select:none;-webkit-font-smoothing:antialiased;font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .title{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .legends .legend text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis text.major{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .text-overlay text.value{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .text-overlay text.label{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .tooltip{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 text.no_data{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:64px} #chart-81cac860-bc94-4923-a62e-2662a0dd99e1{background-color:rgba(249,249,249,1)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 path,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 line,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 rect,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 circle{-webkit-transition:150ms;-moz-transition:150ms;transition:150ms}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .graph &gt; .background{fill:rgba(249,249,249,1)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .plot &gt; .background{fill:rgba(255,255,255,1)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .graph{fill:rgba(0,0,0,.87)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 text.no_data{fill:rgba(0,0,0,1)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .title{fill:rgba(0,0,0,1)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .legends .legend text{fill:rgba(0,0,0,.87)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .legends .legend:hover text{fill:rgba(0,0,0,1)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis .line{stroke:rgba(0,0,0,1)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis .guide.line{stroke:rgba(0,0,0,.54)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis .major.line{stroke:rgba(0,0,0,.87)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis text.major{fill:rgba(0,0,0,1)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis.y .guides:hover .guide.line,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .line-graph .axis.x .guides:hover .guide.line,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .stackedline-graph .axis.x .guides:hover .guide.line,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .xy-graph .axis.x .guides:hover .guide.line{stroke:rgba(0,0,0,1)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis .guides:hover text{fill:rgba(0,0,0,1)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .reactive{fill-opacity:.7;stroke-opacity:.8}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .ci{stroke:rgba(0,0,0,.87)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .reactive.active,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .active .reactive{fill-opacity:.8;stroke-opacity:.9;stroke-width:4}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .ci .reactive.active{stroke-width:1.5}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .series text{fill:rgba(0,0,0,1)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .tooltip rect{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,1);-webkit-transition:opacity 150ms;-moz-transition:opacity 150ms;transition:opacity 150ms}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .tooltip .label{fill:rgba(0,0,0,.87)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .tooltip .label{fill:rgba(0,0,0,.87)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .tooltip .legend{font-size:.8em;fill:rgba(0,0,0,.54)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .tooltip .x_label{font-size:.6em;fill:rgba(0,0,0,1)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .tooltip .xlink{font-size:.5em;text-decoration:underline}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .tooltip .value{font-size:1.5em}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .bound{font-size:.5em}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .max-value{font-size:.75em;fill:rgba(0,0,0,.54)}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .map-element{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,.54) !important}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .map-element .reactive{fill-opacity:inherit;stroke-opacity:inherit}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .color-0,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .color-0 a:visited{stroke:#F44336;fill:#F44336}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .text-overlay .color-0 text{fill:black} #chart-81cac860-bc94-4923-a62e-2662a0dd99e1 text.no_data{text-anchor:middle}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .guide.line{fill:none}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .centered{text-anchor:middle}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .title{text-anchor:middle}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .legends .legend text{fill-opacity:1}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis.x text{text-anchor:middle}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis.x:not(.web) text[transform]{text-anchor:start}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis.x:not(.web) text[transform].backwards{text-anchor:end}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis.y text{text-anchor:end}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis.y text[transform].backwards{text-anchor:start}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis.y2 text{text-anchor:start}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis.y2 text[transform].backwards{text-anchor:end}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis .guide.line{stroke-dasharray:4,4}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis .major.guide.line{stroke-dasharray:6,6}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .horizontal .axis.y .guide.line,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .horizontal .axis.y2 .guide.line,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .vertical .axis.x .guide.line{opacity:0}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .horizontal .axis.always_show .guide.line,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .vertical .axis.always_show .guide.line{opacity:1 !important}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis.y .guides:hover .guide.line,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis.y2 .guides:hover .guide.line,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis.x .guides:hover .guide.line{opacity:1}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .axis .guides:hover text{opacity:1}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .nofill{fill:none}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .subtle-fill{fill-opacity:.2}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .dot{stroke-width:1px;fill-opacity:1}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .dot.active{stroke-width:5px}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .dot.negative{fill:transparent}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 text,#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 tspan{stroke:none !important}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .series text.active{opacity:1}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .tooltip rect{fill-opacity:.95;stroke-width:.5}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .tooltip text{fill-opacity:1}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .showable{visibility:hidden}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .showable.shown{visibility:visible}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .gauge-background{fill:rgba(229,229,229,1);stroke:none}#chart-81cac860-bc94-4923-a62e-2662a0dd99e1 .bg-lines{stroke:rgba(249,249,249,1);stroke-width:2px}</style> </defs> <title>Pygal</title> <g class="graph bar-graph vertical"> <rect class="background" height="600" width="800" x="0" y="0"></rect> <g class="plot" transform="translate(155, 20)"> <rect class="background" height="540" width="624.8" x="0" y="0"></rect> <g class="axis y always_show"> <g class="guides"> <path class="axis major line" d="M0.000000 529.615385 h624.800000"></path> <text class="major" x="-5" y="533.115384615">0</text> <title>0</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 492.099253 h624.800000"></path> <text class="" x="-5" y="495.599252679">10000</text> <title>10000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 454.583121 h624.800000"></path> <text class="" x="-5" y="458.083120742">20000</text> <title>20000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 417.066989 h624.800000"></path> <text class="" x="-5" y="420.566988805">30000</text> <title>30000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 379.550857 h624.800000"></path> <text class="" x="-5" y="383.050856868">40000</text> <title>40000</title> </g> <g class="guides"> <path class="major guide line" d="M0.000000 342.034725 h624.800000"></path> <text class="major" x="-5" y="345.534724932">50000</text> <title>50000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 304.518593 h624.800000"></path> <text class="" x="-5" y="308.018592995">60000</text> <title>60000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 267.002461 h624.800000"></path> <text class="" x="-5" y="270.502461058">70000</text> <title>70000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 229.486329 h624.800000"></path> <text class="" x="-5" y="232.986329122">80000</text> <title>80000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 191.970197 h624.800000"></path> <text class="" x="-5" y="195.470197185">90000</text> <title>90000</title> </g> <g class="guides"> <path class="major guide line" d="M0.000000 154.454065 h624.800000"></path> <text class="major" x="-5" y="157.954065248">100000</text> <title>100000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 116.937933 h624.800000"></path> <text class="" x="-5" y="120.437933311">110000</text> <title>110000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 79.421801 h624.800000"></path> <text class="" x="-5" y="82.9218013746">120000</text> <title>120000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 41.905669 h624.800000"></path> <text class="" x="-5" y="45.4056694379">130000</text> <title>130000</title> </g> </g> <g class="axis x"> <path class="line" d="M0.000000 0.000000 v540.000000"></path> <g class="guides"> <path class="guide line" d="M37.047436 0.000000 v540.000000"></path> <text class="" x="37.0474358974" y="555.0">Jan</text> </g> <g class="guides"> <path class="guide line" d="M87.111538 0.000000 v540.000000"></path> <text class="" x="87.1115384615" y="555.0">Feb</text> </g> <g class="guides"> <path class="guide line" d="M137.175641 0.000000 v540.000000"></path> <text class="" x="137.175641026" y="555.0">Mar</text> </g> <g class="guides"> <path class="guide line" d="M187.239744 0.000000 v540.000000"></path> <text class="" x="187.23974359" y="555.0">Apr</text> </g> <g class="guides"> <path class="guide line" d="M237.303846 0.000000 v540.000000"></path> <text class="" x="237.303846154" y="555.0">Mai</text> </g> <g class="guides"> <path class="guide line" d="M287.367949 0.000000 v540.000000"></path> <text class="" x="287.367948718" y="555.0">Jun</text> </g> <g class="guides"> <path class="guide line" d="M337.432051 0.000000 v540.000000"></path> <text class="" x="337.432051282" y="555.0">Jul</text> </g> <g class="guides"> <path class="guide line" d="M387.496154 0.000000 v540.000000"></path> <text class="" x="387.496153846" y="555.0">Aug</text> </g> <g class="guides"> <path class="guide line" d="M437.560256 0.000000 v540.000000"></path> <text class="" x="437.56025641" y="555.0">Sep</text> </g> <g class="guides"> <path class="guide line" d="M487.624359 0.000000 v540.000000"></path> <text class="" x="487.624358974" y="555.0">Okt</text> </g> <g class="guides"> <path class="guide line" d="M537.688462 0.000000 v540.000000"></path> <text class="" x="537.688461538" y="555.0">Nov</text> </g> <g class="guides"> <path class="guide line" d="M587.752564 0.000000 v540.000000"></path> <text class="" x="587.752564103" y="555.0">Dez</text> </g> </g> <g class="series serie-0 color-0"> <g class="bars"> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="15.4716528107" rx="0" ry="0" width="38.7696410256" x="17.6626153846" y="514.143731805"></rect> <desc class="value">4124</desc> <desc class="x centered">37.0474358974</desc> <desc class="y centered">521.87955821</desc> <desc class="x_label">Jan</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="4.04423902278" rx="0" ry="0" width="38.7696410256" x="67.7267179487" y="525.571145593"></rect> <desc class="value">1078</desc> <desc class="x centered">87.1115384615</desc> <desc class="y centered">527.593265104</desc> <desc class="x_label">Feb</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="4.49818421921" rx="0" ry="0" width="38.7696410256" x="117.790820513" y="525.117200396"></rect> <desc class="value">1199</desc> <desc class="x centered">137.175641026</desc> <desc class="y centered">527.366292506</desc> <desc class="x_label">Mar</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="9.24397490921" rx="0" ry="0" width="38.7696410256" x="167.854923077" y="520.371409706"></rect> <desc class="value">2464</desc> <desc class="x centered">187.23974359</desc> <desc class="y centered">524.993397161</desc> <desc class="x_label">Apr</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="348.821243135" rx="0" ry="0" width="38.7696410256" x="217.919025641" y="180.794141481"></rect> <desc class="value">92979</desc> <desc class="x centered">237.303846154</desc> <desc class="y centered">355.204763048</desc> <desc class="x_label">Mai</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="519.230769231" rx="0" ry="0" width="38.7696410256" x="267.983128205" y="10.3846153846"></rect> <desc class="value">138402</desc> <desc class="x centered">287.367948718</desc> <desc class="y centered">270.0</desc> <desc class="x_label">Jun</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="436.710285423" rx="0" ry="0" width="38.7696410256" x="318.047230769" y="92.9050991927"></rect> <desc class="value">116406</desc> <desc class="x centered">337.432051282</desc> <desc class="y centered">311.260241904</desc> <desc class="x_label">Jul</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="133.760016807" rx="0" ry="0" width="38.7696410256" x="368.111333333" y="395.855367808"></rect> <desc class="value">35654</desc> <desc class="x centered">387.496153846</desc> <desc class="y centered">462.735376212</desc> <desc class="x_label">Aug</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="117.65809298" rx="0" ry="0" width="38.7696410256" x="418.175435897" y="411.957291635"></rect> <desc class="value">31362</desc> <desc class="x centered">437.56025641</desc> <desc class="y centered">470.786338125</desc> <desc class="x_label">Sep</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="90.3088327981" rx="0" ry="0" width="38.7696410256" x="468.239538462" y="439.306551817"></rect> <desc class="value">24072</desc> <desc class="x centered">487.624358974</desc> <desc class="y centered">484.460968216</desc> <desc class="x_label">Okt</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="165.427383775" rx="0" ry="0" width="38.7696410256" x="518.303641026" y="364.18800084"></rect> <desc class="value">44095</desc> <desc class="x centered">537.688461538</desc> <desc class="y centered">446.901692728</desc> <desc class="x_label">Nov</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="217.177136169" rx="0" ry="0" width="38.7696410256" x="568.36774359" y="312.438248447"></rect> <desc class="value">57889</desc> <desc class="x centered">587.752564103</desc> <desc class="y centered">421.026816531</desc> <desc class="x_label">Dez</desc> </g> </g> </g> </g> <g class="titles"></g> <g class="plot overlay" transform="translate(155, 20)"> <g class="series serie-0 color-0"></g> </g> <g class="plot text-overlay" transform="translate(155, 20)"> <g class="series serie-0 color-0"></g> </g> <g class="plot tooltip-overlay" transform="translate(155, 20)"> <g class="tooltip" style="opacity: 0" transform="translate(0 0)"> <rect class="tooltip-box" height="0" rx="0" ry="0" width="0"></rect> <g class="text"></g> </g> </g> <g class="legends" transform="translate(10, 30)"> <g class="legend reactive activate-serie" id="activate-serie-0"> <rect class="color-0 reactive" height="12" width="12" x="0.0" y="1.0"></rect> <text x="17.0" y="11.2">Outgoing</text> </g> </g> <g class="legends" transform="translate(790, 30)"></g> </g> </svg> 
\ No newline at end of file
gelöscht static/images/posts/output.svg
+0 −1
@@ -1 +0,0 @@
1 -
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" id="chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a" class="pygal-chart" viewBox="0 0 800 600"> <!--Generated with pygal 2.4.0 (lxml) ©Kozea 2012-2016 on 2018-01-02--> <!--http://pygal.org--> <!--http://github.com/Kozea/pygal--> <defs> <style type="text/css">#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a{-webkit-user-select:none;-webkit-font-smoothing:antialiased;font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .title{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .legends .legend text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis text.major{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .text-overlay text.value{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .text-overlay text.label{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .tooltip{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a text.no_data{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:64px} #chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a{background-color:rgba(249,249,249,1)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a path,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a line,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a rect,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a circle{-webkit-transition:150ms;-moz-transition:150ms;transition:150ms}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .graph &gt; .background{fill:rgba(249,249,249,1)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .plot &gt; .background{fill:rgba(255,255,255,1)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .graph{fill:rgba(0,0,0,.87)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a text.no_data{fill:rgba(0,0,0,1)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .title{fill:rgba(0,0,0,1)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .legends .legend text{fill:rgba(0,0,0,.87)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .legends .legend:hover text{fill:rgba(0,0,0,1)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis .line{stroke:rgba(0,0,0,1)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis .guide.line{stroke:rgba(0,0,0,.54)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis .major.line{stroke:rgba(0,0,0,.87)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis text.major{fill:rgba(0,0,0,1)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis.y .guides:hover .guide.line,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .line-graph .axis.x .guides:hover .guide.line,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .stackedline-graph .axis.x .guides:hover .guide.line,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .xy-graph .axis.x .guides:hover .guide.line{stroke:rgba(0,0,0,1)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis .guides:hover text{fill:rgba(0,0,0,1)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .reactive{fill-opacity:.7;stroke-opacity:.8}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .ci{stroke:rgba(0,0,0,.87)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .reactive.active,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .active .reactive{fill-opacity:.8;stroke-opacity:.9;stroke-width:4}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .ci .reactive.active{stroke-width:1.5}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .series text{fill:rgba(0,0,0,1)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .tooltip rect{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,1);-webkit-transition:opacity 150ms;-moz-transition:opacity 150ms;transition:opacity 150ms}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .tooltip .label{fill:rgba(0,0,0,.87)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .tooltip .label{fill:rgba(0,0,0,.87)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .tooltip .legend{font-size:.8em;fill:rgba(0,0,0,.54)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .tooltip .x_label{font-size:.6em;fill:rgba(0,0,0,1)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .tooltip .xlink{font-size:.5em;text-decoration:underline}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .tooltip .value{font-size:1.5em}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .bound{font-size:.5em}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .max-value{font-size:.75em;fill:rgba(0,0,0,.54)}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .map-element{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,.54) !important}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .map-element .reactive{fill-opacity:inherit;stroke-opacity:inherit}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .color-0,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .color-0 a:visited{stroke:#F44336;fill:#F44336}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .color-1,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .color-1 a:visited{stroke:#3F51B5;fill:#3F51B5}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .color-2,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .color-2 a:visited{stroke:#009688;fill:#009688}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .text-overlay .color-0 text{fill:black}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .text-overlay .color-1 text{fill:black}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .text-overlay .color-2 text{fill:black} #chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a text.no_data{text-anchor:middle}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .guide.line{fill:none}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .centered{text-anchor:middle}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .title{text-anchor:middle}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .legends .legend text{fill-opacity:1}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis.x text{text-anchor:middle}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis.x:not(.web) text[transform]{text-anchor:start}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis.x:not(.web) text[transform].backwards{text-anchor:end}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis.y text{text-anchor:end}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis.y text[transform].backwards{text-anchor:start}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis.y2 text{text-anchor:start}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis.y2 text[transform].backwards{text-anchor:end}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis .guide.line{stroke-dasharray:4,4}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis .major.guide.line{stroke-dasharray:6,6}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .horizontal .axis.y .guide.line,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .horizontal .axis.y2 .guide.line,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .vertical .axis.x .guide.line{opacity:0}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .horizontal .axis.always_show .guide.line,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .vertical .axis.always_show .guide.line{opacity:1 !important}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis.y .guides:hover .guide.line,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis.y2 .guides:hover .guide.line,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis.x .guides:hover .guide.line{opacity:1}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .axis .guides:hover text{opacity:1}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .nofill{fill:none}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .subtle-fill{fill-opacity:.2}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .dot{stroke-width:1px;fill-opacity:1}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .dot.active{stroke-width:5px}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .dot.negative{fill:transparent}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a text,#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a tspan{stroke:none !important}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .series text.active{opacity:1}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .tooltip rect{fill-opacity:.95;stroke-width:.5}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .tooltip text{fill-opacity:1}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .showable{visibility:hidden}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .showable.shown{visibility:visible}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .gauge-background{fill:rgba(229,229,229,1);stroke:none}#chart-f702e70e-14b4-42e0-a76c-1ea99a8f548a .bg-lines{stroke:rgba(249,249,249,1);stroke-width:2px}</style> </defs> <title>Pygal</title> <g class="graph bar-graph vertical"> <rect class="background" height="600" width="800" x="0" y="0"></rect> <g class="plot" transform="translate(169, 20)"> <rect class="background" height="540" width="610.4" x="0" y="0"></rect> <g class="axis y always_show"> <g class="guides"> <path class="axis major line" d="M0.000000 529.615385 h610.400000"></path> <text class="major" x="-5" y="533.115384615">0</text> <title>0</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 486.331293 h610.400000"></path> <text class="" x="-5" y="489.831292975">100000</text> <title>100000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 443.047201 h610.400000"></path> <text class="" x="-5" y="446.547201334">200000</text> <title>200000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 399.763110 h610.400000"></path> <text class="" x="-5" y="403.263109693">300000</text> <title>300000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 356.479018 h610.400000"></path> <text class="" x="-5" y="359.979018053">400000</text> <title>400000</title> </g> <g class="guides"> <path class="major guide line" d="M0.000000 313.194926 h610.400000"></path> <text class="major" x="-5" y="316.694926412">500000</text> <title>500000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 269.910835 h610.400000"></path> <text class="" x="-5" y="273.410834771">600000</text> <title>600000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 226.626743 h610.400000"></path> <text class="" x="-5" y="230.126743131">700000</text> <title>700000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 183.342651 h610.400000"></path> <text class="" x="-5" y="186.84265149">800000</text> <title>800000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 140.058560 h610.400000"></path> <text class="" x="-5" y="143.558559849">900000</text> <title>900000</title> </g> <g class="guides"> <path class="major guide line" d="M0.000000 96.774468 h610.400000"></path> <text class="major" x="-5" y="100.274468208">1000000</text> <title>1000000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 53.490377 h610.400000"></path> <text class="" x="-5" y="56.9903765677">1100000</text> <title>1100000</title> </g> </g> <g class="axis x"> <path class="line" d="M0.000000 0.000000 v540.000000"></path> <g class="guides"> <path class="guide line" d="M36.193590 0.000000 v540.000000"></path> <text class="" x="36.1935897436" y="555.0">Jan</text> </g> <g class="guides"> <path class="guide line" d="M85.103846 0.000000 v540.000000"></path> <text class="" x="85.1038461538" y="555.0">Feb</text> </g> <g class="guides"> <path class="guide line" d="M134.014103 0.000000 v540.000000"></path> <text class="" x="134.014102564" y="555.0">Mar</text> </g> <g class="guides"> <path class="guide line" d="M182.924359 0.000000 v540.000000"></path> <text class="" x="182.924358974" y="555.0">Apr</text> </g> <g class="guides"> <path class="guide line" d="M231.834615 0.000000 v540.000000"></path> <text class="" x="231.834615385" y="555.0">Mai</text> </g> <g class="guides"> <path class="guide line" d="M280.744872 0.000000 v540.000000"></path> <text class="" x="280.744871795" y="555.0">Jun</text> </g> <g class="guides"> <path class="guide line" d="M329.655128 0.000000 v540.000000"></path> <text class="" x="329.655128205" y="555.0">Jul</text> </g> <g class="guides"> <path class="guide line" d="M378.565385 0.000000 v540.000000"></path> <text class="" x="378.565384615" y="555.0">Aug</text> </g> <g class="guides"> <path class="guide line" d="M427.475641 0.000000 v540.000000"></path> <text class="" x="427.475641026" y="555.0">Sep</text> </g> <g class="guides"> <path class="guide line" d="M476.385897 0.000000 v540.000000"></path> <text class="" x="476.385897436" y="555.0">Okt</text> </g> <g class="guides"> <path class="guide line" d="M525.296154 0.000000 v540.000000"></path> <text class="" x="525.296153846" y="555.0">Nov</text> </g> <g class="guides"> <path class="guide line" d="M574.206410 0.000000 v540.000000"></path> <text class="" x="574.206410256" y="555.0">Dez</text> </g> </g> <g class="series serie-0 color-0"> <g class="bars"> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="7.27822000938" rx="0" ry="0" width="12.6253675214" x="15.5338974359" y="522.337164606"></rect> <desc class="value">16815</desc> <desc class="x centered">21.8465811966</desc> <desc class="y centered">525.976274611</desc> <desc class="x_label">Jan</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.174434889312" rx="0" ry="0" width="12.6253675214" x="64.4441538462" y="529.440949726"></rect> <desc class="value">403</desc> <desc class="x centered">70.7568376068</desc> <desc class="y centered">529.528167171</desc> <desc class="x_label">Feb</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.193047048718" rx="0" ry="0" width="12.6253675214" x="113.354410256" y="529.422337567"></rect> <desc class="value">446</desc> <desc class="x centered">119.667094017</desc> <desc class="y centered">529.518861091</desc> <desc class="x_label">Mar</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="15.7883052669" rx="0" ry="0" width="12.6253675214" x="162.264666667" y="513.827079349"></rect> <desc class="value">36476</desc> <desc class="x centered">168.577350427</desc> <desc class="y centered">521.721231982</desc> <desc class="x_label">Apr</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="266.313164956" rx="0" ry="0" width="12.6253675214" x="211.174923077" y="263.30221966"></rect> <desc class="value">615268</desc> <desc class="x centered">217.487606838</desc> <desc class="y centered">396.458802137</desc> <desc class="x_label">Mai</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="287.727969295" rx="0" ry="0" width="12.6253675214" x="260.085179487" y="241.88741532"></rect> <desc class="value">664743</desc> <desc class="x centered">266.397863248</desc> <desc class="y centered">385.751399968</desc> <desc class="x_label">Jun</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="219.51743496" rx="0" ry="0" width="12.6253675214" x="308.995435897" y="310.097949655"></rect> <desc class="value">507155</desc> <desc class="x centered">315.308119658</desc> <desc class="y centered">419.856667135</desc> <desc class="x_label">Jul</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="204.21867277" rx="0" ry="0" width="12.6253675214" x="357.905692308" y="325.396711845"></rect> <desc class="value">471810</desc> <desc class="x centered">364.218376068</desc> <desc class="y centered">427.50604823</desc> <desc class="x_label">Aug</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="185.429048589" rx="0" ry="0" width="12.6253675214" x="406.815948718" y="344.186336027"></rect> <desc class="value">428400</desc> <desc class="x centered">413.128632479</desc> <desc class="y centered">436.900860321</desc> <desc class="x_label">Sep</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="238.030906637" rx="0" ry="0" width="12.6253675214" x="455.726205128" y="291.584477978"></rect> <desc class="value">549927</desc> <desc class="x centered">462.038888889</desc> <desc class="y centered">410.599931297</desc> <desc class="x_label">Okt</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="395.773286008" rx="0" ry="0" width="12.6253675214" x="504.636461538" y="133.842098608"></rect> <desc class="value">914362</desc> <desc class="x centered">510.949145299</desc> <desc class="y centered">331.728741612</desc> <desc class="x_label">Nov</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="494.174041421" rx="0" ry="0" width="12.6253675214" x="553.546717949" y="35.4413431945"></rect> <desc class="value">1141699</desc> <desc class="x centered">559.859401709</desc> <desc class="y centered">282.528363905</desc> <desc class="x_label">Dez</desc> </g> </g> </g> <g class="series serie-1 color-1"> <g class="bars"> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="1.78503593926" rx="0" ry="0" width="12.6253675214" x="29.8809059829" y="527.830348676"></rect> <desc class="value">4124</desc> <desc class="x centered">36.1935897436</desc> <desc class="y centered">528.722866646</desc> <desc class="x_label">Jan</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.466602507887" rx="0" ry="0" width="12.6253675214" x="78.7911623932" y="529.148782107"></rect> <desc class="value">1078</desc> <desc class="x centered">85.1038461538</desc> <desc class="y centered">529.382083361</desc> <desc class="x_label">Feb</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.518976258772" rx="0" ry="0" width="12.6253675214" x="127.701418803" y="529.096408357"></rect> <desc class="value">1199</desc> <desc class="x centered">134.014102564</desc> <desc class="y centered">529.355896486</desc> <desc class="x_label">Mar</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="1.06652001803" rx="0" ry="0" width="12.6253675214" x="176.611675214" y="528.548864597"></rect> <desc class="value">2464</desc> <desc class="x centered">182.924358974</desc> <desc class="y centered">529.082124606</desc> <desc class="x_label">Apr</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="40.2451155666" rx="0" ry="0" width="12.6253675214" x="225.521931624" y="489.370269049"></rect> <desc class="value">92979</desc> <desc class="x centered">231.834615385</desc> <desc class="y centered">509.492826832</desc> <desc class="x_label">Mai</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="59.9060485126" rx="0" ry="0" width="12.6253675214" x="274.432188034" y="469.709336103"></rect> <desc class="value">138402</desc> <desc class="x centered">280.744871795</desc> <desc class="y centered">499.662360359</desc> <desc class="x_label">Jun</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="50.3852797153" rx="0" ry="0" width="12.6253675214" x="323.342444444" y="479.2301049"></rect> <desc class="value">116406</desc> <desc class="x centered">329.655128205</desc> <desc class="y centered">504.422744758</desc> <desc class="x_label">Jul</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="15.4325100336" rx="0" ry="0" width="12.6253675214" x="372.252700855" y="514.182874582"></rect> <desc class="value">35654</desc> <desc class="x centered">378.565384615</desc> <desc class="y centered">521.899129599</desc> <desc class="x_label">Aug</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="13.5747568204" rx="0" ry="0" width="12.6253675214" x="421.162957265" y="516.040627795"></rect> <desc class="value">31362</desc> <desc class="x centered">427.475641026</desc> <desc class="y centered">522.828006205</desc> <desc class="x_label">Sep</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="10.4193465397" rx="0" ry="0" width="12.6253675214" x="470.073213675" y="519.196038076"></rect> <desc class="value">24072</desc> <desc class="x centered">476.385897436</desc> <desc class="y centered">524.405711346</desc> <desc class="x_label">Okt</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="19.086120209" rx="0" ry="0" width="12.6253675214" x="518.983470085" y="510.529264406"></rect> <desc class="value">44095</desc> <desc class="x centered">525.296153846</desc> <desc class="y centered">520.072324511</desc> <desc class="x_label">Nov</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="25.0567278099" rx="0" ry="0" width="12.6253675214" x="567.893726496" y="504.558656806"></rect> <desc class="value">57889</desc> <desc class="x centered">574.206410256</desc> <desc class="y centered">517.08702071</desc> <desc class="x_label">Dez</desc> </g> </g> </g> <g class="series serie-2 color-2"> <g class="bars"> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="9.06325594864" rx="0" ry="0" width="12.6253675214" x="44.2279145299" y="520.552128667"></rect> <desc class="value">20939</desc> <desc class="x centered">50.5405982906</desc> <desc class="y centered">525.083756641</desc> <desc class="x_label">Jan</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.641037397199" rx="0" ry="0" width="12.6253675214" x="93.1381709402" y="528.974347218"></rect> <desc class="value">1481</desc> <desc class="x centered">99.4508547009</desc> <desc class="y centered">529.294865917</desc> <desc class="x_label">Feb</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.712023307489" rx="0" ry="0" width="12.6253675214" x="142.04842735" y="528.903361308"></rect> <desc class="value">1645</desc> <desc class="x centered">148.361111111</desc> <desc class="y centered">529.259372962</desc> <desc class="x_label">Mar</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="16.8548252849" rx="0" ry="0" width="12.6253675214" x="190.958683761" y="512.76055933"></rect> <desc class="value">38940</desc> <desc class="x centered">197.271367521</desc> <desc class="y centered">521.187971973</desc> <desc class="x_label">Apr</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="306.558280522" rx="0" ry="0" width="12.6253675214" x="239.868940171" y="223.057104093"></rect> <desc class="value">708247</desc> <desc class="x centered">246.181623932</desc> <desc class="y centered">376.336244354</desc> <desc class="x_label">Mai</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="347.634017808" rx="0" ry="0" width="12.6253675214" x="288.779196581" y="181.981366808"></rect> <desc class="value">803145</desc> <desc class="x centered">295.091880342</desc> <desc class="y centered">355.798375712</desc> <desc class="x_label">Jun</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="269.902714676" rx="0" ry="0" width="12.6253675214" x="337.689452991" y="259.71266994"></rect> <desc class="value">623561</desc> <desc class="x centered">344.002136752</desc> <desc class="y centered">394.664027278</desc> <desc class="x_label">Jul</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="219.651182804" rx="0" ry="0" width="12.6253675214" x="386.599709402" y="309.964201812"></rect> <desc class="value">507464</desc> <desc class="x centered">392.912393162</desc> <desc class="y centered">419.789793214</desc> <desc class="x_label">Aug</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="199.003805409" rx="0" ry="0" width="12.6253675214" x="435.509965812" y="330.611579206"></rect> <desc class="value">459762</desc> <desc class="x centered">441.822649573</desc> <desc class="y centered">430.113481911</desc> <desc class="x_label">Sep</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="248.450253177" rx="0" ry="0" width="12.6253675214" x="484.420222222" y="281.165131439"></rect> <desc class="value">573999</desc> <desc class="x centered">490.732905983</desc> <desc class="y centered">405.390258027</desc> <desc class="x_label">Okt</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="414.859406217" rx="0" ry="0" width="12.6253675214" x="533.330478632" y="114.755978399"></rect> <desc class="value">958457</desc> <desc class="x centered">539.643162393</desc> <desc class="y centered">322.185681507</desc> <desc class="x_label">Nov</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="519.230769231" rx="0" ry="0" width="12.6253675214" x="582.240735043" y="10.3846153846"></rect> <desc class="value">1199588</desc> <desc class="x centered">588.553418803</desc> <desc class="y centered">270.0</desc> <desc class="x_label">Dez</desc> </g> </g> </g> </g> <g class="titles"></g> <g class="plot overlay" transform="translate(169, 20)"> <g class="series serie-0 color-0"></g> <g class="series serie-1 color-1"></g> <g class="series serie-2 color-2"></g> </g> <g class="plot text-overlay" transform="translate(169, 20)"> <g class="series serie-0 color-0"></g> <g class="series serie-1 color-1"></g> <g class="series serie-2 color-2"></g> </g> <g class="plot tooltip-overlay" transform="translate(169, 20)"> <g class="tooltip" style="opacity: 0" transform="translate(0 0)"> <rect class="tooltip-box" height="0" rx="0" ry="0" width="0"></rect> <g class="text"></g> </g> </g> <g class="legends" transform="translate(10, 30)"> <g class="legend reactive activate-serie" id="activate-serie-0"> <rect class="color-0 reactive" height="12" width="12" x="0.0" y="1.0"></rect> <text x="17.0" y="11.2">Eingehend</text> </g> <g class="legend reactive activate-serie" id="activate-serie-1"> <rect class="color-1 reactive" height="12" width="12" x="0.0" y="22.0"></rect> <text x="17.0" y="32.2">Ausgehend</text> </g> <g class="legend reactive activate-serie" id="activate-serie-2"> <rect class="color-2 reactive" height="12" width="12" x="0.0" y="43.0"></rect> <text x="17.0" y="53.2">Gesamt</text> </g> </g> <g class="legends" transform="translate(790, 30)"></g> </g> </svg> 
\ No newline at end of file
gelöscht static/images/posts/raspbee2-intro-pic.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/raspbee2-intro-pic.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/sf4008.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/sf4008.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/sum.svg
+0 −1
@@ -1 +0,0 @@
1 -
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" id="chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762" class="pygal-chart" viewBox="0 0 800 600"> <!--Generated with pygal 2.4.0 (lxml) ©Kozea 2012-2016 on 2018-01-02--> <!--http://pygal.org--> <!--http://github.com/Kozea/pygal--> <defs> <style type="text/css">#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762{-webkit-user-select:none;-webkit-font-smoothing:antialiased;font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .title{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .legends .legend text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis text{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis text.major{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .text-overlay text.value{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:16px}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .text-overlay text.label{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:10px}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .tooltip{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:14px}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 text.no_data{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:64px} #chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762{background-color:rgba(249,249,249,1)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 path,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 line,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 rect,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 circle{-webkit-transition:150ms;-moz-transition:150ms;transition:150ms}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .graph &gt; .background{fill:rgba(249,249,249,1)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .plot &gt; .background{fill:rgba(255,255,255,1)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .graph{fill:rgba(0,0,0,.87)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 text.no_data{fill:rgba(0,0,0,1)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .title{fill:rgba(0,0,0,1)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .legends .legend text{fill:rgba(0,0,0,.87)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .legends .legend:hover text{fill:rgba(0,0,0,1)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis .line{stroke:rgba(0,0,0,1)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis .guide.line{stroke:rgba(0,0,0,.54)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis .major.line{stroke:rgba(0,0,0,.87)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis text.major{fill:rgba(0,0,0,1)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis.y .guides:hover .guide.line,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .line-graph .axis.x .guides:hover .guide.line,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .stackedline-graph .axis.x .guides:hover .guide.line,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .xy-graph .axis.x .guides:hover .guide.line{stroke:rgba(0,0,0,1)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis .guides:hover text{fill:rgba(0,0,0,1)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .reactive{fill-opacity:.7;stroke-opacity:.8}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .ci{stroke:rgba(0,0,0,.87)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .reactive.active,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .active .reactive{fill-opacity:.8;stroke-opacity:.9;stroke-width:4}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .ci .reactive.active{stroke-width:1.5}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .series text{fill:rgba(0,0,0,1)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .tooltip rect{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,1);-webkit-transition:opacity 150ms;-moz-transition:opacity 150ms;transition:opacity 150ms}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .tooltip .label{fill:rgba(0,0,0,.87)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .tooltip .label{fill:rgba(0,0,0,.87)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .tooltip .legend{font-size:.8em;fill:rgba(0,0,0,.54)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .tooltip .x_label{font-size:.6em;fill:rgba(0,0,0,1)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .tooltip .xlink{font-size:.5em;text-decoration:underline}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .tooltip .value{font-size:1.5em}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .bound{font-size:.5em}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .max-value{font-size:.75em;fill:rgba(0,0,0,.54)}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .map-element{fill:rgba(255,255,255,1);stroke:rgba(0,0,0,.54) !important}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .map-element .reactive{fill-opacity:inherit;stroke-opacity:inherit}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .color-0,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .color-0 a:visited{stroke:#F44336;fill:#F44336}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .text-overlay .color-0 text{fill:black} #chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 text.no_data{text-anchor:middle}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .guide.line{fill:none}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .centered{text-anchor:middle}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .title{text-anchor:middle}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .legends .legend text{fill-opacity:1}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis.x text{text-anchor:middle}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis.x:not(.web) text[transform]{text-anchor:start}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis.x:not(.web) text[transform].backwards{text-anchor:end}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis.y text{text-anchor:end}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis.y text[transform].backwards{text-anchor:start}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis.y2 text{text-anchor:start}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis.y2 text[transform].backwards{text-anchor:end}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis .guide.line{stroke-dasharray:4,4}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis .major.guide.line{stroke-dasharray:6,6}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .horizontal .axis.y .guide.line,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .horizontal .axis.y2 .guide.line,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .vertical .axis.x .guide.line{opacity:0}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .horizontal .axis.always_show .guide.line,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .vertical .axis.always_show .guide.line{opacity:1 !important}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis.y .guides:hover .guide.line,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis.y2 .guides:hover .guide.line,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis.x .guides:hover .guide.line{opacity:1}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .axis .guides:hover text{opacity:1}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .nofill{fill:none}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .subtle-fill{fill-opacity:.2}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .dot{stroke-width:1px;fill-opacity:1}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .dot.active{stroke-width:5px}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .dot.negative{fill:transparent}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 text,#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 tspan{stroke:none !important}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .series text.active{opacity:1}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .tooltip rect{fill-opacity:.95;stroke-width:.5}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .tooltip text{fill-opacity:1}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .showable{visibility:hidden}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .showable.shown{visibility:visible}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .gauge-background{fill:rgba(229,229,229,1);stroke:none}#chart-b4395bf0-7cbe-4351-97f9-89d6f3bd3762 .bg-lines{stroke:rgba(249,249,249,1);stroke-width:2px}</style> </defs> <title>Pygal</title> <g class="graph bar-graph vertical"> <rect class="background" height="600" width="800" x="0" y="0"></rect> <g class="plot" transform="translate(161, 20)"> <rect class="background" height="540" width="618.8" x="0" y="0"></rect> <g class="axis y always_show"> <g class="guides"> <path class="axis major line" d="M0.000000 529.615385 h618.800000"></path> <text class="major" x="-5" y="533.115384615">0</text> <title>0</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 486.331293 h618.800000"></path> <text class="" x="-5" y="489.831292975">100000</text> <title>100000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 443.047201 h618.800000"></path> <text class="" x="-5" y="446.547201334">200000</text> <title>200000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 399.763110 h618.800000"></path> <text class="" x="-5" y="403.263109693">300000</text> <title>300000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 356.479018 h618.800000"></path> <text class="" x="-5" y="359.979018053">400000</text> <title>400000</title> </g> <g class="guides"> <path class="major guide line" d="M0.000000 313.194926 h618.800000"></path> <text class="major" x="-5" y="316.694926412">500000</text> <title>500000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 269.910835 h618.800000"></path> <text class="" x="-5" y="273.410834771">600000</text> <title>600000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 226.626743 h618.800000"></path> <text class="" x="-5" y="230.126743131">700000</text> <title>700000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 183.342651 h618.800000"></path> <text class="" x="-5" y="186.84265149">800000</text> <title>800000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 140.058560 h618.800000"></path> <text class="" x="-5" y="143.558559849">900000</text> <title>900000</title> </g> <g class="guides"> <path class="major guide line" d="M0.000000 96.774468 h618.800000"></path> <text class="major" x="-5" y="100.274468208">1000000</text> <title>1000000</title> </g> <g class="guides"> <path class="guide line" d="M0.000000 53.490377 h618.800000"></path> <text class="" x="-5" y="56.9903765677">1100000</text> <title>1100000</title> </g> </g> <g class="axis x"> <path class="line" d="M0.000000 0.000000 v540.000000"></path> <g class="guides"> <path class="guide line" d="M36.691667 0.000000 v540.000000"></path> <text class="" x="36.6916666667" y="555.0">Jan</text> </g> <g class="guides"> <path class="guide line" d="M86.275000 0.000000 v540.000000"></path> <text class="" x="86.275" y="555.0">Feb</text> </g> <g class="guides"> <path class="guide line" d="M135.858333 0.000000 v540.000000"></path> <text class="" x="135.858333333" y="555.0">Mar</text> </g> <g class="guides"> <path class="guide line" d="M185.441667 0.000000 v540.000000"></path> <text class="" x="185.441666667" y="555.0">Apr</text> </g> <g class="guides"> <path class="guide line" d="M235.025000 0.000000 v540.000000"></path> <text class="" x="235.025" y="555.0">Mai</text> </g> <g class="guides"> <path class="guide line" d="M284.608333 0.000000 v540.000000"></path> <text class="" x="284.608333333" y="555.0">Jun</text> </g> <g class="guides"> <path class="guide line" d="M334.191667 0.000000 v540.000000"></path> <text class="" x="334.191666667" y="555.0">Jul</text> </g> <g class="guides"> <path class="guide line" d="M383.775000 0.000000 v540.000000"></path> <text class="" x="383.775" y="555.0">Aug</text> </g> <g class="guides"> <path class="guide line" d="M433.358333 0.000000 v540.000000"></path> <text class="" x="433.358333333" y="555.0">Sep</text> </g> <g class="guides"> <path class="guide line" d="M482.941667 0.000000 v540.000000"></path> <text class="" x="482.941666667" y="555.0">Okt</text> </g> <g class="guides"> <path class="guide line" d="M532.525000 0.000000 v540.000000"></path> <text class="" x="532.525" y="555.0">Nov</text> </g> <g class="guides"> <path class="guide line" d="M582.108333 0.000000 v540.000000"></path> <text class="" x="582.108333333" y="555.0">Dez</text> </g> </g> <g class="series serie-0 color-0"> <g class="bars"> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="9.06325594864" rx="0" ry="0" width="38.3973333333" x="17.493" y="520.552128667"></rect> <desc class="value">20939</desc> <desc class="x centered">36.6916666667</desc> <desc class="y centered">525.083756641</desc> <desc class="x_label">Jan</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.641037397199" rx="0" ry="0" width="38.3973333333" x="67.0763333333" y="528.974347218"></rect> <desc class="value">1481</desc> <desc class="x centered">86.275</desc> <desc class="y centered">529.294865917</desc> <desc class="x_label">Feb</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="0.712023307489" rx="0" ry="0" width="38.3973333333" x="116.659666667" y="528.903361308"></rect> <desc class="value">1645</desc> <desc class="x centered">135.858333333</desc> <desc class="y centered">529.259372962</desc> <desc class="x_label">Mar</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="16.8548252849" rx="0" ry="0" width="38.3973333333" x="166.243" y="512.76055933"></rect> <desc class="value">38940</desc> <desc class="x centered">185.441666667</desc> <desc class="y centered">521.187971973</desc> <desc class="x_label">Apr</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="306.558280522" rx="0" ry="0" width="38.3973333333" x="215.826333333" y="223.057104093"></rect> <desc class="value">708247</desc> <desc class="x centered">235.025</desc> <desc class="y centered">376.336244354</desc> <desc class="x_label">Mai</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="347.634017808" rx="0" ry="0" width="38.3973333333" x="265.409666667" y="181.981366808"></rect> <desc class="value">803145</desc> <desc class="x centered">284.608333333</desc> <desc class="y centered">355.798375712</desc> <desc class="x_label">Jun</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="269.902714676" rx="0" ry="0" width="38.3973333333" x="314.993" y="259.71266994"></rect> <desc class="value">623561</desc> <desc class="x centered">334.191666667</desc> <desc class="y centered">394.664027278</desc> <desc class="x_label">Jul</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="219.651182804" rx="0" ry="0" width="38.3973333333" x="364.576333333" y="309.964201812"></rect> <desc class="value">507464</desc> <desc class="x centered">383.775</desc> <desc class="y centered">419.789793214</desc> <desc class="x_label">Aug</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="199.003805409" rx="0" ry="0" width="38.3973333333" x="414.159666667" y="330.611579206"></rect> <desc class="value">459762</desc> <desc class="x centered">433.358333333</desc> <desc class="y centered">430.113481911</desc> <desc class="x_label">Sep</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="248.450253177" rx="0" ry="0" width="38.3973333333" x="463.743" y="281.165131439"></rect> <desc class="value">573999</desc> <desc class="x centered">482.941666667</desc> <desc class="y centered">405.390258027</desc> <desc class="x_label">Okt</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="414.859406217" rx="0" ry="0" width="38.3973333333" x="513.326333333" y="114.755978399"></rect> <desc class="value">958457</desc> <desc class="x centered">532.525</desc> <desc class="y centered">322.185681507</desc> <desc class="x_label">Nov</desc> </g> <g class="bar"> <rect class="rect reactive tooltip-trigger" height="519.230769231" rx="0" ry="0" width="38.3973333333" x="562.909666667" y="10.3846153846"></rect> <desc class="value">1199588</desc> <desc class="x centered">582.108333333</desc> <desc class="y centered">270.0</desc> <desc class="x_label">Dez</desc> </g> </g> </g> </g> <g class="titles"></g> <g class="plot overlay" transform="translate(161, 20)"> <g class="series serie-0 color-0"></g> </g> <g class="plot text-overlay" transform="translate(161, 20)"> <g class="series serie-0 color-0"></g> </g> <g class="plot tooltip-overlay" transform="translate(161, 20)"> <g class="tooltip" style="opacity: 0" transform="translate(0 0)"> <rect class="tooltip-box" height="0" rx="0" ry="0" width="0"></rect> <g class="text"></g> </g> </g> <g class="legends" transform="translate(10, 30)"> <g class="legend reactive activate-serie" id="activate-serie-0"> <rect class="color-0 reactive" height="12" width="12" x="0.0" y="1.0"></rect> <text x="17.0" y="11.2">In &amp; Out</text> </g> </g> <g class="legends" transform="translate(790, 30)"></g> </g> </svg> 
\ No newline at end of file
gelöscht static/images/posts/textcraft_pocket_screen.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/textcraft_pocket_screen.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/2019-08-10-Netzwerkumbau-VLANs-und-Firewall-1.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/2019-08-10-Netzwerkumbau-VLANs-und-Firewall-1.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/2019-08-10-Netzwerkumbau-VLANs-und-Firewall-1.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/2factor-1024x312.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/2factor-1024x312.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/2factor-1024x312.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Compressor-Dyna-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Compressor-Dyna-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Compressor-Dyna-300x225.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Compressor-Dyna-300x225.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/DB-Wifi-1-300x255.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/DB-Wifi-1-300x255.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/DB-Wifi-1-300x255.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/DB-Wifi-1.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/DB-Wifi-1.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/DB-Wifi-1.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/DB-Wifi-2.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/DB-Wifi-2.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/DB-Wifi-2.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/DB-Wifi-3.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/DB-Wifi-3.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/DB-Wifi-3.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Der-Compressor-Dyna-Compressor-Bausatz.jpg-300x300.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Der-Compressor-Dyna-Compressor-Bausatz.jpg-300x300.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Der-Compressor-Dyna-Compressor-Bausatz.jpg-300x300.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Der-Compressor-Dyna-Compressor-Bausatz.jpg.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Der-Compressor-Dyna-Compressor-Bausatz.jpg.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Der-Compressor-Dyna-Compressor-Bausatz.jpg.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1116-300x203.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1116-300x203.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1116.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1116.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1121-1-e1454456497787-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1121-1-e1454456497787-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1122-e1454456449498-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1122-e1454456449498-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1123-e1455287450903-150x150.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1123-e1455287450903-150x150.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1123-e1455287450903.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1123-e1455287450903.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1127-e1455234520305-150x150.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1127-e1455234520305-150x150.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1127-e1455234520305-768x1024.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1127-e1455234520305-768x1024.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1128-e1455234629727-150x150.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1128-e1455234629727-150x150.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1128-e1455234629727-768x1024.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1128-e1455234629727-768x1024.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1129-e1455234758942-150x150.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1129-e1455234758942-150x150.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1129-e1455234758942-768x1024.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1129-e1455234758942-768x1024.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1131-e1455234812127-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1131-e1455234812127-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1131-e1455234812127-150x150.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1131-e1455234812127-150x150.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1435-e1455138449549-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_1435-e1455138449549-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_7208-e1455138417739-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_7208-e1455138417739-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_7260-e1454339420251-225x300.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_7260-e1454339420251-225x300.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_7260-e1454339420251-768x1024.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_7260-e1454339420251-768x1024.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_9117-e1454339397491-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/IMG_9117-e1454339397491-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Mpow-Magneto-1-300x180.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Mpow-Magneto-1-300x180.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Mpow-Magneto-1.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Mpow-Magneto-1.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Mpow-Magneto-2-300x169.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Mpow-Magneto-2-300x169.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Mpow-Magneto-3-300x288.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/Mpow-Magneto-3-300x288.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/burger-n-truck.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/burger-n-truck.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/earpods-1-300x225.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/earpods-1-300x225.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/earpods-2-300x300.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/earpods-2-300x300.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/folders.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/folders.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/folders.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/fuzzy-300x240.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/fuzzy-300x240.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/fuzzy.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/fuzzy.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/github-actions-banner.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/github-actions-banner.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/github-actions-banner.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/goodmans.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/goodmans.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/goodmans.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/high-sierra-install-screen-300x255.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/high-sierra-install-screen-300x255.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/high-sierra-install-screen-300x255.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/high-sierra-install-screen.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/high-sierra-install-screen.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/high-sierra-install-screen.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0150.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0150.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0154.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0154.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0156.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0156.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0157-1.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0157-1.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0159.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0159.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0161-225x300.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0161-225x300.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0161.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_0161.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_1062-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_1062-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_1062-300x225.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_1062-300x225.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_1074.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_1074.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_1075.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_1075.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_5073-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_5073-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_5073-300x225.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_5073-300x225.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_5078-1024x768.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_5078-1024x768.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_5078-300x225.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/img_5078-300x225.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/ioBroker-keller.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/ioBroker-keller.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/ioBroker-keller.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/ioBroker-kueche.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/ioBroker-kueche.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/ioBroker-kueche.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/ioBroker-wohnzimmer.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/ioBroker-wohnzimmer.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/ioBroker-wohnzimmer.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/raspbee2-intro-pic.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/raspbee2-intro-pic.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/sf4008.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/sf4008.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/sf4008.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/textcraft_pocket_screen.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/textcraft_pocket_screen.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/traffic_2018.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/traffic_2018.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/traffic_2018.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/unifiy-pro.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/unifiy-pro.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/unifiy-pro.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/vcard-low.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/vcard-low.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/vcard-low.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/vcard.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/vcard.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/vcard.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/wifi-zugang.jpg
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/wifi-zugang.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/thumbs/wifi-zugang.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/traffic_2018.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/traffic_2018.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/unifiy-pro.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/unifiy-pro.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/vcard-low.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/vcard-low.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/vcard.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/vcard.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/wifi-zugang.png
+0 −0

Binärdatei – kein Textvergleich möglich.

gelöscht static/images/posts/wifi-zugang.webp
+0 −0

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/sommercamp-2026/sommercamp-1.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/sommercamp-2026/sommercamp-2.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/vorstand/david-v2.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/vorstand/david-v3.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/vorstand/david.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/vorstand/dominica-v2.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/vorstand/dominica.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/vorstand/placeholder.svg
+49 −0 Datei ansehen
@@ -0,0 +1,49 @@
1 +
<?xml version="1.0" encoding="UTF-8"?>
2 +
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" preserveAspectRatio="xMidYMid slice">
3 +
  <defs>
4 +
    <linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
5 +
      <stop offset="0%" stop-color="#1f1f1f"/>
6 +
      <stop offset="100%" stop-color="#0e0e0e"/>
7 +
    </linearGradient>
8 +
    <linearGradient id="fig" x1="0" y1="0" x2="0" y2="1">
9 +
      <stop offset="0%" stop-color="#f37021"/>
10 +
      <stop offset="100%" stop-color="#c5571a"/>
11 +
    </linearGradient>
12 +
    <linearGradient id="accent" x1="0" y1="0" x2="1" y2="0">
13 +
      <stop offset="0%"   stop-color="#f37021"/>
14 +
      <stop offset="50%"  stop-color="#ff7a2a"/>
15 +
      <stop offset="100%" stop-color="#f37021"/>
16 +
    </linearGradient>
17 +
  </defs>
18 +
19 +
  <!-- Hintergrund -->
20 +
  <rect width="400" height="400" fill="url(#bg)"/>
21 +
22 +
  <!-- EHC Kicker oben -->
23 +
  <text x="200" y="40" text-anchor="middle"
24 +
        font-family="Segoe UI, Tahoma, sans-serif"
25 +
        font-size="15" font-weight="700"
26 +
        letter-spacing="6" fill="#ffffff" opacity="0.55">EHC</text>
27 +
28 +
  <!-- Personen-Silhouette (mittig, etwas kompakter) -->
29 +
  <circle cx="200" cy="130" r="46" fill="url(#fig)" opacity="0.88"/>
30 +
  <path d="M 200 188 C 152 188, 118 226, 118 295 L 282 295 C 282 226, 248 188, 200 188 Z"
31 +
        fill="url(#fig)" opacity="0.88"/>
32 +
33 +
  <!-- Schwungvoller Pinselstrich als Trenner -->
34 +
  <path d="M 70 322 Q 200 308, 330 322"
35 +
        stroke="url(#accent)" stroke-width="3"
36 +
        fill="none" stroke-linecap="round" opacity="0.8"/>
37 +
38 +
  <!-- "WE ARE" Subtext -->
39 +
  <text x="200" y="352" text-anchor="middle"
40 +
        font-family="Georgia, 'Times New Roman', serif"
41 +
        font-size="13" font-weight="700"
42 +
        letter-spacing="6" fill="#ffffff" opacity="0.6">WE ARE</text>
43 +
44 +
  <!-- "FAMILY" Hauptzeile mit Gradient -->
45 +
  <text x="200" y="388" text-anchor="middle"
46 +
        font-family="Georgia, 'Times New Roman', serif"
47 +
        font-style="italic" font-size="30" font-weight="900"
48 +
        letter-spacing="2" fill="url(#accent)">FAMILY</text>
49 +
</svg>
hinzugefügt static/images/vorstand/stefan-v2.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt static/images/vorstand/stefan.webp
+0 −0 Datei ansehen

Binärdatei – kein Textvergleich möglich.

hinzugefügt themes/ehc/static/css/style.css
+888 −0 Datei ansehen
@@ -0,0 +1,888 @@
1 +
/* ============================================================
2 +
   EHC Essen (Ruhr) e.V. — Quilldrop Theme
3 +
   ============================================================ */
4 +
5 +
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
6 +
7 +
:root {
8 +
  --orange: #f37021;
9 +
  --orange-bright: #ff7a2a;
10 +
  --orange-dark: #c5571a;
11 +
  --black: #0a0a0a;
12 +
  --dark: #141414;
13 +
  --gray-mid: #2a2a2a;
14 +
  --gray-light: #b8b8b8;
15 +
  --silver: #d8d8d8;
16 +
  --white: #ffffff;
17 +
18 +
  --corner-img-w: 160px;
19 +
  --content-right-pad: 220px;
20 +
  --content-max: 1400px;
21 +
}
22 +
23 +
html { height: 100%; }
24 +
25 +
body {
26 +
  min-height: 100vh;
27 +
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
28 +
  color: var(--white);
29 +
  line-height: 1.65;
30 +
  background: var(--black);
31 +
  position: relative;
32 +
  display: flex;
33 +
  flex-direction: column;
34 +
}
35 +
36 +
a { color: #ff4c00; text-decoration: none; transition: color 0.2s ease; }
37 +
a:hover { color: var(--orange-bright); }
38 +
39 +
img { max-width: 100%; height: auto; display: block; }
40 +
41 +
/* ====== Fixierter Hintergrund + Overlay ====== */
42 +
.bg-fixed {
43 +
  position: fixed; inset: 0; z-index: -2;
44 +
  background-image: url('/images/ehc/ehc-steelers-bg.webp');
45 +
  background-size: cover; background-position: center;
46 +
  background-repeat: no-repeat; pointer-events: none;
47 +
}
48 +
.bg-overlay {
49 +
  position: fixed; inset: 0; z-index: -1;
50 +
  background: linear-gradient(180deg, rgba(0,0,0,0.25) 0%, rgba(0,0,0,0.45) 100%);
51 +
  pointer-events: none;
52 +
}
53 +
54 +
/* ====== NAVBAR ====== */
55 +
.navbar {
56 +
  position: sticky; top: 0; z-index: 100;
57 +
  background: linear-gradient(180deg, rgba(10,10,10,0.95) 0%, rgba(20,20,20,0.92) 100%);
58 +
  border-bottom: 3px solid #ff4c00;
59 +
  box-shadow: 0 6px 20px rgba(0,0,0,0.6);
60 +
  backdrop-filter: blur(6px);
61 +
  -webkit-backdrop-filter: blur(6px);
62 +
}
63 +
.nav-inner {
64 +
  max-width: var(--content-max);
65 +
  margin: 0 auto;
66 +
  padding: 12px 30px;
67 +
  display: flex; align-items: center;
68 +
  justify-content: space-between;
69 +
  gap: 30px;
70 +
}
71 +
.nav-brand {
72 +
  display: flex; align-items: center; gap: 14px;
73 +
  text-decoration: none; color: var(--white);
74 +
}
75 +
.nav-brand img {
76 +
  height: 64px; width: auto;
77 +
  filter: drop-shadow(0 4px 8px rgba(0,0,0,0.6));
78 +
}
79 +
.nav-brand-text { display: flex; flex-direction: column; line-height: 1.1; }
80 +
.nav-brand-text .name {
81 +
  font-size: 1.15rem; font-weight: 800; letter-spacing: 1.2px;
82 +
  text-transform: uppercase; color: var(--white);
83 +
}
84 +
.nav-brand-text .sub {
85 +
  font-size: 0.72rem; letter-spacing: 3px; color: #ff4c00;
86 +
  text-transform: uppercase; font-weight: 600;
87 +
}
88 +
.nav-brand:hover .nav-brand-text .name { color: #ff4c00; }
89 +
90 +
/* Nav links */
91 +
.nav-links {
92 +
  display: flex; align-items: center;
93 +
  gap: 4px; list-style: none;
94 +
}
95 +
.nav-links > a,
96 +
.nav-links .nav-dropdown > .nav-dropdown-toggle {
97 +
  display: inline-flex; align-items: center; gap: 6px;
98 +
  padding: 14px 18px;
99 +
  color: var(--white); text-decoration: none;
100 +
  font-size: 0.95rem; font-weight: 700;
101 +
  text-transform: uppercase; letter-spacing: 1.5px;
102 +
  border-radius: 4px; transition: all 0.25s ease;
103 +
  position: relative;
104 +
  background: transparent; border: none; cursor: pointer;
105 +
  font-family: inherit;
106 +
}
107 +
.nav-links > a::after,
108 +
.nav-links .nav-dropdown > .nav-dropdown-toggle::after {
109 +
  content: ""; position: absolute;
110 +
  left: 18px; right: 18px; bottom: 8px;
111 +
  height: 2px; background: #ff4c00;
112 +
  transform: scaleX(0); transform-origin: left;
113 +
  transition: transform 0.3s ease;
114 +
}
115 +
.nav-links > a:hover,
116 +
.nav-links .nav-dropdown:hover > .nav-dropdown-toggle,
117 +
.nav-links .nav-dropdown.open > .nav-dropdown-toggle {
118 +
  color: #ff4c00; background: rgba(243, 112, 33, 0.08);
119 +
}
120 +
.nav-links > a:hover::after,
121 +
.nav-links .nav-dropdown:hover > .nav-dropdown-toggle::after,
122 +
.nav-links .nav-dropdown.open > .nav-dropdown-toggle::after {
123 +
  transform: scaleX(1);
124 +
}
125 +
126 +
/* Dropdown */
127 +
.nav-dropdown { position: relative; }
128 +
.nav-dropdown-menu {
129 +
  position: absolute; top: 100%; left: 0;
130 +
  min-width: 220px;
131 +
  background: rgba(15, 15, 15, 0.98);
132 +
  border: 1px solid rgba(243, 112, 33, 0.4);
133 +
  border-top: 3px solid #ff4c00;
134 +
  padding: 8px 0;
135 +
  opacity: 0; visibility: hidden;
136 +
  transform: translateY(8px);
137 +
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
138 +
  box-shadow: 0 10px 30px rgba(0,0,0,0.7);
139 +
}
140 +
.nav-dropdown:hover > .nav-dropdown-menu,
141 +
.nav-dropdown.open > .nav-dropdown-menu {
142 +
  opacity: 1; visibility: visible; transform: translateY(0);
143 +
}
144 +
/* letztes Item: nach links öffnen, damit es nicht aus der Seite ragt */
145 +
.nav-links > .nav-dropdown:last-of-type > .nav-dropdown-menu { left: auto; right: 0; }
146 +
147 +
.nav-dropdown-menu a {
148 +
  display: block; padding: 10px 20px;
149 +
  color: var(--silver); text-decoration: none;
150 +
  font-size: 0.85rem; text-transform: uppercase;
151 +
  letter-spacing: 1px; font-weight: 600;
152 +
  border-left: 3px solid transparent;
153 +
  transition: all 0.2s ease;
154 +
}
155 +
.nav-dropdown-menu a:hover {
156 +
  color: var(--white); background: rgba(243, 112, 33, 0.15);
157 +
  border-left-color: #ff4c00; padding-left: 26px;
158 +
}
159 +
160 +
/* Search + RSS */
161 +
.search-container { position: relative; }
162 +
.search-toggle, .nav-rss {
163 +
  width: 36px; height: 36px;
164 +
  display: inline-flex; align-items: center; justify-content: center;
165 +
  background: rgba(255,255,255,0.05);
166 +
  border: 1px solid rgba(243, 112, 33, 0.25);
167 +
  border-radius: 50%;
168 +
  color: var(--silver); cursor: pointer;
169 +
  transition: all 0.2s ease;
170 +
  text-decoration: none;
171 +
}
172 +
.search-toggle:hover, .nav-rss:hover {
173 +
  color: #ff4c00; border-color: #ff4c00;
174 +
  background: rgba(243, 112, 33, 0.1);
175 +
}
176 +
.search-box {
177 +
  position: absolute; top: calc(100% + 8px); right: 0;
178 +
  width: 320px;
179 +
  background: rgba(15, 15, 15, 0.98);
180 +
  border: 1px solid rgba(243, 112, 33, 0.4);
181 +
  border-top: 3px solid #ff4c00;
182 +
  border-radius: 4px;
183 +
  padding: 12px;
184 +
  opacity: 0; visibility: hidden;
185 +
  transform: translateY(8px);
186 +
  transition: opacity 0.2s, transform 0.2s, visibility 0.2s;
187 +
  box-shadow: 0 10px 30px rgba(0,0,0,0.7);
188 +
}
189 +
.search-container.active .search-box {
190 +
  opacity: 1; visibility: visible; transform: translateY(0);
191 +
}
192 +
.search-box input {
193 +
  width: 100%; padding: 8px 12px;
194 +
  background: rgba(0,0,0,0.4);
195 +
  border: 1px solid rgba(243, 112, 33, 0.3);
196 +
  border-radius: 4px;
197 +
  color: var(--white);
198 +
  font-family: inherit; font-size: 0.95rem;
199 +
}
200 +
.search-box input:focus { outline: none; border-color: #ff4c00; }
201 +
.search-results { margin-top: 8px; max-height: 60vh; overflow-y: auto; }
202 +
.search-results a {
203 +
  display: block; padding: 8px 10px;
204 +
  color: var(--silver); border-radius: 4px;
205 +
  font-size: 0.88rem;
206 +
}
207 +
.search-results a:hover { background: rgba(243, 112, 33, 0.1); color: var(--white); }
208 +
.search-results .search-result-title { color: var(--white); font-weight: 600; display: block; }
209 +
.search-results .search-result-snippet { color: var(--gray-light); font-size: 0.8rem; display: block; margin-top: 2px; }
210 +
211 +
/* Hamburger (mobile) */
212 +
.hamburger { display: none; background: transparent; border: none; cursor: pointer; padding: 8px; }
213 +
.hamburger span {
214 +
  display: block; width: 24px; height: 2px;
215 +
  background: var(--white); margin: 5px 0;
216 +
  transition: all 0.3s ease;
217 +
}
218 +
.hamburger.active span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
219 +
.hamburger.active span:nth-child(2) { opacity: 0; }
220 +
.hamburger.active span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
221 +
222 +
/* ====== MAIN / CONTAINER ====== */
223 +
.container {
224 +
  max-width: var(--content-max);
225 +
  margin: 0 auto;
226 +
  padding: 40px 30px 60px;
227 +
  padding-right: var(--content-right-pad);
228 +
  flex: 1;
229 +
  width: 100%;
230 +
}
231 +
232 +
/* ====== HERO (Homepage) ====== */
233 +
.hero-image {
234 +
  margin-bottom: 32px;
235 +
  border-radius: 12px;
236 +
  overflow: hidden;
237 +
  box-shadow: 0 0 0 2px rgba(243, 112, 33, 0.7), 0 20px 60px rgba(0,0,0,0.7);
238 +
  position: relative;
239 +
}
240 +
.hero-image img { width: 100%; display: block; }
241 +
.hero-image::after {
242 +
  content: ""; position: absolute; inset: 0;
243 +
  background: linear-gradient(180deg, rgba(0,0,0,0) 60%, rgba(0,0,0,0.4) 100%);
244 +
  pointer-events: none;
245 +
}
246 +
247 +
/* ====== Sektionen ====== */
248 +
.section {
249 +
  background: rgba(15, 15, 15, 0.78);
250 +
  border: 1px solid rgba(255,255,255,0.06);
251 +
  border-radius: 10px;
252 +
  padding: 32px 36px;
253 +
  margin-bottom: 28px;
254 +
  box-shadow: 0 8px 30px rgba(0,0,0,0.5);
255 +
  backdrop-filter: blur(4px);
256 +
}
257 +
.section h2 {
258 +
  font-size: 1.8rem;
259 +
  text-transform: uppercase; letter-spacing: 2px;
260 +
  color: var(--white);
261 +
  margin-bottom: 0;
262 +
  padding-bottom: 12px;
263 +
  border-bottom: 2px solid #ff4c00;
264 +
  display: inline-block;
265 +
}
266 +
.section h2:not(.no-margin) { margin-bottom: 18px; }
267 +
.section p { color: var(--gray-light); margin-bottom: 12px; }
268 +
269 +
.section-head {
270 +
  display: flex; align-items: flex-end; justify-content: space-between;
271 +
  gap: 20px; margin-bottom: 18px; flex-wrap: wrap;
272 +
}
273 +
.section-head h2 { margin-bottom: 0; }
274 +
.all-link {
275 +
  color: #ff4c00; text-decoration: none;
276 +
  font-size: 0.9rem; font-weight: 700;
277 +
  letter-spacing: 1.5px; text-transform: uppercase;
278 +
  padding-bottom: 4px;
279 +
  transition: color 0.2s ease, transform 0.2s ease;
280 +
}
281 +
.all-link:hover { color: var(--orange-bright); transform: translateX(3px); }
282 +
283 +
/* ====== Partner Karussell ====== */
284 +
.partner-section {
285 +
  background: rgba(15, 15, 15, 0.78);
286 +
  border: 1px solid rgba(255,255,255,0.06);
287 +
  border-radius: 10px;
288 +
  padding: 32px 36px;
289 +
  margin-bottom: 28px;
290 +
  box-shadow: 0 8px 30px rgba(0,0,0,0.5);
291 +
  backdrop-filter: blur(4px);
292 +
}
293 +
.carousel { position: relative; overflow: hidden; padding: 10px 0; }
294 +
.carousel-track { display: flex; transition: transform 0.7s cubic-bezier(0.4, 0, 0.2, 1); will-change: transform; }
295 +
.carousel-slide {
296 +
  flex: 0 0 calc(100% / 3);
297 +
  padding: 0 14px;
298 +
  display: flex; align-items: center; justify-content: center;
299 +
}
300 +
.partner-link { display: block; width: 100%; text-decoration: none; }
301 +
.partner-card {
302 +
  width: 100%; height: 140px;
303 +
  background: var(--white);
304 +
  border-radius: 8px;
305 +
  display: flex; align-items: center; justify-content: center;
306 +
  padding: 18px;
307 +
  box-shadow: 0 6px 16px rgba(0,0,0,0.4);
308 +
  transition: transform 0.3s ease, box-shadow 0.3s ease;
309 +
}
310 +
.partner-card:hover {
311 +
  transform: translateY(-4px);
312 +
  box-shadow: 0 12px 24px rgba(243, 112, 33, 0.25);
313 +
}
314 +
.partner-card img { max-width: 100%; max-height: 100%; object-fit: contain; }
315 +
.carousel-dots { display: flex; justify-content: center; gap: 8px; margin-top: 20px; }
316 +
.carousel-dot {
317 +
  width: 10px; height: 10px; border-radius: 50%;
318 +
  background: rgba(255,255,255,0.25);
319 +
  border: none; cursor: pointer; padding: 0;
320 +
  transition: all 0.25s ease;
321 +
}
322 +
.carousel-dot.active { background: #ff4c00; transform: scale(1.3); }
323 +
324 +
/* ====== Post-Liste / News-Karten ====== */
325 +
.post-list {
326 +
  display: grid;
327 +
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
328 +
  gap: 24px;
329 +
}
330 +
.post-card {
331 +
  background: rgba(0,0,0,0.55);
332 +
  border: 1px solid rgba(243, 112, 33, 0.25);
333 +
  border-radius: 8px;
334 +
  overflow: hidden;
335 +
  display: flex; flex-direction: column;
336 +
  transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
337 +
}
338 +
.post-card:hover {
339 +
  border-color: #ff4c00;
340 +
  transform: translateY(-4px);
341 +
  box-shadow: 0 12px 28px rgba(243, 112, 33, 0.18);
342 +
}
343 +
.post-card-cover {
344 +
  display: block;
345 +
  aspect-ratio: 16 / 10;
346 +
  overflow: hidden;
347 +
  background: #1a1a1a;
348 +
}
349 +
.post-card-cover img {
350 +
  width: 100%; height: 100%;
351 +
  object-fit: cover;
352 +
  transition: transform 0.5s ease;
353 +
}
354 +
.post-card:hover .post-card-cover img { transform: scale(1.05); }
355 +
.post-card-body {
356 +
  padding: 20px 22px 22px;
357 +
  display: flex; flex-direction: column; gap: 10px;
358 +
  flex: 1;
359 +
}
360 +
.post-card-meta {
361 +
  display: flex; align-items: center; justify-content: space-between;
362 +
  gap: 10px; flex-wrap: wrap;
363 +
}
364 +
.post-card-meta time {
365 +
  color: #ff4c00;
366 +
  font-size: 0.75rem; font-weight: 700;
367 +
  letter-spacing: 1.8px; text-transform: uppercase;
368 +
}
369 +
.post-card-title { margin: 0; }
370 +
.post-card-title a {
371 +
  color: var(--white); text-decoration: none;
372 +
  font-size: 1.1rem; font-weight: 800; line-height: 1.3;
373 +
}
374 +
.post-card-title a:hover { color: #ff4c00; }
375 +
.post-card-preview { color: var(--gray-light); font-size: 0.92rem; flex: 1; margin: 0; }
376 +
.read-more {
377 +
  color: #ff4c00; text-decoration: none;
378 +
  font-size: 0.78rem; font-weight: 700;
379 +
  letter-spacing: 1.5px; text-transform: uppercase;
380 +
  margin-top: 4px; padding-top: 10px;
381 +
  border-top: 1px solid rgba(243, 112, 33, 0.2);
382 +
}
383 +
.post-card:hover .read-more { color: var(--orange-bright); }
384 +
385 +
/* Tags */
386 +
.post-tags { display: flex; flex-wrap: wrap; gap: 6px; }
387 +
.tag {
388 +
  display: inline-block;
389 +
  padding: 3px 10px;
390 +
  background: rgba(243, 112, 33, 0.1);
391 +
  border: 1px solid rgba(243, 112, 33, 0.35);
392 +
  border-radius: 12px;
393 +
  color: #ff4c00;
394 +
  font-size: 0.7rem; font-weight: 700;
395 +
  letter-spacing: 0.5px; text-transform: uppercase;
396 +
  text-decoration: none;
397 +
  transition: all 0.2s ease;
398 +
}
399 +
.tag:hover { background: rgba(243, 112, 33, 0.2); color: var(--orange-bright); }
400 +
.tag-large {
401 +
  font-size: 0.95rem;
402 +
  padding: 8px 16px;
403 +
  border-radius: 20px;
404 +
}
405 +
.tag-count {
406 +
  margin-left: 6px;
407 +
  padding: 1px 8px;
408 +
  background: rgba(243, 112, 33, 0.3);
409 +
  border-radius: 10px;
410 +
  font-size: 0.75rem;
411 +
}
412 +
413 +
/* ====== Single Post ====== */
414 +
.post-single, .page-single {
415 +
  background: rgba(15, 15, 15, 0.82);
416 +
  border: 1px solid rgba(255,255,255,0.06);
417 +
  border-radius: 10px;
418 +
  padding: 36px 40px;
419 +
  box-shadow: 0 8px 30px rgba(0,0,0,0.5);
420 +
  backdrop-filter: blur(4px);
421 +
}
422 +
.post-header { margin-bottom: 26px; padding-bottom: 14px; border-bottom: 2px solid #ff4c00; }
423 +
.post-header-meta {
424 +
  display: flex; gap: 16px;
425 +
  color: #ff4c00;
426 +
  font-size: 0.85rem; font-weight: 700;
427 +
  letter-spacing: 2px; text-transform: uppercase;
428 +
  margin-bottom: 10px;
429 +
}
430 +
.post-title, .page-title {
431 +
  font-size: 2.2rem;
432 +
  color: var(--white);
433 +
  line-height: 1.25;
434 +
  font-weight: 800;
435 +
  text-transform: uppercase;
436 +
  letter-spacing: 3px;
437 +
  margin-bottom: 14px;
438 +
}
439 +
.post-cover {
440 +
  margin: 0 0 28px;
441 +
  border-radius: 10px;
442 +
  overflow: hidden;
443 +
  border: 2px solid rgba(243, 112, 33, 0.7);
444 +
  box-shadow: 0 12px 36px rgba(0,0,0,0.6);
445 +
}
446 +
.post-cover img { width: 100%; }
447 +
.page-header { margin-bottom: 26px; padding-bottom: 14px; border-bottom: 2px solid #ff4c00; }
448 +
449 +
/* TOC */
450 +
.toc {
451 +
  background: rgba(0,0,0,0.35);
452 +
  border: 1px dashed rgba(243, 112, 33, 0.35);
453 +
  border-radius: 6px;
454 +
  padding: 18px 22px;
455 +
  margin-bottom: 28px;
456 +
}
457 +
.toc h3 {
458 +
  color: #ff4c00; font-size: 0.85rem;
459 +
  text-transform: uppercase; letter-spacing: 2px;
460 +
  font-weight: 700; margin-bottom: 10px;
461 +
}
462 +
.toc ul { list-style: none; padding: 0; margin: 0; }
463 +
.toc li { margin: 4px 0; }
464 +
.toc li a { color: var(--silver); font-size: 0.92rem; }
465 +
.toc li a:hover { color: var(--orange-bright); }
466 +
.toc .toc-level-1 { padding-left: 16px; }
467 +
.toc .toc-level-2 { padding-left: 32px; }
468 +
.toc .toc-level-3 { padding-left: 48px; }
469 +
470 +
/* ============================================================
471 +
   Markdown-Content
472 +
   ------------------------------------------------------------
473 +
   Alle Selektoren nutzen :where(.post-content), damit ihre
474 +
   Spezifität bei (0,0,X) bleibt – jede Widget-Klasse (board-card,
475 +
   partner-tile etc.) gewinnt damit automatisch und Markdown-Regeln
476 +
   verirren sich nicht in eingebettete HTML-Komponenten.
477 +
   ============================================================ */
478 +
.post-content { color: var(--gray-light); font-size: 1.02rem; line-height: 1.75; }
479 +
480 +
:where(.post-content) h1,
481 +
:where(.post-content) h2,
482 +
:where(.post-content) h3,
483 +
:where(.post-content) h4 {
484 +
  color: var(--white);
485 +
  margin: 28px 0 14px;
486 +
  line-height: 1.3;
487 +
}
488 +
:where(.post-content) h1 { font-size: 1.7rem; }
489 +
:where(.post-content) h2 {
490 +
  font-size: 1.4rem;
491 +
  padding: 8px 14px;
492 +
  background: rgba(243, 112, 33, 0.12);
493 +
  border-left: 4px solid #ff4c00;
494 +
}
495 +
:where(.post-content) h3 { font-size: 1.15rem; color: #ff4c00; }
496 +
:where(.post-content) h4 { font-size: 1.02rem; text-transform: uppercase; letter-spacing: 0.5px; }
497 +
:where(.post-content) p { margin-bottom: 16px; }
498 +
:where(.post-content) a { color: #ff4c00; }
499 +
:where(.post-content) a:hover { color: var(--orange-bright); text-decoration: underline; }
500 +
:where(.post-content) strong { color: var(--white); font-weight: 700; }
501 +
:where(.post-content) ul,
502 +
:where(.post-content) ol { margin: 10px 0 18px 22px; }
503 +
:where(.post-content) li { margin-bottom: 6px; }
504 +
:where(.post-content) li::marker { color: #ff4c00; }
505 +
:where(.post-content) blockquote {
506 +
  margin: 18px 0;
507 +
  padding: 14px 20px;
508 +
  background: rgba(0,0,0,0.4);
509 +
  border-left: 4px solid #ff4c00;
510 +
  border-radius: 4px;
511 +
  color: var(--silver);
512 +
  font-style: italic;
513 +
}
514 +
:where(.post-content) code {
515 +
  background: rgba(0,0,0,0.5);
516 +
  padding: 2px 6px;
517 +
  border-radius: 4px;
518 +
  font-family: 'JetBrains Mono', Consolas, monospace;
519 +
  font-size: 0.9em;
520 +
  color: var(--orange-bright);
521 +
  border: 1px solid rgba(243, 112, 33, 0.2);
522 +
}
523 +
:where(.post-content) pre {
524 +
  background: rgba(0,0,0,0.6);
525 +
  border: 1px solid rgba(243, 112, 33, 0.2);
526 +
  border-radius: 6px;
527 +
  padding: 16px 18px;
528 +
  overflow-x: auto;
529 +
  margin: 16px 0;
530 +
}
531 +
:where(.post-content) pre code {
532 +
  background: transparent;
533 +
  border: none;
534 +
  padding: 0;
535 +
  color: var(--silver);
536 +
}
537 +
:where(.post-content) img {
538 +
  border-radius: 6px;
539 +
  margin: 16px 0;
540 +
}
541 +
:where(.post-content) table {
542 +
  border-collapse: collapse;
543 +
  margin: 16px 0;
544 +
  width: 100%;
545 +
}
546 +
:where(.post-content) th,
547 +
:where(.post-content) td {
548 +
  border: 1px solid rgba(243, 112, 33, 0.2);
549 +
  padding: 8px 12px;
550 +
  text-align: left;
551 +
}
552 +
:where(.post-content) th { background: rgba(243, 112, 33, 0.12); color: var(--white); }
553 +
.highlight { color: #ff4c00; }
554 +
555 +
/* Post navigation */
556 +
.post-nav {
557 +
  display: grid; grid-template-columns: 1fr 1fr;
558 +
  gap: 16px; margin: 36px 0 20px;
559 +
}
560 +
.post-nav-link {
561 +
  display: flex; flex-direction: column; gap: 4px;
562 +
  padding: 16px 18px;
563 +
  background: rgba(0,0,0,0.4);
564 +
  border: 1px solid rgba(243, 112, 33, 0.2);
565 +
  border-radius: 8px;
566 +
  text-decoration: none;
567 +
  transition: all 0.25s ease;
568 +
  color: inherit;
569 +
}
570 +
.post-nav-link:hover { border-color: #ff4c00; background: rgba(243, 112, 33, 0.08); }
571 +
.post-nav-link.disabled { pointer-events: none; opacity: 0.4; }
572 +
.post-nav-next { text-align: right; }
573 +
.post-nav-label {
574 +
  color: #ff4c00;
575 +
  font-size: 0.75rem; font-weight: 700;
576 +
  letter-spacing: 1.5px; text-transform: uppercase;
577 +
}
578 +
.post-nav-title { color: var(--white); font-weight: 700; font-size: 0.95rem; }
579 +
580 +
.post-footer { margin-top: 20px; }
581 +
.back-link {
582 +
  display: inline-block;
583 +
  color: #ff4c00;
584 +
  font-weight: 700;
585 +
  letter-spacing: 1.5px;
586 +
  text-transform: uppercase;
587 +
  font-size: 0.9rem;
588 +
  text-decoration: none;
589 +
}
590 +
.back-link:hover { color: var(--orange-bright); text-decoration: underline; }
591 +
592 +
/* ====== Tags-/Kategorien-Seiten ====== */
593 +
.tags-page, .tag-page {
594 +
  background: rgba(15, 15, 15, 0.82);
595 +
  border: 1px solid rgba(255,255,255,0.06);
596 +
  border-radius: 10px;
597 +
  padding: 36px 40px;
598 +
  box-shadow: 0 8px 30px rgba(0,0,0,0.5);
599 +
  backdrop-filter: blur(4px);
600 +
}
601 +
.tags-page h1, .tag-page h1 {
602 +
  font-size: 2rem; color: var(--white);
603 +
  margin-bottom: 24px; padding-bottom: 14px;
604 +
  border-bottom: 2px solid #ff4c00;
605 +
  display: inline-block;
606 +
}
607 +
.tags-cloud { display: flex; flex-wrap: wrap; gap: 10px; }
608 +
609 +
/* ====== Pagination ====== */
610 +
.pagination {
611 +
  display: flex; align-items: center; justify-content: center;
612 +
  gap: 14px; margin: 40px 0 20px; flex-wrap: wrap;
613 +
}
614 +
.pagination-btn, .pagination-num {
615 +
  display: inline-block;
616 +
  padding: 10px 18px;
617 +
  border: 1px solid rgba(243, 112, 33, 0.3);
618 +
  border-radius: 6px;
619 +
  color: var(--silver); text-decoration: none;
620 +
  font-size: 0.85rem; font-weight: 700;
621 +
  text-transform: uppercase; letter-spacing: 1px;
622 +
  transition: all 0.2s ease;
623 +
}
624 +
.pagination-btn:hover, .pagination-num:hover {
625 +
  border-color: #ff4c00;
626 +
  color: var(--white);
627 +
  background: rgba(243, 112, 33, 0.1);
628 +
}
629 +
.pagination-num.active {
630 +
  background: #ff4c00;
631 +
  color: var(--black);
632 +
  border-color: #ff4c00;
633 +
}
634 +
.pagination-btn.disabled { opacity: 0.35; pointer-events: none; }
635 +
.pagination-pages { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
636 +
.pagination-ellipsis { color: var(--gray-light); padding: 0 4px; }
637 +
638 +
/* ====== Fixed Corner ====== */
639 +
.corner-fixed {
640 +
  position: fixed; right: 20px; bottom: 20px;
641 +
  width: var(--corner-img-w); height: auto;
642 +
  z-index: 50; pointer-events: none;
643 +
  filter: drop-shadow(0 8px 24px rgba(0,0,0,0.85));
644 +
}
645 +
646 +
/* ====== Footer ====== */
647 +
.footer {
648 +
  background: rgba(5, 5, 5, 0.92);
649 +
  border-top: 3px solid #ff4c00;
650 +
  padding: 30px;
651 +
  text-align: center;
652 +
  color: var(--gray-light);
653 +
  font-size: 0.9rem;
654 +
  margin-top: 40px;
655 +
}
656 +
.footer-inner {
657 +
  max-width: var(--content-max);
658 +
  margin: 0 auto;
659 +
  padding-right: calc(var(--content-right-pad) - 30px);
660 +
}
661 +
.footer a { color: #ff4c00; margin: 0 8px; }
662 +
.footer a:hover { color: var(--orange-bright); text-decoration: underline; }
663 +
664 +
/* ====== RESPONSIVE ====== */
665 +
@media (max-width: 1100px) {
666 +
  :root { --corner-img-w: 130px; --content-right-pad: 190px; }
667 +
}
668 +
669 +
@media (max-width: 860px) {
670 +
  :root { --corner-img-w: 110px; --content-right-pad: 20px; }
671 +
672 +
  /* Eckbild auf Mobile ausblenden – im engen Viewport würde es sonst
673 +
     die Karten/Texte rechts überlagern */
674 +
  .corner-fixed { display: none; }
675 +
676 +
  .nav-inner { padding: 10px 16px; flex-wrap: wrap; }
677 +
  .nav-brand img { height: 52px; }
678 +
  .nav-brand-text .name { font-size: 1rem; }
679 +
680 +
  .hamburger { display: inline-block; }
681 +
  .nav-links {
682 +
    display: none;
683 +
    flex-direction: column;
684 +
    align-items: stretch;
685 +
    width: 100%;
686 +
    gap: 0;
687 +
    margin-top: 10px;
688 +
    padding-top: 10px;
689 +
    border-top: 1px solid rgba(243, 112, 33, 0.3);
690 +
  }
691 +
  .nav-links.open { display: flex; }
692 +
  .nav-links > a,
693 +
  .nav-links .nav-dropdown > .nav-dropdown-toggle { padding: 12px 14px; width: 100%; justify-content: space-between; }
694 +
  .nav-dropdown-menu {
695 +
    position: static; opacity: 1; visibility: hidden;
696 +
    transform: none; box-shadow: none; border: none;
697 +
    border-left: 3px solid #ff4c00;
698 +
    background: rgba(0,0,0,0.3);
699 +
    margin: 4px 0 8px 14px;
700 +
    padding: 4px 0;
701 +
    max-height: 0;
702 +
    overflow: hidden;
703 +
    transition: max-height 0.3s ease, visibility 0s linear 0.3s;
704 +
  }
705 +
  .nav-dropdown.open > .nav-dropdown-menu {
706 +
    visibility: visible;
707 +
    max-height: 400px;
708 +
    transition: max-height 0.3s ease, visibility 0s;
709 +
  }
710 +
  .nav-dropdown-menu a { padding: 8px 16px; }
711 +
712 +
  .search-box { width: calc(100vw - 32px); right: -8px; }
713 +
714 +
  .container { padding: 24px 16px 40px; }
715 +
  .section, .partner-section, .post-single, .page-single, .tags-page, .tag-page { padding: 22px 20px; }
716 +
  .post-title, .page-title { font-size: 1.5rem; }
717 +
  .section h2 { font-size: 1.4rem; }
718 +
  .carousel-slide { flex: 0 0 100%; }
719 +
  .post-nav { grid-template-columns: 1fr; }
720 +
}
721 +
722 +
/* Eckbild ist auf ≤860 bereits ausgeblendet, daher hier nichts mehr nötig. */
723 +
724 +
/* ====== Vorstand ====== */
725 +
.board-grid {
726 +
  display: grid;
727 +
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
728 +
  gap: 26px;
729 +
  margin: 24px 0 8px;
730 +
}
731 +
.board-card {
732 +
  background: rgba(0, 0, 0, 0.5);
733 +
  border: 1px solid rgba(243, 112, 33, 0.2);
734 +
  border-radius: 12px;
735 +
  overflow: hidden;
736 +
  display: flex;
737 +
  flex-direction: column;
738 +
  transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
739 +
}
740 +
.board-card:hover {
741 +
  transform: translateY(-4px);
742 +
  border-color: #ff4c00;
743 +
  box-shadow: 0 14px 30px rgba(243, 112, 33, 0.18);
744 +
}
745 +
.board-card .photo {
746 +
  width: 100%;
747 +
  height: 500px;
748 +
  aspect-ratio: 1 / 1;
749 +
  /* background: #1a1a1a; */
750 +
  overflow: hidden;
751 +
}
752 +
.board-card .photo img {
753 +
  width: 100%; height: 100%;
754 +
  object-fit: cover; display: block;
755 +
}
756 +
.board-card .info {
757 +
  padding: 22px 24px 26px;
758 +
  display: flex; flex-direction: column;
759 +
  gap: 10px; flex: 1;
760 +
}
761 +
.board-card .role {
762 +
  color: #ff4c00;
763 +
  font-size: 0.78rem; font-weight: 700;
764 +
  text-transform: uppercase; letter-spacing: 2px;
765 +
}
766 +
.board-card .name {
767 +
  color: var(--white);
768 +
  font-size: 1.3rem; font-weight: 800;
769 +
  letter-spacing: 0.3px;
770 +
  margin: 0;
771 +
  /* Reset, falls die Karte als h2 in .post-content steht */
772 +
  padding: 0;
773 +
  background: transparent;
774 +
  border: none;
775 +
  text-transform: none;
776 +
}
777 +
.board-card .email {
778 +
  margin-top: auto;
779 +
  display: inline-flex; align-items: center; gap: 8px;
780 +
  color: var(--silver);
781 +
  text-decoration: none;
782 +
  font-size: 0.95rem;
783 +
  word-break: break-all;
784 +
  padding-top: 12px;
785 +
  border-top: 1px solid rgba(243, 112, 33, 0.2);
786 +
  transition: color 0.2s ease;
787 +
}
788 +
.board-card .email:hover { color: var(--orange-bright); }
789 +
.board-card .email::before {
790 +
  content: "✉";
791 +
  color: #ff4c00;
792 +
  font-size: 1.05rem;
793 +
  flex-shrink: 0;
794 +
}
795 +
796 +
/* ====== Impressum / Datenschutz Blöcke ====== */
797 +
.impressum-block { margin-bottom: 22px; }
798 +
.impressum-block .label {
799 +
  color: #ff4c00;
800 +
  font-size: 0.9rem; font-weight: 700;
801 +
  text-transform: uppercase; letter-spacing: 1.5px;
802 +
  margin-bottom: 4px;
803 +
}
804 +
.address-block {
805 +
  background: rgba(0,0,0,0.4);
806 +
  border-left: 3px solid #ff4c00;
807 +
  padding: 14px 18px;
808 +
  margin: 10px 0 18px;
809 +
  border-radius: 4px;
810 +
}
811 +
.uppercase-notice {
812 +
  background: rgba(243, 112, 33, 0.06);
813 +
  border: 1px solid rgba(243, 112, 33, 0.3);
814 +
  border-radius: 6px;
815 +
  padding: 14px 18px;
816 +
  margin: 12px 0;
817 +
  color: var(--silver);
818 +
  font-size: 0.85rem;
819 +
  line-height: 1.55;
820 +
  text-transform: uppercase;
821 +
  letter-spacing: 0.4px;
822 +
}
823 +
824 +
/* ====== Partner-Grid (Übersichtsseite) ====== */
825 +
.partner-grid {
826 +
  display: grid;
827 +
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
828 +
  gap: 22px;
829 +
  margin: 20px 0 8px;
830 +
}
831 +
.partner-tile {
832 +
  background: rgba(0, 0, 0, 0.5);
833 +
  border: 1px solid rgba(243, 112, 33, 0.2);
834 +
  border-radius: 10px;
835 +
  overflow: hidden;
836 +
  display: flex;
837 +
  flex-direction: column;
838 +
  text-decoration: none;
839 +
  color: inherit;
840 +
  transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
841 +
}
842 +
.partner-tile:hover {
843 +
  transform: translateY(-4px);
844 +
  border-color: #ff4c00;
845 +
  box-shadow: 0 12px 28px rgba(243, 112, 33, 0.18);
846 +
}
847 +
.partner-tile .logo {
848 +
  background: var(--white);
849 +
  height: 150px;
850 +
  display: flex;
851 +
  align-items: center;
852 +
  justify-content: center;
853 +
  padding: 20px;
854 +
}
855 +
.partner-tile .logo img {
856 +
  max-width: 100%;
857 +
  max-height: 100%;
858 +
  object-fit: contain;
859 +
}
860 +
.partner-tile .info {
861 +
  padding: 16px 18px 18px;
862 +
  flex: 1;
863 +
  display: flex;
864 +
  flex-direction: column;
865 +
  justify-content: space-between;
866 +
  gap: 10px;
867 +
}
868 +
.partner-tile .name {
869 +
  color: var(--white);
870 +
  font-size: 1.05rem;
871 +
  font-weight: 700;
872 +
  letter-spacing: 0.3px;
873 +
}
874 +
.partner-tile .visit {
875 +
  color: #ff4c00;
876 +
  font-size: 0.85rem;
877 +
  font-weight: 700;
878 +
  letter-spacing: 1.5px;
879 +
  text-transform: uppercase;
880 +
  transition: color 0.2s ease;
881 +
}
882 +
.partner-tile:hover .visit { color: var(--orange-bright); }
883 +
.partner-tile .no-url {
884 +
  color: rgba(184, 184, 184, 0.55);
885 +
  font-size: 0.8rem;
886 +
  font-style: italic;
887 +
  letter-spacing: 0.5px;
888 +
}
hinzugefügt themes/ehc/static/js/partner-carousel.js
+112 −0 Datei ansehen
@@ -0,0 +1,112 @@
1 +
/* ============================================================
2 +
   Partner-Carousel — Quilldrop Widget
3 +
   ------------------------------------------------------------
4 +
   Erwartet im DOM:
5 +
     <div id="partner-carousel"></div>
6 +
     <div id="partner-carousel-dots"></div>      (optional)
7 +
8 +
   Daten: /static/data/partners.json
9 +
   Konfig per data-Attribut auf #partner-carousel:
10 +
     data-visible="3"     Anzahl gleichzeitig sichtbarer Logos
11 +
     data-interval="3500" Auto-Rotation in ms
12 +
   ============================================================ */
13 +
(function() {
14 +
  'use strict';
15 +
16 +
  const DATA_URL = '/static/data/partners.json';
17 +
18 +
  function esc(s) {
19 +
    return String(s).replace(/[&<>"]/g, c =>
20 +
      ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c])
21 +
    );
22 +
  }
23 +
24 +
  function build(host, dotsBox, partners, opts) {
25 +
    const VISIBLE  = opts.visible;
26 +
    const INTERVAL = opts.interval;
27 +
28 +
    host.classList.add('carousel');
29 +
    host.innerHTML = '';
30 +
31 +
    const track = document.createElement('div');
32 +
    track.className = 'carousel-track';
33 +
    host.appendChild(track);
34 +
35 +
    // Slides + Klone für Endlos-Loop
36 +
    const all = partners.concat(partners.slice(0, VISIBLE));
37 +
    all.forEach(p => {
38 +
      const slide = document.createElement('div');
39 +
      slide.className = 'carousel-slide';
40 +
      const card = `<div class="partner-card" title="${esc(p.name)}">
41 +
        <img src="${esc(p.src)}" alt="${esc(p.name)}" loading="lazy" />
42 +
      </div>`;
43 +
      slide.innerHTML = p.url
44 +
        ? `<a href="${esc(p.url)}" target="_blank" rel="noopener" class="partner-link" aria-label="${esc(p.name)}">${card}</a>`
45 +
        : card;
46 +
      track.appendChild(slide);
47 +
    });
48 +
49 +
    // Dots
50 +
    if (dotsBox) {
51 +
      dotsBox.innerHTML = '';
52 +
      partners.forEach((_, i) => {
53 +
        const b = document.createElement('button');
54 +
        b.className = 'carousel-dot' + (i === 0 ? ' active' : '');
55 +
        b.setAttribute('aria-label', `Partner ${i + 1}`);
56 +
        b.addEventListener('click', () => goTo(i));
57 +
        dotsBox.appendChild(b);
58 +
      });
59 +
    }
60 +
61 +
    let index = 0;
62 +
    function update() {
63 +
      track.style.transition = 'transform 0.7s cubic-bezier(0.4, 0, 0.2, 1)';
64 +
      track.style.transform  = `translateX(-${(100 / VISIBLE) * index}%)`;
65 +
      if (dotsBox) {
66 +
        const active = index % partners.length;
67 +
        [...dotsBox.children].forEach((d, i) => d.classList.toggle('active', i === active));
68 +
      }
69 +
    }
70 +
    function goTo(i) { index = i; update(); }
71 +
    function next() {
72 +
      index++;
73 +
      update();
74 +
      if (index >= partners.length) {
75 +
        setTimeout(() => {
76 +
          track.style.transition = 'none';
77 +
          index = 0;
78 +
          track.style.transform = 'translateX(0)';
79 +
          if (dotsBox) [...dotsBox.children].forEach((d, i) => d.classList.toggle('active', i === 0));
80 +
        }, 720);
81 +
      }
82 +
    }
83 +
84 +
    update();
85 +
    setInterval(next, INTERVAL);
86 +
  }
87 +
88 +
  function init() {
89 +
    const host = document.getElementById('partner-carousel');
90 +
    if (!host) return;
91 +
    const dotsBox = document.getElementById('partner-carousel-dots');
92 +
93 +
    const opts = {
94 +
      visible:  parseInt(host.dataset.visible,  10) || 3,
95 +
      interval: parseInt(host.dataset.interval, 10) || 3500
96 +
    };
97 +
98 +
    fetch(DATA_URL)
99 +
      .then(r => r.json())
100 +
      .then(partners => {
101 +
        if (!Array.isArray(partners) || partners.length === 0) return;
102 +
        build(host, dotsBox, partners, opts);
103 +
      })
104 +
      .catch(err => console.error('partner-carousel:', err));
105 +
  }
106 +
107 +
  if (document.readyState === 'loading') {
108 +
    document.addEventListener('DOMContentLoaded', init);
109 +
  } else {
110 +
    init();
111 +
  }
112 +
})();
hinzugefügt themes/ehc/static/js/partner-grid.js
+72 −0 Datei ansehen
@@ -0,0 +1,72 @@
1 +
/* ============================================================
2 +
   Partner-Grid — Quilldrop Widget
3 +
   ------------------------------------------------------------
4 +
   Erwartet im DOM:
5 +
     <div id="partner-grid"></div>
6 +
7 +
   Daten: /static/data/partners.json
8 +
   Konfig per data-Attribut auf #partner-grid:
9 +
     data-sort="name|none"   alphabetisch sortieren (Default: name)
10 +
   ============================================================ */
11 +
(function() {
12 +
  'use strict';
13 +
14 +
  const DATA_URL = '/static/data/partners.json';
15 +
16 +
  function esc(s) {
17 +
    return String(s).replace(/[&<>"]/g, c =>
18 +
      ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c])
19 +
    );
20 +
  }
21 +
22 +
  function build(host, partners) {
23 +
    host.classList.add('partner-grid');
24 +
    host.innerHTML = '';
25 +
26 +
    partners.forEach(p => {
27 +
      const tag = p.url ? 'a' : 'div';
28 +
      const el  = document.createElement(tag);
29 +
      el.className = 'partner-tile';
30 +
      if (p.url) {
31 +
        el.href   = p.url;
32 +
        el.target = '_blank';
33 +
        el.rel    = 'noopener';
34 +
      }
35 +
      el.innerHTML = `
36 +
        <div class="logo">
37 +
          <img src="${esc(p.src)}" alt="${esc(p.name)}" loading="lazy" />
38 +
        </div>
39 +
        <div class="info">
40 +
          <div class="name">${esc(p.name)}</div>
41 +
          ${p.url
42 +
            ? `<div class="visit">Website besuchen &rarr;</div>`
43 +
            : `<div class="no-url">Website folgt</div>`}
44 +
        </div>`;
45 +
      host.appendChild(el);
46 +
    });
47 +
  }
48 +
49 +
  function init() {
50 +
    const host = document.getElementById('partner-grid');
51 +
    if (!host) return;
52 +
53 +
    const sortMode = host.dataset.sort || 'name';
54 +
55 +
    fetch(DATA_URL)
56 +
      .then(r => r.json())
57 +
      .then(partners => {
58 +
        if (!Array.isArray(partners) || partners.length === 0) return;
59 +
        if (sortMode === 'name') {
60 +
          partners.sort((a, b) => a.name.localeCompare(b.name, 'de'));
61 +
        }
62 +
        build(host, partners);
63 +
      })
64 +
      .catch(err => console.error('partner-grid:', err));
65 +
  }
66 +
67 +
  if (document.readyState === 'loading') {
68 +
    document.addEventListener('DOMContentLoaded', init);
69 +
  } else {
70 +
    init();
71 +
  }
72 +
})();
hinzugefügt themes/ehc/static/js/search.js
+146 −0 Datei ansehen
@@ -0,0 +1,146 @@
1 +
(function () {
2 +
    'use strict';
3 +
4 +
    let searchIndex = null;
5 +
    let debounceTimer = null;
6 +
7 +
    const toggle = document.getElementById('search-toggle');
8 +
    const container = document.getElementById('search-container');
9 +
    const box = document.getElementById('search-box');
10 +
    const input = document.getElementById('search-input');
11 +
    const results = document.getElementById('search-results');
12 +
13 +
    if (!toggle || !input || !results) return;
14 +
15 +
    // Toggle search box
16 +
    toggle.addEventListener('click', function (e) {
17 +
        e.stopPropagation();
18 +
        const isOpen = container.classList.toggle('active');
19 +
        if (isOpen) {
20 +
            input.focus();
21 +
            loadIndex();
22 +
        } else {
23 +
            closeSearch();
24 +
        }
25 +
    });
26 +
27 +
    // Load search index (lazy, only once)
28 +
    function loadIndex() {
29 +
        if (searchIndex !== null) return;
30 +
        fetch('/search-index.json')
31 +
            .then(function (res) { return res.json(); })
32 +
            .then(function (data) { searchIndex = data; })
33 +
            .catch(function (err) {
34 +
                console.error('Search index load failed:', err);
35 +
            });
36 +
    }
37 +
38 +
    // Search on input
39 +
    input.addEventListener('input', function () {
40 +
        clearTimeout(debounceTimer);
41 +
        debounceTimer = setTimeout(doSearch, 200);
42 +
    });
43 +
44 +
    function doSearch() {
45 +
        var query = input.value.trim().toLowerCase();
46 +
        if (!query || !searchIndex) {
47 +
            results.innerHTML = '';
48 +
            results.classList.remove('visible');
49 +
            return;
50 +
        }
51 +
52 +
        var terms = query.split(/\s+/);
53 +
        var matches = searchIndex.filter(function (entry) {
54 +
            var haystack = [
55 +
                entry.title,
56 +
                entry.preview,
57 +
                (entry.tags || []).join(' '),
58 +
                (entry.categories || []).join(' ')
59 +
            ].join(' ').toLowerCase();
60 +
61 +
            return terms.every(function (term) {
62 +
                return haystack.indexOf(term) !== -1;
63 +
            });
64 +
        });
65 +
66 +
        renderResults(matches.slice(0, 8));
67 +
    }
68 +
69 +
    function renderResults(items) {
70 +
        if (items.length === 0) {
71 +
            results.innerHTML = '<div class="search-no-results">Keine Ergebnisse gefunden</div>';
72 +
            results.classList.add('visible');
73 +
            return;
74 +
        }
75 +
76 +
        var html = '';
77 +
        items.forEach(function (item) {
78 +
            var tags = (item.tags || []).slice(0, 3).map(function (t) {
79 +
                return '<span class="search-result-tag">' + escapeHtml(t) + '</span>';
80 +
            }).join('');
81 +
82 +
            html += '<a href="' + escapeHtml(item.url) + '" class="search-result-item">' +
83 +
                '<div class="search-result-title">' + highlightMatch(escapeHtml(item.title), input.value.trim()) + '</div>' +
84 +
                '<div class="search-result-meta">' +
85 +
                    '<span class="search-result-date">' + escapeHtml(item.date) + '</span>' +
86 +
                    (tags ? '<span class="search-result-tags">' + tags + '</span>' : '') +
87 +
                '</div>' +
88 +
            '</a>';
89 +
        });
90 +
91 +
        results.innerHTML = html;
92 +
        results.classList.add('visible');
93 +
    }
94 +
95 +
    function highlightMatch(text, query) {
96 +
        if (!query) return text;
97 +
        var terms = query.toLowerCase().split(/\s+/);
98 +
        terms.forEach(function (term) {
99 +
            if (!term) return;
100 +
            var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'gi');
101 +
            text = text.replace(regex, '<mark>$1</mark>');
102 +
        });
103 +
        return text;
104 +
    }
105 +
106 +
    function escapeHtml(str) {
107 +
        if (!str) return '';
108 +
        return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
109 +
    }
110 +
111 +
    function closeSearch() {
112 +
        container.classList.remove('active');
113 +
        input.value = '';
114 +
        results.innerHTML = '';
115 +
        results.classList.remove('visible');
116 +
    }
117 +
118 +
    // Keyboard shortcuts
119 +
    input.addEventListener('keydown', function (e) {
120 +
        if (e.key === 'Escape') {
121 +
            closeSearch();
122 +
        }
123 +
    });
124 +
125 +
    // Close on click outside
126 +
    document.addEventListener('click', function (e) {
127 +
        if (!container.contains(e.target)) {
128 +
            closeSearch();
129 +
        }
130 +
    });
131 +
132 +
    // Prevent search box clicks from closing
133 +
    box.addEventListener('click', function (e) {
134 +
        e.stopPropagation();
135 +
    });
136 +
137 +
    // Global shortcut: Ctrl+K or Cmd+K to open search
138 +
    document.addEventListener('keydown', function (e) {
139 +
        if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
140 +
            e.preventDefault();
141 +
            container.classList.add('active');
142 +
            input.focus();
143 +
            loadIndex();
144 +
        }
145 +
    });
146 +
})();
hinzugefügt themes/ehc/static/js/theme.js
+94 −0 Datei ansehen
@@ -0,0 +1,94 @@
1 +
(function() {
2 +
    var html = document.documentElement;
3 +
    var toggle = document.getElementById('theme-toggle');
4 +
    var stored = localStorage.getItem('theme');
5 +
6 +
    if (stored) {
7 +
        html.setAttribute('data-theme', stored);
8 +
    }
9 +
10 +
    function updateIcon() {
11 +
        if (toggle) {
12 +
            toggle.textContent = html.getAttribute('data-theme') === 'dark' ? '\u263D' : '\u2600\uFE0F';
13 +
        }
14 +
    }
15 +
16 +
    updateIcon();
17 +
18 +
    if (toggle) {
19 +
        toggle.addEventListener('click', function() {
20 +
            var next = html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
21 +
            html.setAttribute('data-theme', next);
22 +
            localStorage.setItem('theme', next);
23 +
            updateIcon();
24 +
        });
25 +
    }
26 +
27 +
    // Hamburger menu
28 +
    var hamburger = document.getElementById('hamburger');
29 +
    var navLinks = document.getElementById('nav-links');
30 +
    if (hamburger && navLinks) {
31 +
        hamburger.addEventListener('click', function() {
32 +
            hamburger.classList.toggle('active');
33 +
            navLinks.classList.toggle('open');
34 +
        });
35 +
        // Close mobile menu when clicking a link
36 +
        navLinks.querySelectorAll('a').forEach(function(link) {
37 +
            link.addEventListener('click', function() {
38 +
                hamburger.classList.remove('active');
39 +
                navLinks.classList.remove('open');
40 +
            });
41 +
        });
42 +
    }
43 +
44 +
    // Dropdown toggles (for mobile tap support)
45 +
    document.querySelectorAll('.nav-dropdown-toggle').forEach(function(btn) {
46 +
        btn.addEventListener('click', function(e) {
47 +
            e.preventDefault();
48 +
            e.stopPropagation();
49 +
            var dropdown = btn.closest('.nav-dropdown');
50 +
            // Close other dropdowns
51 +
            document.querySelectorAll('.nav-dropdown.open').forEach(function(other) {
52 +
                if (other !== dropdown) other.classList.remove('open');
53 +
            });
54 +
            dropdown.classList.toggle('open');
55 +
        });
56 +
    });
57 +
58 +
    // Close dropdown when clicking outside
59 +
    document.addEventListener('click', function(e) {
60 +
        if (!e.target.closest('.nav-dropdown')) {
61 +
            document.querySelectorAll('.nav-dropdown.open').forEach(function(d) {
62 +
                d.classList.remove('open');
63 +
            });
64 +
        }
65 +
    });
66 +
67 +
    // TOC generator for posts with toc: true
68 +
    var toc = document.getElementById('toc');
69 +
    if (toc) {
70 +
        var headings = document.querySelectorAll('.post-content h1, .post-content h2, .post-content h3');
71 +
        if (headings.length > 0) {
72 +
            // Determine the highest (smallest number) heading level used
73 +
            var minLevel = 6;
74 +
            headings.forEach(function(h) {
75 +
                var level = parseInt(h.tagName.charAt(1));
76 +
                if (level < minLevel) minLevel = level;
77 +
            });
78 +
79 +
            var ul = document.createElement('ul');
80 +
            headings.forEach(function(h) {
81 +
                var level = parseInt(h.tagName.charAt(1));
82 +
                var li = document.createElement('li');
83 +
                // Indent relative to the highest heading level found
84 +
                li.className = 'toc-level-' + (level - minLevel);
85 +
                var a = document.createElement('a');
86 +
                a.href = '#' + h.id;
87 +
                a.textContent = h.textContent;
88 +
                li.appendChild(a);
89 +
                ul.appendChild(li);
90 +
            });
91 +
            toc.appendChild(ul);
92 +
        }
93 +
    }
94 +
})();
hinzugefügt themes/ehc/templates/base.html
+93 −0 Datei ansehen
@@ -0,0 +1,93 @@
1 +
{{define "base"}}<!DOCTYPE html>
2 +
<html lang="de">
3 +
<head>
4 +
    <meta charset="UTF-8">
5 +
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 +
    <title>{{block "title" .}}{{.Site.Title}}{{end}}</title>
7 +
    <meta name="description" content="{{.Site.Description}}">
8 +
    <link rel="alternate" type="application/rss+xml" title="{{.Site.Title}} RSS Feed" href="/index.xml">
9 +
    <link rel="stylesheet" href="/static/css/style.css">
10 +
    <link rel="icon" type="image/png" href="/images/ehc/EHC_Logo.png">
11 +
    <link rel="apple-touch-icon" sizes="180x180" href="/static/icons/apple-touch-icon.png">
12 +
    <link rel="manifest" href="/static/icons/site.webmanifest">
13 +
    <meta name="theme-color" content="#0a0a0a">
14 +
</head>
15 +
<body>
16 +
17 +
<div class="bg-fixed" aria-hidden="true"></div>
18 +
<div class="bg-overlay" aria-hidden="true"></div>
19 +
20 +
<header class="navbar">
21 +
    <div class="nav-inner">
22 +
        <a href="/" class="nav-brand">
23 +
            <img src="/images/ehc/EHC_Logo.webp" alt="EHC Logo">
24 +
            <span class="nav-brand-text">
25 +
                <span class="name">{{.Site.Title}}</span>
26 +
                <span class="sub">We Are Family</span>
27 +
            </span>
28 +
        </a>
29 +
30 +
        <button class="hamburger" id="hamburger" aria-label="Menü öffnen">
31 +
            <span></span><span></span><span></span>
32 +
        </button>
33 +
34 +
        <nav class="nav-links" id="nav-links" aria-label="Hauptnavigation">
35 +
            {{range .Site.Menu}}
36 +
            {{if hasChildren .}}
37 +
            <div class="nav-dropdown">
38 +
                <button class="nav-dropdown-toggle">{{.Label}} <svg width="10" height="6" viewBox="0 0 10 6" fill="none" aria-hidden="true"><path d="M1 1L5 5L9 1" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button>
39 +
                <div class="nav-dropdown-menu">
40 +
                    {{range .Children}}<a href="{{.URL}}">{{.Label}}</a>{{end}}
41 +
                </div>
42 +
            </div>
43 +
            {{else}}
44 +
            <a href="{{.URL}}">{{.Label}}</a>
45 +
            {{end}}
46 +
            {{end}}
47 +
48 +
            <div class="search-container" id="search-container">
49 +
                <button class="search-toggle" id="search-toggle" aria-label="Suche">
50 +
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
51 +
                </button>
52 +
                <div class="search-box" id="search-box">
53 +
                    <input type="text" id="search-input" placeholder="Suche..." autocomplete="off">
54 +
                    <div class="search-results" id="search-results"></div>
55 +
                </div>
56 +
            </div>
57 +
58 +
            <a href="/index.xml" class="nav-rss" title="RSS Feed" aria-label="RSS Feed">
59 +
                <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><circle cx="6.18" cy="17.82" r="2.18"/><path d="M4 4.44v2.83c7.03 0 12.73 5.7 12.73 12.73h2.83c0-8.59-6.97-15.56-15.56-15.56zm0 5.66v2.83c3.9 0 7.07 3.17 7.07 7.07h2.83c0-5.47-4.43-9.9-9.9-9.9z"/></svg>
60 +
            </a>
61 +
        </nav>
62 +
    </div>
63 +
</header>
64 +
65 +
<main class="container">
66 +
    {{block "content" .}}{{end}}
67 +
</main>
68 +
69 +
<div class="corner-fixed" aria-hidden="true">
70 +
    <img src="/images/ehc/we-are-family.webp" alt="">
71 +
</div>
72 +
73 +
<footer class="footer">
74 +
    <div class="footer-inner">
75 +
        &copy; <span id="year"></span> {{.Site.Title}} &middot; We Are Family
76 +
        &middot; <a href="/sites/impressum/">Impressum</a>
77 +
        &middot; <a href="/sites/datenschutz/">Datenschutz</a>
78 +
    </div>
79 +
</footer>
80 +
81 +
<script>document.getElementById('year').textContent = new Date().getFullYear();</script>
82 +
<script src="/static/js/theme.js"></script>
83 +
<script src="/static/js/search.js"></script>
84 +
    <script>
85 +
        (function () {
86 +
        var i = new Image(1, 1);
87 +
        i.src = "https://assets.tytik.cloud/assets/img/s.gif"
88 +
                + "?u=" + encodeURIComponent(location.href)
89 +
                + "&ref=" + encodeURIComponent(document.referrer);
90 +
        })();
91 +
    </script>
92 +
</body>
93 +
</html>{{end}}
hinzugefügt themes/ehc/templates/categories.html
+14 −0 Datei ansehen
@@ -0,0 +1,14 @@
1 +
{{define "title"}}Kategorien &middot; {{.Site.Title}}{{end}}
2 +
{{define "content"}}
3 +
<div class="tags-page">
4 +
    <h1>Kategorien</h1>
5 +
    <div class="tags-cloud">
6 +
        {{range $cat, $count := .Categories}}
7 +
        <a href="/categories/{{lower $cat}}/" class="tag tag-large">{{$cat}} <span class="tag-count">{{$count}}</span></a>
8 +
        {{end}}
9 +
    </div>
10 +
    <div class="post-footer">
11 +
        <a href="/" class="back-link">&larr; Zurück zur Startseite</a>
12 +
    </div>
13 +
</div>
14 +
{{end}}
hinzugefügt themes/ehc/templates/category.html
+31 −0 Datei ansehen
@@ -0,0 +1,31 @@
1 +
{{define "title"}}Kategorie: {{.Category}} &middot; {{.Site.Title}}{{end}}
2 +
{{define "content"}}
3 +
<div class="tag-page">
4 +
    <h1>Kategorie: <span class="highlight">{{.Category}}</span></h1>
5 +
    <div class="post-list">
6 +
        {{range .Posts}}
7 +
        <article class="post-card">
8 +
            {{if .GetCover}}
9 +
            <a href="/posts/{{.Slug}}/" class="post-card-cover">
10 +
                <img src="{{.GetCover}}" alt="{{.Title}}" loading="lazy">
11 +
            </a>
12 +
            {{end}}
13 +
            <div class="post-card-body">
14 +
                <div class="post-card-meta">
15 +
                    <time datetime="{{isoDate .Date.Time}}">{{formatDate .Date.Time}}</time>
16 +
                    <div class="post-tags">
17 +
                        {{range .Tags}}<a href="/tags/{{lower .}}/" class="tag">{{.}}</a>{{end}}
18 +
                    </div>
19 +
                </div>
20 +
                <h2 class="post-card-title"><a href="/posts/{{.Slug}}/">{{.Title}}</a></h2>
21 +
                <p class="post-card-preview">{{.GetPreview}}</p>
22 +
                <a href="/posts/{{.Slug}}/" class="read-more">Weiterlesen &rarr;</a>
23 +
            </div>
24 +
        </article>
25 +
        {{end}}
26 +
    </div>
27 +
    <div class="post-footer">
28 +
        <a href="/categories/" class="back-link">&larr; Alle Kategorien</a>
29 +
    </div>
30 +
</div>
31 +
{{end}}
hinzugefügt themes/ehc/templates/home.html
+69 −0 Datei ansehen
@@ -0,0 +1,69 @@
1 +
{{define "title"}}{{.Site.Title}}{{end}}
2 +
{{define "content"}}
3 +
4 +
{{if eq .Page 1}}
5 +
<div class="hero-image">
6 +
    <!-- <img src="/images/ehc/we-are-family-team-short.webp" alt="EHC Essen (Ruhr) e.V. - We Are Family"> -->
7 +
    <img src="/images/ehc/we-are-family-v2.webp" alt="EHC Essen (Ruhr) e.V. - We Are Family">
8 +
</div>
9 +
10 +
<section class="partner-section">
11 +
    <div class="section-head">
12 +
        <h2>Unsere Partner</h2>
13 +
        <a href="/sites/partner/" class="all-link">Alle Partner anzeigen &rarr;</a>
14 +
    </div>
15 +
16 +
    <!-- Partner-Karussell-Widget; lädt /static/data/partners.json -->
17 +
    <div id="partner-carousel" data-visible="3" data-interval="3500" aria-label="Partner Karussell"></div>
18 +
    <div id="partner-carousel-dots" class="carousel-dots"></div>
19 +
    <script src="/static/js/partner-carousel.js" defer></script>
20 +
</section>
21 +
{{end}}
22 +
23 +
<section class="section">
24 +
    <div class="section-head">
25 +
        <h2>News</h2>
26 +
        {{if gt .TotalPages 1}}<a href="{{pageURL 2}}" class="all-link">Ältere News &rarr;</a>{{end}}
27 +
    </div>
28 +
29 +
    <div class="post-list">
30 +
        {{range .Posts}}
31 +
        <article class="post-card">
32 +
            {{if .GetCover}}
33 +
            <a href="/posts/{{.Slug}}/" class="post-card-cover">
34 +
                <img src="{{.GetCover}}" alt="{{.Title}}" loading="lazy">
35 +
            </a>
36 +
            {{end}}
37 +
            <div class="post-card-body">
38 +
                <div class="post-card-meta">
39 +
                    <time datetime="{{isoDate .Date.Time}}">{{formatDate .Date.Time}}</time>
40 +
                    <div class="post-tags">
41 +
                        {{range .Tags}}<a href="/tags/{{lower .}}/" class="tag">{{.}}</a>{{end}}
42 +
                    </div>
43 +
                </div>
44 +
                <h2 class="post-card-title"><a href="/posts/{{.Slug}}/">{{.Title}}</a></h2>
45 +
                <p class="post-card-preview">{{.GetPreview}}</p>
46 +
                <a href="/posts/{{.Slug}}/" class="read-more">Weiterlesen &rarr;</a>
47 +
            </div>
48 +
        </article>
49 +
        {{end}}
50 +
    </div>
51 +
</section>
52 +
53 +
{{if gt .TotalPages 1}}
54 +
<nav class="pagination">
55 +
    {{if gt .Page 1}}<a href="{{pageURL (sub .Page 1)}}" class="pagination-btn pagination-prev">&larr; Neuere</a>
56 +
    {{else}}<span class="pagination-btn pagination-prev disabled">&larr; Neuere</span>{{end}}
57 +
    <div class="pagination-pages">
58 +
        {{range paginationRange $.Page $.TotalPages}}
59 +
        {{if isEllipsis .}}<span class="pagination-ellipsis">&hellip;</span>
60 +
        {{else if eq . $.Page}}<span class="pagination-num active">{{.}}</span>
61 +
        {{else}}<a href="{{pageURL .}}" class="pagination-num">{{.}}</a>{{end}}
62 +
        {{end}}
63 +
    </div>
64 +
    {{if lt .Page .TotalPages}}<a href="{{pageURL (add .Page 1)}}" class="pagination-btn pagination-next">Ältere &rarr;</a>
65 +
    {{else}}<span class="pagination-btn pagination-next disabled">Ältere &rarr;</span>{{end}}
66 +
</nav>
67 +
{{end}}
68 +
69 +
{{end}}
hinzugefügt themes/ehc/templates/page.html
+14 −0 Datei ansehen
@@ -0,0 +1,14 @@
1 +
{{define "title"}}{{.Page.Title}} &middot; {{.Site.Title}}{{end}}
2 +
{{define "content"}}
3 +
<article class="page-single">
4 +
    <header class="page-header">
5 +
        <h1 class="page-title">{{.Page.Title}}</h1>
6 +
    </header>
7 +
    <div class="post-content">
8 +
        {{safeHTML .Page.HTMLContent}}
9 +
    </div>
10 +
    <div class="post-footer">
11 +
        <a href="/" class="back-link">&larr; Zurück zur Startseite</a>
12 +
    </div>
13 +
</article>
14 +
{{end}}
hinzugefügt themes/ehc/templates/post.html
+50 −0 Datei ansehen
@@ -0,0 +1,50 @@
1 +
{{define "title"}}{{.Post.Title}} &middot; {{.Site.Title}}{{end}}
2 +
{{define "content"}}
3 +
<article class="post-single">
4 +
    <header class="post-header">
5 +
        <div class="post-header-meta">
6 +
            <time datetime="{{isoDate .Post.Date.Time}}">{{formatDate .Post.Date.Time}}</time>
7 +
            <span class="post-author">{{.Post.Author}}</span>
8 +
        </div>
9 +
        <h1 class="post-title">{{.Post.Title}}</h1>
10 +
        <div class="post-tags">
11 +
            {{range .Post.Tags}}<a href="/tags/{{lower .}}/" class="tag">{{.}}</a>{{end}}
12 +
        </div>
13 +
    </header>
14 +
15 +
    {{if .Post.GetCover}}
16 +
    <div class="post-cover">
17 +
        <img src="{{.Post.GetCover}}" alt="{{.Post.Title}}" loading="lazy">
18 +
    </div>
19 +
    {{end}}
20 +
21 +
    {{if .Post.TOC}}
22 +
    <nav class="toc" id="toc">
23 +
        <h3>Inhaltsverzeichnis</h3>
24 +
    </nav>
25 +
    {{end}}
26 +
27 +
    <div class="post-content">
28 +
        {{safeHTML .Post.HTMLContent}}
29 +
    </div>
30 +
31 +
    <nav class="post-nav">
32 +
        {{if .PrevPost}}
33 +
        <a href="/posts/{{.PrevPost.Slug}}/" class="post-nav-link post-nav-prev">
34 +
            <span class="post-nav-label">&larr; Neuerer Artikel</span>
35 +
            <span class="post-nav-title">{{.PrevPost.Title}}</span>
36 +
        </a>
37 +
        {{else}}<span class="post-nav-link post-nav-prev disabled"></span>{{end}}
38 +
        {{if .NextPost}}
39 +
        <a href="/posts/{{.NextPost.Slug}}/" class="post-nav-link post-nav-next">
40 +
            <span class="post-nav-label">Älterer Artikel &rarr;</span>
41 +
            <span class="post-nav-title">{{.NextPost.Title}}</span>
42 +
        </a>
43 +
        {{else}}<span class="post-nav-link post-nav-next disabled"></span>{{end}}
44 +
    </nav>
45 +
46 +
    <div class="post-footer">
47 +
        <a href="/" class="back-link">&larr; Zurück zur Startseite</a>
48 +
    </div>
49 +
</article>
50 +
{{end}}
hinzugefügt themes/ehc/templates/tag.html
+31 −0 Datei ansehen
@@ -0,0 +1,31 @@
1 +
{{define "title"}}Tag: {{.Tag}} &middot; {{.Site.Title}}{{end}}
2 +
{{define "content"}}
3 +
<div class="tag-page">
4 +
    <h1>Tag: <span class="highlight">{{.Tag}}</span></h1>
5 +
    <div class="post-list">
6 +
        {{range .Posts}}
7 +
        <article class="post-card">
8 +
            {{if .GetCover}}
9 +
            <a href="/posts/{{.Slug}}/" class="post-card-cover">
10 +
                <img src="{{.GetCover}}" alt="{{.Title}}" loading="lazy">
11 +
            </a>
12 +
            {{end}}
13 +
            <div class="post-card-body">
14 +
                <div class="post-card-meta">
15 +
                    <time datetime="{{isoDate .Date.Time}}">{{formatDate .Date.Time}}</time>
16 +
                    <div class="post-tags">
17 +
                        {{range .Tags}}<a href="/tags/{{lower .}}/" class="tag">{{.}}</a>{{end}}
18 +
                    </div>
19 +
                </div>
20 +
                <h2 class="post-card-title"><a href="/posts/{{.Slug}}/">{{.Title}}</a></h2>
21 +
                <p class="post-card-preview">{{.GetPreview}}</p>
22 +
                <a href="/posts/{{.Slug}}/" class="read-more">Weiterlesen &rarr;</a>
23 +
            </div>
24 +
        </article>
25 +
        {{end}}
26 +
    </div>
27 +
    <div class="post-footer">
28 +
        <a href="/tags/" class="back-link">&larr; Alle Tags</a>
29 +
    </div>
30 +
</div>
31 +
{{end}}
hinzugefügt themes/ehc/templates/tags.html
+14 −0 Datei ansehen
@@ -0,0 +1,14 @@
1 +
{{define "title"}}Tags &middot; {{.Site.Title}}{{end}}
2 +
{{define "content"}}
3 +
<div class="tags-page">
4 +
    <h1>Tags</h1>
5 +
    <div class="tags-cloud">
6 +
        {{range $tag, $count := .Tags}}
7 +
        <a href="/tags/{{lower $tag}}/" class="tag tag-large">{{$tag}} <span class="tag-count">{{$count}}</span></a>
8 +
        {{end}}
9 +
    </div>
10 +
    <div class="post-footer">
11 +
        <a href="/" class="back-link">&larr; Zurück zur Startseite</a>
12 +
    </div>
13 +
</div>
14 +
{{end}}