diff --git a/docker/resume/Caddyfile b/docker/resume/Caddyfile index b7fd78c..697179c 100644 --- a/docker/resume/Caddyfile +++ b/docker/resume/Caddyfile @@ -29,7 +29,7 @@ colinknapp.com { Cache-Control "public, max-age=31536000, immutable" # CSP with hashes for scripts and styles - Content-Security-Policy "default-src 'none'; script-src 'self' 'sha256-oRCvBUmDTuPb8XOF1vLYwhIrcj2kzMbEwX5QzUPAPQI=' 'sha256-Ue6wom48SQbpmwW9QIk7pyVDR5Bg36SetP67V2pDkxc=' 'sha256-PzIpA2rd65QhtrVKWtx1/13mwFPbIl8DKS3arIpG8y4=' 'sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=' 'sha256-1ZUvhca3M/N6hch4NrdPufDPLTnANOpJ4hfsZgRykgg=' 'sha256-Ue6wom48SQbpmwW9QIk7pyVDR5Bg36SetP67V2pDkxc=' 'sha256-ryQsJ+aghKKD/CeXgx8jtsnZT3Epp3EjIw8RyHIq544='; style-src 'self' 'sha256-5oTxos9Qxwhor3qIwHSM12YyIZi5E+tHuFdYER0hXoI=' 'sha256-807UZmWvd6eLc8xVckZkNX6CRP9WV8MzHURc5BgtRWo=' 'sha256-ALJm8rFr/KMj0rKwlJLLJ3iq4FoBvZrBZaaGZS1qGOY=' 'sha256-O42V9brCZFYWsV+Yu5u141A1u5p5LcnOs5K1dVeaIVs=' 'sha256-2EA12+9d+s6rrc0rkdIjfmjbh6p2o0ZSXs4wbZuk/tA='; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none';" + Content-Security-Policy "default-src 'none'; script-src 'self' 'sha256-oRCvBUmDTuPb8XOF1vLYwhIrcj2kzMbEwX5QzUPAPQI=' 'sha256-Ue6wom48SQbpmwW9QIk7pyVDR5Bg36SetP67V2pDkxc=' 'sha256-fOEWMJmrMxKbP5wElIXmDNUlfs6BSn+E9zt81T0Rysg=' 'sha256-q9ac7XWqnIASoBRfs4I4hpSMlnxGARofcEw0cSFfn/E=' 'sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=' 'sha256-1ZUvhca3M/N6hch4NrdPufDPLTnANOpJ4hfsZgRykgg=' 'sha256-JR8sYN1/jgctBktEsjejl175usnuJQ+LimW18BWyL8I=' 'sha256-Ue6wom48SQbpmwW9QIk7pyVDR5Bg36SetP67V2pDkxc=' 'sha256-ryQsJ+aghKKD/CeXgx8jtsnZT3Epp3EjIw8RyHIq544='; style-src 'self' 'sha256-5oTxos9Qxwhor3qIwHSM12YyIZi5E+tHuFdYER0hXoI=' 'sha256-807UZmWvd6eLc8xVckZkNX6CRP9WV8MzHURc5BgtRWo=' 'sha256-efXJB9ojE48KDEisFG5s+pGha1fH1bZA/IKW/ZKrL50=' 'sha256-5Lrk4RP6+4oP0Dbe2qVepxbZ0tYjXoWQHz55YlbGXFk=' 'sha256-2EA12+9d+s6rrc0rkdIjfmjbh6p2o0ZSXs4wbZuk/tA='; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none';" } # Handle 404s @@ -79,7 +79,7 @@ colinknapp.com { Cache-Control "public, max-age=31536000, immutable" # CSP with hashes for scripts and styles - Content-Security-Policy "default-src 'none'; script-src 'self' 'sha256-oRCvBUmDTuPb8XOF1vLYwhIrcj2kzMbEwX5QzUPAPQI=' 'sha256-Ue6wom48SQbpmwW9QIk7pyVDR5Bg36SetP67V2pDkxc=' 'sha256-PzIpA2rd65QhtrVKWtx1/13mwFPbIl8DKS3arIpG8y4=' 'sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=' 'sha256-1ZUvhca3M/N6hch4NrdPufDPLTnANOpJ4hfsZgRykgg=' 'sha256-Ue6wom48SQbpmwW9QIk7pyVDR5Bg36SetP67V2pDkxc=' 'sha256-ryQsJ+aghKKD/CeXgx8jtsnZT3Epp3EjIw8RyHIq544='; style-src 'self' 'sha256-5oTxos9Qxwhor3qIwHSM12YyIZi5E+tHuFdYER0hXoI=' 'sha256-807UZmWvd6eLc8xVckZkNX6CRP9WV8MzHURc5BgtRWo=' 'sha256-ALJm8rFr/KMj0rKwlJLLJ3iq4FoBvZrBZaaGZS1qGOY=' 'sha256-O42V9brCZFYWsV+Yu5u141A1u5p5LcnOs5K1dVeaIVs=' 'sha256-2EA12+9d+s6rrc0rkdIjfmjbh6p2o0ZSXs4wbZuk/tA='; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none';" + Content-Security-Policy "default-src 'none'; script-src 'self' 'sha256-oRCvBUmDTuPb8XOF1vLYwhIrcj2kzMbEwX5QzUPAPQI=' 'sha256-Ue6wom48SQbpmwW9QIk7pyVDR5Bg36SetP67V2pDkxc=' 'sha256-fOEWMJmrMxKbP5wElIXmDNUlfs6BSn+E9zt81T0Rysg=' 'sha256-q9ac7XWqnIASoBRfs4I4hpSMlnxGARofcEw0cSFfn/E=' 'sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=' 'sha256-1ZUvhca3M/N6hch4NrdPufDPLTnANOpJ4hfsZgRykgg=' 'sha256-JR8sYN1/jgctBktEsjejl175usnuJQ+LimW18BWyL8I=' 'sha256-Ue6wom48SQbpmwW9QIk7pyVDR5Bg36SetP67V2pDkxc=' 'sha256-ryQsJ+aghKKD/CeXgx8jtsnZT3Epp3EjIw8RyHIq544='; style-src 'self' 'sha256-5oTxos9Qxwhor3qIwHSM12YyIZi5E+tHuFdYER0hXoI=' 'sha256-807UZmWvd6eLc8xVckZkNX6CRP9WV8MzHURc5BgtRWo=' 'sha256-efXJB9ojE48KDEisFG5s+pGha1fH1bZA/IKW/ZKrL50=' 'sha256-5Lrk4RP6+4oP0Dbe2qVepxbZ0tYjXoWQHz55YlbGXFk=' 'sha256-2EA12+9d+s6rrc0rkdIjfmjbh6p2o0ZSXs4wbZuk/tA='; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none';" } # Handle 404s diff --git a/docker/resume/Caddyfile.local b/docker/resume/Caddyfile.local index 702d1f2..4232461 100644 --- a/docker/resume/Caddyfile.local +++ b/docker/resume/Caddyfile.local @@ -39,6 +39,6 @@ Cache-Control "public, max-age=31536000, immutable" # CSP with hashes for scripts and styles - Content-Security-Policy "default-src 'none'; script-src 'self' 'sha256-oRCvBUmDTuPb8XOF1vLYwhIrcj2kzMbEwX5QzUPAPQI=' 'sha256-Ue6wom48SQbpmwW9QIk7pyVDR5Bg36SetP67V2pDkxc=' 'sha256-PzIpA2rd65QhtrVKWtx1/13mwFPbIl8DKS3arIpG8y4=' 'sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=' 'sha256-1ZUvhca3M/N6hch4NrdPufDPLTnANOpJ4hfsZgRykgg=' 'sha256-Ue6wom48SQbpmwW9QIk7pyVDR5Bg36SetP67V2pDkxc=' 'sha256-ryQsJ+aghKKD/CeXgx8jtsnZT3Epp3EjIw8RyHIq544='; style-src 'self' 'sha256-5oTxos9Qxwhor3qIwHSM12YyIZi5E+tHuFdYER0hXoI=' 'sha256-807UZmWvd6eLc8xVckZkNX6CRP9WV8MzHURc5BgtRWo=' 'sha256-ALJm8rFr/KMj0rKwlJLLJ3iq4FoBvZrBZaaGZS1qGOY=' 'sha256-O42V9brCZFYWsV+Yu5u141A1u5p5LcnOs5K1dVeaIVs=' 'sha256-2EA12+9d+s6rrc0rkdIjfmjbh6p2o0ZSXs4wbZuk/tA='; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none';" + Content-Security-Policy "default-src 'none'; script-src 'self' 'sha256-oRCvBUmDTuPb8XOF1vLYwhIrcj2kzMbEwX5QzUPAPQI=' 'sha256-Ue6wom48SQbpmwW9QIk7pyVDR5Bg36SetP67V2pDkxc=' 'sha256-fOEWMJmrMxKbP5wElIXmDNUlfs6BSn+E9zt81T0Rysg=' 'sha256-q9ac7XWqnIASoBRfs4I4hpSMlnxGARofcEw0cSFfn/E=' 'sha256-+dDNTo7WAOmn2YC875+vn9oH4UkMwlVOGlARp2uq3A4=' 'sha256-1ZUvhca3M/N6hch4NrdPufDPLTnANOpJ4hfsZgRykgg=' 'sha256-JR8sYN1/jgctBktEsjejl175usnuJQ+LimW18BWyL8I=' 'sha256-Ue6wom48SQbpmwW9QIk7pyVDR5Bg36SetP67V2pDkxc=' 'sha256-ryQsJ+aghKKD/CeXgx8jtsnZT3Epp3EjIw8RyHIq544='; style-src 'self' 'sha256-5oTxos9Qxwhor3qIwHSM12YyIZi5E+tHuFdYER0hXoI=' 'sha256-807UZmWvd6eLc8xVckZkNX6CRP9WV8MzHURc5BgtRWo=' 'sha256-efXJB9ojE48KDEisFG5s+pGha1fH1bZA/IKW/ZKrL50=' 'sha256-5Lrk4RP6+4oP0Dbe2qVepxbZ0tYjXoWQHz55YlbGXFk=' 'sha256-2EA12+9d+s6rrc0rkdIjfmjbh6p2o0ZSXs4wbZuk/tA='; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none';" } } diff --git a/docker/resume/convert-favicon.sh b/docker/resume/convert-favicon.sh new file mode 100755 index 0000000..7e650bf --- /dev/null +++ b/docker/resume/convert-favicon.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# Generate the SVG favicon +echo "Generating SVG favicon..." +node generate-favicon.js + +# Check if the SVG was generated +if [ ! -f "favicon.svg" ]; then + echo "Error: favicon.svg was not generated." + exit 1 +fi + +# Create a temporary directory for favicon files +mkdir -p favicon_tmp + +# Convert SVG to PNG files of different sizes +echo "Converting SVG to PNG files of various sizes..." +for size in 16 32 48 64 128 256; do + # Using ImageMagick's convert command if available + if command -v convert > /dev/null; then + convert -background none -size ${size}x${size} favicon.svg favicon_tmp/favicon-${size}.png + else + echo "ImageMagick not found. Please install it to convert SVG to PNG." + exit 1 + fi +done + +# Create favicon.ico from the PNG files +echo "Creating favicon.ico..." +if command -v convert > /dev/null; then + convert favicon_tmp/favicon-16.png favicon_tmp/favicon-32.png favicon_tmp/favicon-48.png favicon.ico +else + echo "ImageMagick not found. Please install it to create favicon.ico." + exit 1 +fi + +# Create apple-touch-icon.png (for iOS) +echo "Creating apple-touch-icon.png..." +cp favicon_tmp/favicon-128.png apple-touch-icon.png + +# Create favicon-32x32.png and favicon-16x16.png (for modern browsers) +echo "Creating standard browser favicons..." +cp favicon_tmp/favicon-32.png favicon-32x32.png +cp favicon_tmp/favicon-16.png favicon-16x16.png + +# Clean up temporary directory +echo "Cleaning up temporary files..." +rm -rf favicon_tmp + +echo "Favicon generation complete!" +echo "Created: favicon.ico, favicon-16x16.png, favicon-32x32.png, apple-touch-icon.png" \ No newline at end of file diff --git a/docker/resume/csv-tool-output.html b/docker/resume/csv-tool-output.html index 71698e9..074ea36 100644 --- a/docker/resume/csv-tool-output.html +++ b/docker/resume/csv-tool-output.html @@ -7,10 +7,10 @@ CSV Viewer - Colin Knapp - + - + - +
diff --git a/docker/resume/favicon.ico b/docker/resume/favicon.ico index 0519ecb..56c1fa4 100644 Binary files a/docker/resume/favicon.ico and b/docker/resume/favicon.ico differ diff --git a/docker/resume/favicon.svg b/docker/resume/favicon.svg new file mode 100644 index 0000000..81b05c3 --- /dev/null +++ b/docker/resume/favicon.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docker/resume/generate-favicon.js b/docker/resume/generate-favicon.js new file mode 100755 index 0000000..e0aac99 --- /dev/null +++ b/docker/resume/generate-favicon.js @@ -0,0 +1,38 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +// Create an SVG favicon with a gradient background and initials +function generateFavicon() { + // Define colors for gradient + const primaryColor = '#3498db'; // Blue + const secondaryColor = '#2980b9'; // Darker blue + + // Create SVG content with gradient and text + const svgContent = ` + + + + + + + + + + + + + + +`; + + // Write SVG file + fs.writeFileSync(path.join(__dirname, 'favicon.svg'), svgContent); + console.log('Generated favicon.svg'); +} + +// Run the generator +generateFavicon(); \ No newline at end of file diff --git a/docker/resume/includes.js b/docker/resume/includes.js index 16d51ef..a0fdaea 100644 --- a/docker/resume/includes.js +++ b/docker/resume/includes.js @@ -19,6 +19,27 @@ document.addEventListener('DOMContentLoaded', function() { } } + // Function to include HTML content in the head + async function includeInHead(filePath) { + try { + const response = await fetch(filePath); + if (!response.ok) { + throw new Error(`Failed to load ${filePath}: ${response.status} ${response.statusText}`); + } + const content = await response.text(); + const headElement = document.getElementsByTagName('head')[0]; + const tempDiv = document.createElement('div'); + tempDiv.innerHTML = content; + + // Append each child from the loaded content to the head + while (tempDiv.firstChild) { + headElement.appendChild(tempDiv.firstChild); + } + } catch (error) { + console.error('Error including HTML in head:', error); + } + } + // Function to set active navigation item function setActiveNavItem() { const currentPath = window.location.pathname; @@ -147,6 +168,9 @@ document.addEventListener('DOMContentLoaded', function() { }); } + // Include favicon links + includeInHead('/includes/favicon-links.html'); + // Process header and footer placeholders const headerElement = document.getElementById('header-include'); const footerElement = document.getElementById('footer-include'); diff --git a/docker/resume/includes/favicon-links.html b/docker/resume/includes/favicon-links.html new file mode 100644 index 0000000..ff0287c --- /dev/null +++ b/docker/resume/includes/favicon-links.html @@ -0,0 +1,5 @@ + + + + + diff --git a/docker/resume/index-with-includes.html b/docker/resume/index-with-includes.html index e2078d0..6578bae 100644 --- a/docker/resume/index-with-includes.html +++ b/docker/resume/index-with-includes.html @@ -6,11 +6,11 @@ Colin Knapp - Portfolio - + - + - +
diff --git a/docker/resume/index.html b/docker/resume/index.html index e01f73e..a840d99 100644 --- a/docker/resume/index.html +++ b/docker/resume/index.html @@ -8,9 +8,9 @@ - + - +
diff --git a/docker/resume/one-pager-tools/csv-tool.html b/docker/resume/one-pager-tools/csv-tool.html index 6dfc97b..dc2d36b 100644 --- a/docker/resume/one-pager-tools/csv-tool.html +++ b/docker/resume/one-pager-tools/csv-tool.html @@ -7,10 +7,10 @@ CSV Viewer - Colin Knapp - + - + - +
diff --git a/docker/resume/one-pager-tools/template.html b/docker/resume/one-pager-tools/template.html index 87f23a5..f8ff1ca 100644 --- a/docker/resume/one-pager-tools/template.html +++ b/docker/resume/one-pager-tools/template.html @@ -6,14 +6,14 @@ Colin Knapp Tools - - + + - + - +
diff --git a/docker/resume/one-pager-tools/tool-with-includes.html b/docker/resume/one-pager-tools/tool-with-includes.html index 440815c..3337250 100644 --- a/docker/resume/one-pager-tools/tool-with-includes.html +++ b/docker/resume/one-pager-tools/tool-with-includes.html @@ -7,13 +7,13 @@ Tool Example - Colin Knapp - + - + - +
diff --git a/docker/resume/stories/airport-dns.html b/docker/resume/stories/airport-dns.html index a9dd94b..ef4d569 100644 --- a/docker/resume/stories/airport-dns.html +++ b/docker/resume/stories/airport-dns.html @@ -6,11 +6,12 @@ Airport DNS Infrastructure - Colin Knapp Case Study - + - - + + +
@@ -53,4 +54,4 @@ - \ No newline at end of file + diff --git a/docker/resume/stories/fawe-plotsquared.html b/docker/resume/stories/fawe-plotsquared.html index a8922a4..6a946ca 100644 --- a/docker/resume/stories/fawe-plotsquared.html +++ b/docker/resume/stories/fawe-plotsquared.html @@ -6,11 +6,12 @@ FastAsyncWorldEdit & PlotSquared - Colin Knapp Case Study - + - - + + +
@@ -54,4 +55,4 @@ - \ No newline at end of file + diff --git a/docker/resume/stories/healthcare-platform.html b/docker/resume/stories/healthcare-platform.html index 14705d2..8564749 100644 --- a/docker/resume/stories/healthcare-platform.html +++ b/docker/resume/stories/healthcare-platform.html @@ -6,11 +6,12 @@ Healthcare Platform - Colin Knapp Case Study - + - - + + +
@@ -54,4 +55,4 @@ - \ No newline at end of file + diff --git a/docker/resume/stories/index.html b/docker/resume/stories/index.html index 927ac7e..8595711 100644 --- a/docker/resume/stories/index.html +++ b/docker/resume/stories/index.html @@ -6,12 +6,12 @@ Colin Knapp - Stories & Case Studies - + - - + + - +
diff --git a/docker/resume/stories/nitric-leadership.html b/docker/resume/stories/nitric-leadership.html index 0e4e39d..9124a5c 100644 --- a/docker/resume/stories/nitric-leadership.html +++ b/docker/resume/stories/nitric-leadership.html @@ -6,11 +6,12 @@ NitricConcepts Leadership - Colin Knapp Case Study - + - - + + +
@@ -53,4 +54,4 @@ - \ No newline at end of file + diff --git a/docker/resume/stories/open-source-success.html b/docker/resume/stories/open-source-success.html index 7f5706a..bbf7fdb 100644 --- a/docker/resume/stories/open-source-success.html +++ b/docker/resume/stories/open-source-success.html @@ -6,12 +6,12 @@ Open Source Community Success - Colin Knapp Case Study - + - - + + - +
diff --git a/docker/resume/stories/story-with-includes.html b/docker/resume/stories/story-with-includes.html index 4ea1eae..39c1b49 100644 --- a/docker/resume/stories/story-with-includes.html +++ b/docker/resume/stories/story-with-includes.html @@ -6,12 +6,12 @@ Story Example - Colin Knapp - - + + - + - +
diff --git a/docker/resume/stories/template-story.html b/docker/resume/stories/template-story.html index ec5075f..b49e50f 100644 --- a/docker/resume/stories/template-story.html +++ b/docker/resume/stories/template-story.html @@ -6,12 +6,12 @@ [Story Title] - Colin Knapp Case Study - + - - + + - +
diff --git a/docker/resume/stories/viperwire.html b/docker/resume/stories/viperwire.html index 5e7bbd9..d22fb96 100644 --- a/docker/resume/stories/viperwire.html +++ b/docker/resume/stories/viperwire.html @@ -6,11 +6,11 @@ ViperWire Cybersecurity - Colin Knapp Case Study - + - - - + + + diff --git a/docker/resume/stories/wordpress-security.html b/docker/resume/stories/wordpress-security.html index e740a3f..b5efaba 100644 --- a/docker/resume/stories/wordpress-security.html +++ b/docker/resume/stories/wordpress-security.html @@ -6,11 +6,12 @@ WordPress Security Automation - Colin Knapp Case Study - + - - + + +
@@ -53,4 +54,4 @@ - \ No newline at end of file + diff --git a/docker/resume/template-with-includes.html b/docker/resume/template-with-includes.html index 3eb4d08..cae06be 100644 --- a/docker/resume/template-with-includes.html +++ b/docker/resume/template-with-includes.html @@ -6,11 +6,11 @@ Template with Includes - Colin Knapp - + - + - +
diff --git a/docker/resume/update-favicon.js b/docker/resume/update-favicon.js new file mode 100644 index 0000000..1869202 --- /dev/null +++ b/docker/resume/update-favicon.js @@ -0,0 +1,38 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +// Create a simple ICO file directly (base64 encoded) +function generateFaviconICO() { + // This is a minimal 16x16 ICO file with a blue square and white "CK" text + // The data is base64 encoded + const icoBase64 = ` + AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAVlZWAFZWVgBWVlYAVlZWAFZWVgBWVlYAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFZWVgBWVlYCVlZWQFZWVoBWVlaAVlZWQFZWVgJWVlYAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFZWVgBWVlYGVlZWaFZWVuJWVlb/VlZW/1ZWVuJWVlZoVlZW + BlZWVgAAAAAAAAAAAAAAAAAAAAAAVlZWAFZWVgBWVlYmVlZWtVZWVv9WVlb/VlZW/1ZWVv9WVlb/ + VlZWtVZWViZWVlYAVlZWAAAAAAAAAAAAAAAAAFZWVgBWVlY0VlZW1VZWVv9WVlb/VlZW/1ZWVv9W + Vlb/VlZW/1ZWVtVWVlY0VlZWAAAAAAAAAAAAAAAAAAAAAABWVlYSVlZWrVZWVv9WVlb/VlZW/1ZW + Vv9WVlb/VlZW/1ZWVv9WVlatVlZWElZWVgAAAAAAAAAAAAAAAAAAAAAAVlZWRlZWVvFWVlb/VlZW + /1ZWVv9WVlb/VlZW/1ZWVv9WVlbxVlZWRlZWVgAAAAAAAAAAAAAAAAAAAAAAVlZWRlZWVvFWVlb/ + VlZW/1ZWVv9WVlb/VlZW/1ZWVv9WVlbxVlZWRlZWVgAAAAAAAAAAAAAAAAAAAAAAVlZWElZWVq1W + Vlb/VlZW/1ZWVv9WVlb/VlZW/1ZWVv9WVlb/VlZWrVZWVhJWVlYAAAAAAAAAAAAAAAAAAAAAAFZW + VjRWVlbVVlZW/1ZWVv9WVlb/VlZW/1ZWVv9WVlb/VlZW1VZWVjRWVlYAAAAAAAAAAAAAAAAAVlZW + AFZWVgBWVlYmVlZWtVZWVv9WVlb/VlZW/1ZWVv9WVlb/VlZWtVZWViZWVlYAVlZWAAAAAAAAAAAA + AAAAAAAAAAAAAFZWVgZWVlZoVlZW4lZWVv9WVlb/VlZW4lZWVmhWVlYGVlZWAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAFZWVgJWVlZAVlZWgFZWVoBWVlZAVlZWAlZWVgAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVlZWAFZWVgBWVlYAVlZWAFZWVgBWVlYAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + `.trim(); + + // Write the base64 data to the ICO file + const icoBuffer = Buffer.from(icoBase64, 'base64'); + fs.writeFileSync(path.join(__dirname, 'favicon.ico'), icoBuffer); + console.log('Generated favicon.ico'); +} + +// Run the generator +generateFaviconICO(); \ No newline at end of file