diff --git a/src/content/projects/invoice/images/customers.png b/src/content/projects/invoice/images/customers.png
new file mode 100644
index 0000000..5344f3f
--- /dev/null
+++ b/src/content/projects/invoice/images/customers.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9a3c0131bd4a0b227a15cffd1029352cd8c44c8f9afbfa271ad88fbd26e54538
+size 43398
diff --git a/src/content/projects/invoice/images/edit-customer.png b/src/content/projects/invoice/images/edit-customer.png
new file mode 100644
index 0000000..2778f5d
--- /dev/null
+++ b/src/content/projects/invoice/images/edit-customer.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:81018ad808f5ebe1e0cb436913b20f6ab0498d68c3c86885bf71e52ad258bf2b
+size 37835
diff --git a/src/content/projects/invoice/images/edit-profile.png b/src/content/projects/invoice/images/edit-profile.png
new file mode 100644
index 0000000..dc88236
--- /dev/null
+++ b/src/content/projects/invoice/images/edit-profile.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:01aae5353baeea5d55f9cf612729d3abd1fc6e1fbb4a1fe325b93322fae854aa
+size 42388
diff --git a/src/content/projects/invoice/images/invoices.png b/src/content/projects/invoice/images/invoices.png
new file mode 100644
index 0000000..d31bbb1
--- /dev/null
+++ b/src/content/projects/invoice/images/invoices.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5cc5db1fb6dc53f7c11b6f4fae76950a6e33db12604ad1a9951c18b17bc258f4
+size 51188
diff --git a/src/content/projects/invoice/images/overview.png b/src/content/projects/invoice/images/overview.png
new file mode 100644
index 0000000..46c89a4
--- /dev/null
+++ b/src/content/projects/invoice/images/overview.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:10999609b1e0bf84e2f8bd53d63777ca356db6f954551dfc7a949bdd7dad534c
+size 36679
diff --git a/src/content/projects/invoice/index.mdx b/src/content/projects/invoice/index.mdx
index 70c4c2f..1a40372 100644
--- a/src/content/projects/invoice/index.mdx
+++ b/src/content/projects/invoice/index.mdx
@@ -12,6 +12,18 @@ links:
]
---
+import bg from './images/bg.jpg'
+import invoices from './images/invoices.png'
+import customers from './images/customers.png'
+import editCustomers from './images/edit-customer.png'
+import editProfile from './images/edit-profile.png'
+import overview from './images/overview.png'
+import ImageSlider from '@components/ImageSlider.svelte'
+import Image from '@components/Image.astro'
+
+
+# Einleitung
+
In meiner Freizeit übernehme ich gerne kleinere Aufträge und erledige Botengänge, Aufbauten und Abholungen für andere.
Ein unvermeidlicher Bestandteil dieser Tätigkeiten ist das Erstellen von Rechnungen im PDF-Format. Anfangs habe ich mich dem manuellen Prozess hingegeben und die ersten Rechnungen in Figma erstellt. Doch wie es unter Programmierer*innen oft heißt:
@@ -20,25 +32,32 @@ Ein unvermeidlicher Bestandteil dieser Tätigkeiten ist das Erstellen von Rechnu
Aus dieser Überlegung heraus entstand mein neuestes Hobbyprojekt – **"Invoice."**
-## Entwicklung
+
+
+
+
+
+
+
+
+# Entwicklung
In der Entwicklung habe ich stets das Prinzip 'K.I.S.S.' im Hinterkopf behalten: Keep it simple, stupid. Für dieses Projekt bedeutete das die Auswahl von "langweiligen", aber mir bestens vertrauten Technologien:
-[-> SvelteKit](https://kit.svelte.dev)
+## [🚀 SvelteKit](https://kit.svelte.dev)
Für eine effiziente und reaktive Benutzeroberfläche.
-[-> UNOcss](https://unocss.dev/)
+## [🎨 UNOcss](https://unocss.dev/)
Die schnellere Tailwind Alternative.
-[-> TypesafeI18n]()
+## [🌍 TypesafeI18n](https://github.com/ivanhofer/typesafe-i18n)
Um mehrsprachige Unterstützung ohne komplizierte Logik zu integrieren.
-[-> Prisma](https://prisma.io)
+## [🛠️ Prisma](https://prisma.io)
Als Datenbankzugriffslayer für eine reibungslose Datenverwaltung.
-[-> SQLite](https://www.sqlite.org/index.html)
+## [🗃️ SQLite](https://www.sqlite.org/index.html)
Als zuverlässiges Backend, das sich ideal für kleinere Projekte eignet.
-Diese bewährten Technologien bildeten das robuste Fundament, auf dem "Invoice" aufgebaut wurde.
-
-
+## [📄Playwright ](https://playwright.dev)
+Zum erstellen der PDFs.
diff --git a/src/content/projects/isyncrasy/index.mdx b/src/content/projects/isyncrasy/index.mdx
index e7ac32e..b5436c4 100644
--- a/src/content/projects/isyncrasy/index.mdx
+++ b/src/content/projects/isyncrasy/index.mdx
@@ -5,20 +5,25 @@ draft: false
cover: ./images/main.png
icon: "/projects/isyncrasy/favicon.ico"
description: "A small fun virtual OS build with svelte"
+links: [["live", "https://isyncrasy.com"]]
tags: ["svelte", "web", "os"]
---
-# Isyncrasy
+
+Isyncrasy ist ein kleines virtuelles Betriebssystem, das mit Svelte erstellt wurde. Es ist ein kleines Projekt, das ich gemacht habe, um Svelte zu lernen. Es ist ein einfaches Betriebssystem, das eine E-Mail-Anwendung und eine Terminalanwendung enthält. Es ist ein einfaches Projekt, aber es war sehr lehrreich.
import Image from "@components/Image.astro"
import Main from "./images/main.png"
import Mail from "./images/mail.png"
import Terminal from "./images/terminal.png"
import ImageGallery from "@components/ImageGallery.svelte"
+import ImageSlider from "@components/ImageSlider.svelte"
-
-
-
+
+
+
+
+
diff --git a/src/content/projects/karl/index.mdx b/src/content/projects/karl/index.mdx
index d8aec1e..022011b 100644
--- a/src/content/projects/karl/index.mdx
+++ b/src/content/projects/karl/index.mdx
@@ -26,7 +26,7 @@ import ImageGallery from "@components/ImageGallery.svelte"
> K.A.R.L ist eine WebApp die einem dabei hilft 360Grad Panoramas in Sektionen einzuteilen, (Himmel, Boden, Bäume usw...) und dann den Anteil der einzelnen Sektionen am Gesamtbild festzustellen.
-## Einleitung
+# Einleitung
Das Projekt ist aus der Zusammenarbeit mit zwei Freunden entstanden. Der eine steckt gerade mitten in der Konzeptionsphase seiner Bachelorarbeit (Geographie), die sich mit der Auswirkung von Vegetation auf das Stadtklima beschäftigt. Dazu hat er an verschiedenen Orten in Köln Albedo Messungen vorgenommen, also quasi "wieviel Licht kommt vom Himmel, und wieviel davon wird vom Boden reflektiert". Um diese Messungen in den richtigen Kontext zu setzen hat er von jedem Messort 360 Panoramas angelegt, diese sehen ungefähr so aus:
@@ -36,7 +36,7 @@ Dazu brauchte er jetzt Angaben wieviel Prozent der Sicht zum Beispiel Vegetation
-## Problemstellung
+# Problemstellung
Wenn wir jetzt einfach naiv hingehen und die Pixel der einzelnen Farben zählen und daraus eine prozentuale Verteilung machen kriegen wir das klassische Problem mit der Verzerrung das die Menschheit schon seit Jahrhunderten mit Karten hat. Undzwar lassen sich Kugeln nur sehr ungern zwei dimensional darstellen, dabei kommt es immer zu Verzerrungen, wie folgendes Bild visualisiert.
@@ -63,31 +63,31 @@ Hier noch einiger der ersten Versuch in Desmos (fantastisches Tool btw):
-## Die Technologien
+# Die Technologien
Ich hatte den Wunsch eine WebApp zu bauen die reintheoretisch auch komplett offline funktioniert. Deswegen werden nach dem ersten laden der Website keine weiteren Daten mehr verschickt, sondern alles wird im Browser ausgeführt. Dies ist bei einer Anwendung die sehr viele Pixel bearbeiten und so sehr viel Performance braucht schwierig da die Ressourcen des Browsers begrenzt sind. Folgende Technologien haben mir dabei geholfen die User Experience trotzdem halbwegs okay zu gestalten:
-### Canvas
+## Canvas
Wenn es um irgendwas mit Pixeln im Browser geht kommt man an Canvas2D eigentlich gar nicht vorbei. Canvas ist durch seine programmatische Schnittstelle optimal für diesen Job geeignet.
-### Web Workers
+## Web Workers
Normalerweise werden im Browser alle Operationen einer Website in einem Thread ausgeführt. Dies führt dazu eine rechenintensive Aufgabe die komplette Website zum erliegen bringen kann. Dabei können WebWorker Abhilfe schaffen. WebWorker können beliebigen Code in einem seperaten Thread ausführen mit dem einzigen Hinderniss das die Kommunikation mit dem Haupt Thread etwas schwierig ist.
Bei K.A.R.L werden zwei WebWorker eingesetzt, der pixel-worker ist für das Analysieren der Segmentationsmap und für das Eimer Werkzeug verantwortlich und der ai-worker fürs ausführen des Tensorflow Codes.
-### Tensorflow
+## Tensorflow
Warum per Hand malen nach zahlen machen wenn der Rechner das ganz automagisch kann? Hab ich mir auch gedacht und Tensorflow mit dem [ade20k](https://groups.csail.mit.edu/vision/datasets/ADE20K/) eingebaut. Dieses Netwerk ist super darin Bäume, Boden, Beton und Himmel zu erkennen. In der Editor Ansicht versteckt sich diese Funktion rechts unter dem "AI" Knopf.
-### IndexDB
+## IndexDB
Wenn es darum geht größere Mengen an Daten (vorallem Bilder), lokal im Browser zu speichern geht das eigentlich nur richtig mit IndexDB *(ja, localStorage mit Base64 Bildern könnte auch gehen, ist aber in machen Browsern auf 5mb beschränkt)*. Da die IndexDB Api aber zu einer der [verwirrensten Browser Api's weit und breit gehört](https://nolanlawson.github.io/offlinefirst-2016-03/#/27) benutze ich [idb](npmjs.com/package/idb), eine fantastische kleine Wrapperlibrary um IndexDB rum die auch noch Promises unterstützt.
-## Interessantes...
+# Interessantes...
-### FloodFill Allgorithmus
+## FloodFill Allgorithmus
Nachdem ich einige Panoramas per Hand mit den Tools segmentiert habe ist mir aufgefallen das man sehr oft einfach Regionen die eine ähnliche Farbe haben anmalt. Das brachte mich auf die Idee ein Fill Tool ähnlich wie in Photoshop zu bauen, aber vieeel besser.
@@ -98,7 +98,7 @@ Das Tool funktioniert ungefähr so:
4. Das Bild wird zurückgeschickt
5. Im Canvas Code wird dann aufgrund des Wertes der einzelnen Pixel entschieden ob dies gefüllt werden oder nicht
-### Svelte Bindings
+## Svelte Bindings
Ich fand es immer kompliziert State über mehrere Komponenten hinweg zu regeln. Ein Beispiel wäre der Editor, er besteht aus drei einzelnen Komponenten (Toolbar, Topbar, PaintArea) die alle wissen müssen welches Farbe und welches Werkzeug gerade aktiv sind. Man könnte diesen State in einen globalen Store schreiben und in jedem der einzelnen Komponenten darauf zugreifen, aber eigentlich ist das aktive Werkzeug nur in dem Editor Kontext wichtig. Also liegt dieser State jetzt in dem Editor Komponent der in per binding an seine Unterkomponenten weitergibt, das ganze sieht dan ungefähr so aus:
@@ -116,7 +116,6 @@ Ich fand es immer kompliziert State über mehrere Komponenten hinweg zu regeln.
-