Compare changes

Choose any two refs to compare.

+2 -22
.gitignore
··· 1 - # build output 2 - dist/ 3 - 4 - # generated types 5 - .astro/ 6 - 7 - # dependencies 8 - node_modules/ 9 - 10 - # logs 11 - npm-debug.log* 12 - yarn-debug.log* 13 - yarn-error.log* 14 - pnpm-debug.log* 15 - 16 - # environment variables 17 - .env 18 - .env.production 19 - 20 - # macOS-specific files 21 - .DS_Store 22 - .vercel 1 + .wrangler 2 + node_modules
+19
.tangled/workflows/deploy.yml
··· 1 + # deploy 2 + 3 + when: 4 + - event: ["push"] 5 + branch: ["main"] 6 + 7 + engine: "nixery" 8 + 9 + dependencies: 10 + nixpkgs: 11 + - nodejs 12 + - pnpm 13 + - gnused 14 + 15 + steps: 16 + - name: "deps" 17 + command: "pnpm install" 18 + - name: "deploy" 19 + command: "pnpm run deploy"
-4
.vscode/extensions.json
··· 1 - { 2 - "recommendations": ["astro-build.astro-vscode"], 3 - "unwantedRecommendations": [] 4 - }
-11
.vscode/launch.json
··· 1 - { 2 - "version": "0.2.0", 3 - "configurations": [ 4 - { 5 - "command": "./node_modules/.bin/astro dev", 6 - "name": "Development server", 7 - "request": "launch", 8 - "type": "node-terminal" 9 - } 10 - ] 11 - }
-3
README.md
··· 1 - # Dane's Personal Site 2 - 3 - Welcome to the repository for my personal site! This iteration is using [astro](https://astro.build). Feel free to look around if you want to use this as an example for your personal website.
-21
astro.config.ts
··· 1 - import { defineConfig, sharpImageService } from "astro/config"; 2 - import sitemap from "@astrojs/sitemap"; 3 - import UnoCSS from "unocss/astro"; 4 - 5 - export default defineConfig({ 6 - site: "https://dane.computer", 7 - image: { 8 - service: sharpImageService(), 9 - }, 10 - integrations: [ 11 - UnoCSS({ 12 - injectReset: true, 13 - }), 14 - sitemap(), 15 - ], 16 - markdown: { 17 - shikiConfig: { 18 - theme: "material-theme-palenight", 19 - }, 20 - }, 21 - });
bun.lockb

This is a binary file and will not be displayed.

+11 -25
package.json
··· 1 1 { 2 - "name": "danethe.dev-astro", 3 - "type": "module", 4 - "version": "0.0.1", 5 - "scripts": { 6 - "dev": "astro dev", 7 - "start": "astro dev", 8 - "build": "astro build", 9 - "preview": "astro preview", 10 - "astro": "astro" 11 - }, 12 - "dependencies": { 13 - "@astrojs/sitemap": "latest", 14 - "@notionhq/client": "^2.2.10", 15 - "@tailwindcss/typography": "^0.5.9", 16 - "astro": "latest", 17 - "sharp": "^0.33.0" 18 - }, 19 - "trustedDependencies": [ 20 - "sharp" 21 - ], 22 - "devDependencies": { 23 - "@iconify-json/lucide": "^1.1.144", 24 - "@unocss/reset": "^0.58.0", 25 - "unocss": "^0.58.0" 26 - } 2 + "name": "website", 3 + "version": "0.0.0", 4 + "private": true, 5 + "scripts": { 6 + "deploy": "wrangler deploy", 7 + "dev": "wrangler dev", 8 + "start": "wrangler dev" 9 + }, 10 + "devDependencies": { 11 + "wrangler": "^4.55.0" 12 + } 27 13 }
+887
pnpm-lock.yaml
··· 1 + lockfileVersion: '9.0' 2 + 3 + settings: 4 + autoInstallPeers: true 5 + excludeLinksFromLockfile: false 6 + 7 + importers: 8 + 9 + .: 10 + devDependencies: 11 + wrangler: 12 + specifier: ^4.55.0 13 + version: 4.55.0 14 + 15 + packages: 16 + 17 + '@cloudflare/kv-asset-handler@0.4.1': 18 + resolution: {integrity: sha512-Nu8ahitGFFJztxUml9oD/DLb7Z28C8cd8F46IVQ7y5Btz575pvMY8AqZsXkX7Gds29eCKdMgIHjIvzskHgPSFg==} 19 + engines: {node: '>=18.0.0'} 20 + 21 + '@cloudflare/unenv-preset@2.7.13': 22 + resolution: {integrity: sha512-NulO1H8R/DzsJguLC0ndMuk4Ufv0KSlN+E54ay9rn9ZCQo0kpAPwwh3LhgpZ96a3Dr6L9LqW57M4CqC34iLOvw==} 23 + peerDependencies: 24 + unenv: 2.0.0-rc.24 25 + workerd: ^1.20251202.0 26 + peerDependenciesMeta: 27 + workerd: 28 + optional: true 29 + 30 + '@cloudflare/workerd-darwin-64@1.20251213.0': 31 + resolution: {integrity: sha512-29mPlP7xgyik85EHotrakuQur5WfuAR4tRAntRFwLEFnB88RB7br6Me9wb15itu/1l9nMyimZWhBMAfnEs5PQw==} 32 + engines: {node: '>=16'} 33 + cpu: [x64] 34 + os: [darwin] 35 + 36 + '@cloudflare/workerd-darwin-arm64@1.20251213.0': 37 + resolution: {integrity: sha512-gn4nIg7hbGyHxyNdVqDmSvgMfgytFr4Z/OXGp2ZorP1+OKeGLvfQ70LEEYY/kZwSsbOqEYDXyU6LzPj4n86NZQ==} 38 + engines: {node: '>=16'} 39 + cpu: [arm64] 40 + os: [darwin] 41 + 42 + '@cloudflare/workerd-linux-64@1.20251213.0': 43 + resolution: {integrity: sha512-zMO9tV4aGDZnRfsWg5MC1mbXaRdutDcMeqH5XMzGHsuKO66tbBipV38gX76PLqxKH+UfbE3Uo3jk3iqIuPEF3g==} 44 + engines: {node: '>=16'} 45 + cpu: [x64] 46 + os: [linux] 47 + 48 + '@cloudflare/workerd-linux-arm64@1.20251213.0': 49 + resolution: {integrity: sha512-8pQk1dCzdyZdJXehIhxkFMTc5lTLxzqmxskCGlpbem/pWIPTAEjt25OFCxq5Z3iU/x/kI8tcQdYRYx77KS32mQ==} 50 + engines: {node: '>=16'} 51 + cpu: [arm64] 52 + os: [linux] 53 + 54 + '@cloudflare/workerd-windows-64@1.20251213.0': 55 + resolution: {integrity: sha512-QBwfyZXTzI2JHLS7ZEuVVMC81PAQyNxPdcv9Dxd8wvV4QYF7B97h9pUtaBnqUdlBwL6e3O8QniYkOl8c7bEFJw==} 56 + engines: {node: '>=16'} 57 + cpu: [x64] 58 + os: [win32] 59 + 60 + '@cspotcode/source-map-support@0.8.1': 61 + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} 62 + engines: {node: '>=12'} 63 + 64 + '@emnapi/runtime@1.7.1': 65 + resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} 66 + 67 + '@esbuild/aix-ppc64@0.27.0': 68 + resolution: {integrity: sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==} 69 + engines: {node: '>=18'} 70 + cpu: [ppc64] 71 + os: [aix] 72 + 73 + '@esbuild/android-arm64@0.27.0': 74 + resolution: {integrity: sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==} 75 + engines: {node: '>=18'} 76 + cpu: [arm64] 77 + os: [android] 78 + 79 + '@esbuild/android-arm@0.27.0': 80 + resolution: {integrity: sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==} 81 + engines: {node: '>=18'} 82 + cpu: [arm] 83 + os: [android] 84 + 85 + '@esbuild/android-x64@0.27.0': 86 + resolution: {integrity: sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==} 87 + engines: {node: '>=18'} 88 + cpu: [x64] 89 + os: [android] 90 + 91 + '@esbuild/darwin-arm64@0.27.0': 92 + resolution: {integrity: sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==} 93 + engines: {node: '>=18'} 94 + cpu: [arm64] 95 + os: [darwin] 96 + 97 + '@esbuild/darwin-x64@0.27.0': 98 + resolution: {integrity: sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==} 99 + engines: {node: '>=18'} 100 + cpu: [x64] 101 + os: [darwin] 102 + 103 + '@esbuild/freebsd-arm64@0.27.0': 104 + resolution: {integrity: sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==} 105 + engines: {node: '>=18'} 106 + cpu: [arm64] 107 + os: [freebsd] 108 + 109 + '@esbuild/freebsd-x64@0.27.0': 110 + resolution: {integrity: sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==} 111 + engines: {node: '>=18'} 112 + cpu: [x64] 113 + os: [freebsd] 114 + 115 + '@esbuild/linux-arm64@0.27.0': 116 + resolution: {integrity: sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==} 117 + engines: {node: '>=18'} 118 + cpu: [arm64] 119 + os: [linux] 120 + 121 + '@esbuild/linux-arm@0.27.0': 122 + resolution: {integrity: sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==} 123 + engines: {node: '>=18'} 124 + cpu: [arm] 125 + os: [linux] 126 + 127 + '@esbuild/linux-ia32@0.27.0': 128 + resolution: {integrity: sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==} 129 + engines: {node: '>=18'} 130 + cpu: [ia32] 131 + os: [linux] 132 + 133 + '@esbuild/linux-loong64@0.27.0': 134 + resolution: {integrity: sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==} 135 + engines: {node: '>=18'} 136 + cpu: [loong64] 137 + os: [linux] 138 + 139 + '@esbuild/linux-mips64el@0.27.0': 140 + resolution: {integrity: sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==} 141 + engines: {node: '>=18'} 142 + cpu: [mips64el] 143 + os: [linux] 144 + 145 + '@esbuild/linux-ppc64@0.27.0': 146 + resolution: {integrity: sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==} 147 + engines: {node: '>=18'} 148 + cpu: [ppc64] 149 + os: [linux] 150 + 151 + '@esbuild/linux-riscv64@0.27.0': 152 + resolution: {integrity: sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==} 153 + engines: {node: '>=18'} 154 + cpu: [riscv64] 155 + os: [linux] 156 + 157 + '@esbuild/linux-s390x@0.27.0': 158 + resolution: {integrity: sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==} 159 + engines: {node: '>=18'} 160 + cpu: [s390x] 161 + os: [linux] 162 + 163 + '@esbuild/linux-x64@0.27.0': 164 + resolution: {integrity: sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==} 165 + engines: {node: '>=18'} 166 + cpu: [x64] 167 + os: [linux] 168 + 169 + '@esbuild/netbsd-arm64@0.27.0': 170 + resolution: {integrity: sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==} 171 + engines: {node: '>=18'} 172 + cpu: [arm64] 173 + os: [netbsd] 174 + 175 + '@esbuild/netbsd-x64@0.27.0': 176 + resolution: {integrity: sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==} 177 + engines: {node: '>=18'} 178 + cpu: [x64] 179 + os: [netbsd] 180 + 181 + '@esbuild/openbsd-arm64@0.27.0': 182 + resolution: {integrity: sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==} 183 + engines: {node: '>=18'} 184 + cpu: [arm64] 185 + os: [openbsd] 186 + 187 + '@esbuild/openbsd-x64@0.27.0': 188 + resolution: {integrity: sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==} 189 + engines: {node: '>=18'} 190 + cpu: [x64] 191 + os: [openbsd] 192 + 193 + '@esbuild/openharmony-arm64@0.27.0': 194 + resolution: {integrity: sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==} 195 + engines: {node: '>=18'} 196 + cpu: [arm64] 197 + os: [openharmony] 198 + 199 + '@esbuild/sunos-x64@0.27.0': 200 + resolution: {integrity: sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==} 201 + engines: {node: '>=18'} 202 + cpu: [x64] 203 + os: [sunos] 204 + 205 + '@esbuild/win32-arm64@0.27.0': 206 + resolution: {integrity: sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==} 207 + engines: {node: '>=18'} 208 + cpu: [arm64] 209 + os: [win32] 210 + 211 + '@esbuild/win32-ia32@0.27.0': 212 + resolution: {integrity: sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==} 213 + engines: {node: '>=18'} 214 + cpu: [ia32] 215 + os: [win32] 216 + 217 + '@esbuild/win32-x64@0.27.0': 218 + resolution: {integrity: sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==} 219 + engines: {node: '>=18'} 220 + cpu: [x64] 221 + os: [win32] 222 + 223 + '@img/sharp-darwin-arm64@0.33.5': 224 + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} 225 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 226 + cpu: [arm64] 227 + os: [darwin] 228 + 229 + '@img/sharp-darwin-x64@0.33.5': 230 + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} 231 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 232 + cpu: [x64] 233 + os: [darwin] 234 + 235 + '@img/sharp-libvips-darwin-arm64@1.0.4': 236 + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} 237 + cpu: [arm64] 238 + os: [darwin] 239 + 240 + '@img/sharp-libvips-darwin-x64@1.0.4': 241 + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} 242 + cpu: [x64] 243 + os: [darwin] 244 + 245 + '@img/sharp-libvips-linux-arm64@1.0.4': 246 + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} 247 + cpu: [arm64] 248 + os: [linux] 249 + 250 + '@img/sharp-libvips-linux-arm@1.0.5': 251 + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} 252 + cpu: [arm] 253 + os: [linux] 254 + 255 + '@img/sharp-libvips-linux-s390x@1.0.4': 256 + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} 257 + cpu: [s390x] 258 + os: [linux] 259 + 260 + '@img/sharp-libvips-linux-x64@1.0.4': 261 + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} 262 + cpu: [x64] 263 + os: [linux] 264 + 265 + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': 266 + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} 267 + cpu: [arm64] 268 + os: [linux] 269 + 270 + '@img/sharp-libvips-linuxmusl-x64@1.0.4': 271 + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} 272 + cpu: [x64] 273 + os: [linux] 274 + 275 + '@img/sharp-linux-arm64@0.33.5': 276 + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} 277 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 278 + cpu: [arm64] 279 + os: [linux] 280 + 281 + '@img/sharp-linux-arm@0.33.5': 282 + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} 283 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 284 + cpu: [arm] 285 + os: [linux] 286 + 287 + '@img/sharp-linux-s390x@0.33.5': 288 + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} 289 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 290 + cpu: [s390x] 291 + os: [linux] 292 + 293 + '@img/sharp-linux-x64@0.33.5': 294 + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} 295 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 296 + cpu: [x64] 297 + os: [linux] 298 + 299 + '@img/sharp-linuxmusl-arm64@0.33.5': 300 + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} 301 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 302 + cpu: [arm64] 303 + os: [linux] 304 + 305 + '@img/sharp-linuxmusl-x64@0.33.5': 306 + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} 307 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 308 + cpu: [x64] 309 + os: [linux] 310 + 311 + '@img/sharp-wasm32@0.33.5': 312 + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} 313 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 314 + cpu: [wasm32] 315 + 316 + '@img/sharp-win32-ia32@0.33.5': 317 + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} 318 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 319 + cpu: [ia32] 320 + os: [win32] 321 + 322 + '@img/sharp-win32-x64@0.33.5': 323 + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} 324 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 325 + cpu: [x64] 326 + os: [win32] 327 + 328 + '@jridgewell/resolve-uri@3.1.2': 329 + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 330 + engines: {node: '>=6.0.0'} 331 + 332 + '@jridgewell/sourcemap-codec@1.5.5': 333 + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} 334 + 335 + '@jridgewell/trace-mapping@0.3.9': 336 + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} 337 + 338 + '@poppinss/colors@4.1.6': 339 + resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} 340 + 341 + '@poppinss/dumper@0.6.5': 342 + resolution: {integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==} 343 + 344 + '@poppinss/exception@1.2.3': 345 + resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} 346 + 347 + '@sindresorhus/is@7.1.1': 348 + resolution: {integrity: sha512-rO92VvpgMc3kfiTjGT52LEtJ8Yc5kCWhZjLQ3LwlA4pSgPpQO7bVpYXParOD8Jwf+cVQECJo3yP/4I8aZtUQTQ==} 349 + engines: {node: '>=18'} 350 + 351 + '@speed-highlight/core@1.2.12': 352 + resolution: {integrity: sha512-uilwrK0Ygyri5dToHYdZSjcvpS2ZwX0w5aSt3GCEN9hrjxWCoeV4Z2DTXuxjwbntaLQIEEAlCeNQss5SoHvAEA==} 353 + 354 + acorn-walk@8.3.2: 355 + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} 356 + engines: {node: '>=0.4.0'} 357 + 358 + acorn@8.14.0: 359 + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} 360 + engines: {node: '>=0.4.0'} 361 + hasBin: true 362 + 363 + blake3-wasm@2.1.5: 364 + resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} 365 + 366 + color-convert@2.0.1: 367 + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 368 + engines: {node: '>=7.0.0'} 369 + 370 + color-name@1.1.4: 371 + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 372 + 373 + color-string@1.9.1: 374 + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} 375 + 376 + color@4.2.3: 377 + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} 378 + engines: {node: '>=12.5.0'} 379 + 380 + cookie@1.1.1: 381 + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} 382 + engines: {node: '>=18'} 383 + 384 + detect-libc@2.1.2: 385 + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} 386 + engines: {node: '>=8'} 387 + 388 + error-stack-parser-es@1.0.5: 389 + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} 390 + 391 + esbuild@0.27.0: 392 + resolution: {integrity: sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==} 393 + engines: {node: '>=18'} 394 + hasBin: true 395 + 396 + exit-hook@2.2.1: 397 + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} 398 + engines: {node: '>=6'} 399 + 400 + fsevents@2.3.3: 401 + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 402 + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 403 + os: [darwin] 404 + 405 + glob-to-regexp@0.4.1: 406 + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} 407 + 408 + is-arrayish@0.3.4: 409 + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} 410 + 411 + kleur@4.1.5: 412 + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} 413 + engines: {node: '>=6'} 414 + 415 + mime@3.0.0: 416 + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} 417 + engines: {node: '>=10.0.0'} 418 + hasBin: true 419 + 420 + miniflare@4.20251213.0: 421 + resolution: {integrity: sha512-/Or0LuRA6dQMKvL7nztPWNOVXosrJRBiO0BdJX9LUIesyeAUWIZMPFmP9XX+cdny2fIUcqYcG4DuoL5JHxj95w==} 422 + engines: {node: '>=18.0.0'} 423 + hasBin: true 424 + 425 + path-to-regexp@6.3.0: 426 + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} 427 + 428 + pathe@2.0.3: 429 + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} 430 + 431 + semver@7.7.3: 432 + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} 433 + engines: {node: '>=10'} 434 + hasBin: true 435 + 436 + sharp@0.33.5: 437 + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} 438 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 439 + 440 + simple-swizzle@0.2.4: 441 + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} 442 + 443 + stoppable@1.1.0: 444 + resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} 445 + engines: {node: '>=4', npm: '>=6'} 446 + 447 + supports-color@10.2.2: 448 + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} 449 + engines: {node: '>=18'} 450 + 451 + tslib@2.8.1: 452 + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 453 + 454 + undici@7.14.0: 455 + resolution: {integrity: sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==} 456 + engines: {node: '>=20.18.1'} 457 + 458 + unenv@2.0.0-rc.24: 459 + resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} 460 + 461 + workerd@1.20251213.0: 462 + resolution: {integrity: sha512-knLMSqmUKo7EO1wV69u8o2J+6RVDow3H5qK9f1tzk24fd4rEZXkR1cxFiYisfTRjk/Jl3/1URAkQRSDAiWE5RA==} 463 + engines: {node: '>=16'} 464 + hasBin: true 465 + 466 + wrangler@4.55.0: 467 + resolution: {integrity: sha512-50icmLX8UbNaq0FmFHbcvvOh7I6rDA/FyaMYRcNSl1iX0JwuKswezmmtYvYPxPTkbYz7FUYR8GPZLaT23uzFqw==} 468 + engines: {node: '>=20.0.0'} 469 + hasBin: true 470 + peerDependencies: 471 + '@cloudflare/workers-types': ^4.20251213.0 472 + peerDependenciesMeta: 473 + '@cloudflare/workers-types': 474 + optional: true 475 + 476 + ws@8.18.0: 477 + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} 478 + engines: {node: '>=10.0.0'} 479 + peerDependencies: 480 + bufferutil: ^4.0.1 481 + utf-8-validate: '>=5.0.2' 482 + peerDependenciesMeta: 483 + bufferutil: 484 + optional: true 485 + utf-8-validate: 486 + optional: true 487 + 488 + youch-core@0.3.3: 489 + resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} 490 + 491 + youch@4.1.0-beta.10: 492 + resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} 493 + 494 + zod@3.22.3: 495 + resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} 496 + 497 + snapshots: 498 + 499 + '@cloudflare/kv-asset-handler@0.4.1': 500 + dependencies: 501 + mime: 3.0.0 502 + 503 + '@cloudflare/unenv-preset@2.7.13(unenv@2.0.0-rc.24)(workerd@1.20251213.0)': 504 + dependencies: 505 + unenv: 2.0.0-rc.24 506 + optionalDependencies: 507 + workerd: 1.20251213.0 508 + 509 + '@cloudflare/workerd-darwin-64@1.20251213.0': 510 + optional: true 511 + 512 + '@cloudflare/workerd-darwin-arm64@1.20251213.0': 513 + optional: true 514 + 515 + '@cloudflare/workerd-linux-64@1.20251213.0': 516 + optional: true 517 + 518 + '@cloudflare/workerd-linux-arm64@1.20251213.0': 519 + optional: true 520 + 521 + '@cloudflare/workerd-windows-64@1.20251213.0': 522 + optional: true 523 + 524 + '@cspotcode/source-map-support@0.8.1': 525 + dependencies: 526 + '@jridgewell/trace-mapping': 0.3.9 527 + 528 + '@emnapi/runtime@1.7.1': 529 + dependencies: 530 + tslib: 2.8.1 531 + optional: true 532 + 533 + '@esbuild/aix-ppc64@0.27.0': 534 + optional: true 535 + 536 + '@esbuild/android-arm64@0.27.0': 537 + optional: true 538 + 539 + '@esbuild/android-arm@0.27.0': 540 + optional: true 541 + 542 + '@esbuild/android-x64@0.27.0': 543 + optional: true 544 + 545 + '@esbuild/darwin-arm64@0.27.0': 546 + optional: true 547 + 548 + '@esbuild/darwin-x64@0.27.0': 549 + optional: true 550 + 551 + '@esbuild/freebsd-arm64@0.27.0': 552 + optional: true 553 + 554 + '@esbuild/freebsd-x64@0.27.0': 555 + optional: true 556 + 557 + '@esbuild/linux-arm64@0.27.0': 558 + optional: true 559 + 560 + '@esbuild/linux-arm@0.27.0': 561 + optional: true 562 + 563 + '@esbuild/linux-ia32@0.27.0': 564 + optional: true 565 + 566 + '@esbuild/linux-loong64@0.27.0': 567 + optional: true 568 + 569 + '@esbuild/linux-mips64el@0.27.0': 570 + optional: true 571 + 572 + '@esbuild/linux-ppc64@0.27.0': 573 + optional: true 574 + 575 + '@esbuild/linux-riscv64@0.27.0': 576 + optional: true 577 + 578 + '@esbuild/linux-s390x@0.27.0': 579 + optional: true 580 + 581 + '@esbuild/linux-x64@0.27.0': 582 + optional: true 583 + 584 + '@esbuild/netbsd-arm64@0.27.0': 585 + optional: true 586 + 587 + '@esbuild/netbsd-x64@0.27.0': 588 + optional: true 589 + 590 + '@esbuild/openbsd-arm64@0.27.0': 591 + optional: true 592 + 593 + '@esbuild/openbsd-x64@0.27.0': 594 + optional: true 595 + 596 + '@esbuild/openharmony-arm64@0.27.0': 597 + optional: true 598 + 599 + '@esbuild/sunos-x64@0.27.0': 600 + optional: true 601 + 602 + '@esbuild/win32-arm64@0.27.0': 603 + optional: true 604 + 605 + '@esbuild/win32-ia32@0.27.0': 606 + optional: true 607 + 608 + '@esbuild/win32-x64@0.27.0': 609 + optional: true 610 + 611 + '@img/sharp-darwin-arm64@0.33.5': 612 + optionalDependencies: 613 + '@img/sharp-libvips-darwin-arm64': 1.0.4 614 + optional: true 615 + 616 + '@img/sharp-darwin-x64@0.33.5': 617 + optionalDependencies: 618 + '@img/sharp-libvips-darwin-x64': 1.0.4 619 + optional: true 620 + 621 + '@img/sharp-libvips-darwin-arm64@1.0.4': 622 + optional: true 623 + 624 + '@img/sharp-libvips-darwin-x64@1.0.4': 625 + optional: true 626 + 627 + '@img/sharp-libvips-linux-arm64@1.0.4': 628 + optional: true 629 + 630 + '@img/sharp-libvips-linux-arm@1.0.5': 631 + optional: true 632 + 633 + '@img/sharp-libvips-linux-s390x@1.0.4': 634 + optional: true 635 + 636 + '@img/sharp-libvips-linux-x64@1.0.4': 637 + optional: true 638 + 639 + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': 640 + optional: true 641 + 642 + '@img/sharp-libvips-linuxmusl-x64@1.0.4': 643 + optional: true 644 + 645 + '@img/sharp-linux-arm64@0.33.5': 646 + optionalDependencies: 647 + '@img/sharp-libvips-linux-arm64': 1.0.4 648 + optional: true 649 + 650 + '@img/sharp-linux-arm@0.33.5': 651 + optionalDependencies: 652 + '@img/sharp-libvips-linux-arm': 1.0.5 653 + optional: true 654 + 655 + '@img/sharp-linux-s390x@0.33.5': 656 + optionalDependencies: 657 + '@img/sharp-libvips-linux-s390x': 1.0.4 658 + optional: true 659 + 660 + '@img/sharp-linux-x64@0.33.5': 661 + optionalDependencies: 662 + '@img/sharp-libvips-linux-x64': 1.0.4 663 + optional: true 664 + 665 + '@img/sharp-linuxmusl-arm64@0.33.5': 666 + optionalDependencies: 667 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 668 + optional: true 669 + 670 + '@img/sharp-linuxmusl-x64@0.33.5': 671 + optionalDependencies: 672 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 673 + optional: true 674 + 675 + '@img/sharp-wasm32@0.33.5': 676 + dependencies: 677 + '@emnapi/runtime': 1.7.1 678 + optional: true 679 + 680 + '@img/sharp-win32-ia32@0.33.5': 681 + optional: true 682 + 683 + '@img/sharp-win32-x64@0.33.5': 684 + optional: true 685 + 686 + '@jridgewell/resolve-uri@3.1.2': {} 687 + 688 + '@jridgewell/sourcemap-codec@1.5.5': {} 689 + 690 + '@jridgewell/trace-mapping@0.3.9': 691 + dependencies: 692 + '@jridgewell/resolve-uri': 3.1.2 693 + '@jridgewell/sourcemap-codec': 1.5.5 694 + 695 + '@poppinss/colors@4.1.6': 696 + dependencies: 697 + kleur: 4.1.5 698 + 699 + '@poppinss/dumper@0.6.5': 700 + dependencies: 701 + '@poppinss/colors': 4.1.6 702 + '@sindresorhus/is': 7.1.1 703 + supports-color: 10.2.2 704 + 705 + '@poppinss/exception@1.2.3': {} 706 + 707 + '@sindresorhus/is@7.1.1': {} 708 + 709 + '@speed-highlight/core@1.2.12': {} 710 + 711 + acorn-walk@8.3.2: {} 712 + 713 + acorn@8.14.0: {} 714 + 715 + blake3-wasm@2.1.5: {} 716 + 717 + color-convert@2.0.1: 718 + dependencies: 719 + color-name: 1.1.4 720 + 721 + color-name@1.1.4: {} 722 + 723 + color-string@1.9.1: 724 + dependencies: 725 + color-name: 1.1.4 726 + simple-swizzle: 0.2.4 727 + 728 + color@4.2.3: 729 + dependencies: 730 + color-convert: 2.0.1 731 + color-string: 1.9.1 732 + 733 + cookie@1.1.1: {} 734 + 735 + detect-libc@2.1.2: {} 736 + 737 + error-stack-parser-es@1.0.5: {} 738 + 739 + esbuild@0.27.0: 740 + optionalDependencies: 741 + '@esbuild/aix-ppc64': 0.27.0 742 + '@esbuild/android-arm': 0.27.0 743 + '@esbuild/android-arm64': 0.27.0 744 + '@esbuild/android-x64': 0.27.0 745 + '@esbuild/darwin-arm64': 0.27.0 746 + '@esbuild/darwin-x64': 0.27.0 747 + '@esbuild/freebsd-arm64': 0.27.0 748 + '@esbuild/freebsd-x64': 0.27.0 749 + '@esbuild/linux-arm': 0.27.0 750 + '@esbuild/linux-arm64': 0.27.0 751 + '@esbuild/linux-ia32': 0.27.0 752 + '@esbuild/linux-loong64': 0.27.0 753 + '@esbuild/linux-mips64el': 0.27.0 754 + '@esbuild/linux-ppc64': 0.27.0 755 + '@esbuild/linux-riscv64': 0.27.0 756 + '@esbuild/linux-s390x': 0.27.0 757 + '@esbuild/linux-x64': 0.27.0 758 + '@esbuild/netbsd-arm64': 0.27.0 759 + '@esbuild/netbsd-x64': 0.27.0 760 + '@esbuild/openbsd-arm64': 0.27.0 761 + '@esbuild/openbsd-x64': 0.27.0 762 + '@esbuild/openharmony-arm64': 0.27.0 763 + '@esbuild/sunos-x64': 0.27.0 764 + '@esbuild/win32-arm64': 0.27.0 765 + '@esbuild/win32-ia32': 0.27.0 766 + '@esbuild/win32-x64': 0.27.0 767 + 768 + exit-hook@2.2.1: {} 769 + 770 + fsevents@2.3.3: 771 + optional: true 772 + 773 + glob-to-regexp@0.4.1: {} 774 + 775 + is-arrayish@0.3.4: {} 776 + 777 + kleur@4.1.5: {} 778 + 779 + mime@3.0.0: {} 780 + 781 + miniflare@4.20251213.0: 782 + dependencies: 783 + '@cspotcode/source-map-support': 0.8.1 784 + acorn: 8.14.0 785 + acorn-walk: 8.3.2 786 + exit-hook: 2.2.1 787 + glob-to-regexp: 0.4.1 788 + sharp: 0.33.5 789 + stoppable: 1.1.0 790 + undici: 7.14.0 791 + workerd: 1.20251213.0 792 + ws: 8.18.0 793 + youch: 4.1.0-beta.10 794 + zod: 3.22.3 795 + transitivePeerDependencies: 796 + - bufferutil 797 + - utf-8-validate 798 + 799 + path-to-regexp@6.3.0: {} 800 + 801 + pathe@2.0.3: {} 802 + 803 + semver@7.7.3: {} 804 + 805 + sharp@0.33.5: 806 + dependencies: 807 + color: 4.2.3 808 + detect-libc: 2.1.2 809 + semver: 7.7.3 810 + optionalDependencies: 811 + '@img/sharp-darwin-arm64': 0.33.5 812 + '@img/sharp-darwin-x64': 0.33.5 813 + '@img/sharp-libvips-darwin-arm64': 1.0.4 814 + '@img/sharp-libvips-darwin-x64': 1.0.4 815 + '@img/sharp-libvips-linux-arm': 1.0.5 816 + '@img/sharp-libvips-linux-arm64': 1.0.4 817 + '@img/sharp-libvips-linux-s390x': 1.0.4 818 + '@img/sharp-libvips-linux-x64': 1.0.4 819 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 820 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 821 + '@img/sharp-linux-arm': 0.33.5 822 + '@img/sharp-linux-arm64': 0.33.5 823 + '@img/sharp-linux-s390x': 0.33.5 824 + '@img/sharp-linux-x64': 0.33.5 825 + '@img/sharp-linuxmusl-arm64': 0.33.5 826 + '@img/sharp-linuxmusl-x64': 0.33.5 827 + '@img/sharp-wasm32': 0.33.5 828 + '@img/sharp-win32-ia32': 0.33.5 829 + '@img/sharp-win32-x64': 0.33.5 830 + 831 + simple-swizzle@0.2.4: 832 + dependencies: 833 + is-arrayish: 0.3.4 834 + 835 + stoppable@1.1.0: {} 836 + 837 + supports-color@10.2.2: {} 838 + 839 + tslib@2.8.1: 840 + optional: true 841 + 842 + undici@7.14.0: {} 843 + 844 + unenv@2.0.0-rc.24: 845 + dependencies: 846 + pathe: 2.0.3 847 + 848 + workerd@1.20251213.0: 849 + optionalDependencies: 850 + '@cloudflare/workerd-darwin-64': 1.20251213.0 851 + '@cloudflare/workerd-darwin-arm64': 1.20251213.0 852 + '@cloudflare/workerd-linux-64': 1.20251213.0 853 + '@cloudflare/workerd-linux-arm64': 1.20251213.0 854 + '@cloudflare/workerd-windows-64': 1.20251213.0 855 + 856 + wrangler@4.55.0: 857 + dependencies: 858 + '@cloudflare/kv-asset-handler': 0.4.1 859 + '@cloudflare/unenv-preset': 2.7.13(unenv@2.0.0-rc.24)(workerd@1.20251213.0) 860 + blake3-wasm: 2.1.5 861 + esbuild: 0.27.0 862 + miniflare: 4.20251213.0 863 + path-to-regexp: 6.3.0 864 + unenv: 2.0.0-rc.24 865 + workerd: 1.20251213.0 866 + optionalDependencies: 867 + fsevents: 2.3.3 868 + transitivePeerDependencies: 869 + - bufferutil 870 + - utf-8-validate 871 + 872 + ws@8.18.0: {} 873 + 874 + youch-core@0.3.3: 875 + dependencies: 876 + '@poppinss/exception': 1.2.3 877 + error-stack-parser-es: 1.0.5 878 + 879 + youch@4.1.0-beta.10: 880 + dependencies: 881 + '@poppinss/colors': 4.1.6 882 + '@poppinss/dumper': 0.6.5 883 + '@speed-highlight/core': 1.2.12 884 + cookie: 1.1.1 885 + youch-core: 0.3.3 886 + 887 + zod@3.22.3: {}
+1 -9
public/favicon.svg
··· 1 - <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128"> 2 - <path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" /> 3 - <style> 4 - path { fill: #000; } 5 - @media (prefers-color-scheme: dark) { 6 - path { fill: #FFF; } 7 - } 8 - </style> 9 - </svg> 1 + <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 16 16"><text x="0" y="14">โ™จ๏ธ</text></svg>
+209
public/index.html
··· 1 + <!DOCTYPE html> 2 + <html lang="en"> 3 + <head> 4 + <meta charset="UTF-8"> 5 + <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 + <title>Dane's Website</title> 7 + <meta name="description" content="Hey, I'm Dane. A frontend/fullstack developer from Toronto that enjoys building cool and accessible websites using the latest web technologies."> 8 + <link rel="icon" type="image/svg+xml" href="/public/favicon.svg"> 9 + <meta property="og:type" content="website"> 10 + <meta property="og:title" content="Dane's Website"> 11 + <meta property="og:description" content="Hey, I'm Dane. A frontend/fullstack developer from Toronto that enjoys building cool and accessible websites using the latest web technologies."> 12 + <link rel="canonical" href="https://dane.computer/"> 13 + <meta property="og:url" content="https://dane.computer/"> 14 + <style> 15 + @layer reset { 16 + *, 17 + *::before, 18 + *::after { 19 + box-sizing: border-box; 20 + } 21 + 22 + * { 23 + margin: 0; 24 + padding: 0; 25 + } 26 + 27 + html { 28 + -webkit-text-size-adjust: none; 29 + -webkit-font-smoothing: antialiased; 30 + text-rendering: optimizespeed; 31 + text-size-adjust: none; 32 + color-scheme: dark light; 33 + tab-size: 2; 34 + scrollbar-gutter: stable; 35 + interpolate-size: allow-keywords; 36 + line-height: 1.5; 37 + } 38 + 39 + body { 40 + margin: 0; 41 + font-family: Menlo, Consolas, Monaco, Adwaita Mono, Liberation Mono, Lucida Console, monospace; 42 + font-synthesis: none; 43 + } 44 + 45 + ul[role=list], ol[role=list] { 46 + list-style: none; 47 + padding: 0; 48 + } 49 + 50 + ::marker { 51 + line-height: 0; 52 + } 53 + 54 + :focus-visible { 55 + outline-offset: 2px; 56 + } 57 + 58 + @media (prefers-reduced-motion: no-preference) { 59 + html:focus-within { 60 + scroll-behavior: smooth; 61 + } 62 + } 63 + 64 + a { 65 + color: inherit; 66 + text-underline-offset: 0.2ex; 67 + } 68 + 69 + h1, h2, 70 + h3, h4 { 71 + text-wrap: balance; 72 + } 73 + 74 + a[href] { 75 + -webkit-tap-highlight-color: transparent; 76 + } 77 + 78 + p, h1, h2, h3, h4, h5, h6 { 79 + overflow-wrap: break-word; 80 + } 81 + 82 + p { 83 + text-wrap: pretty; 84 + } 85 + 86 + } 87 + 88 + .container { 89 + max-width: 65ch; 90 + margin: 0 auto; 91 + padding: 5.5rem 0; 92 + } 93 + 94 + .intro { 95 + margin-bottom: 2rem; 96 + } 97 + 98 + .name { 99 + font-size: 2.5rem; 100 + font-weight: bold; 101 + text-transform: capitalize; 102 + } 103 + 104 + .title { 105 + font-weight: bold; 106 + margin-bottom: 1.5rem; 107 + } 108 + 109 + .bio { 110 + margin-bottom: 2rem; 111 + font-weight: 500; 112 + } 113 + 114 + .bio p:not(:last-of-type) { 115 + margin-bottom: 1rem; 116 + } 117 + 118 + .links { 119 + margin-bottom: 2rem; 120 + } 121 + 122 + .links p:first-of-type { 123 + font-weight: bold; 124 + } 125 + 126 + .job { 127 + display: flex; 128 + justify-content: space-between; 129 + } 130 + 131 + .work-experience ul { 132 + display: flex; 133 + flex-direction: column; 134 + row-gap: 1rem; 135 + } 136 + 137 + @media (width <= 640px) { 138 + .container { 139 + padding: 3.5rem 1rem; 140 + } 141 + } 142 + 143 + @media (width <= 600px) { 144 + .container { 145 + text-align: center; 146 + } 147 + 148 + .work-experience .job { 149 + display: flex; 150 + flex-direction: column; 151 + } 152 + } 153 + </style> 154 + </head> 155 + <body> 156 + <main class="container"> 157 + <section class="intro"> 158 + <h1 class="name">dane miller</h1> 159 + <p class="title">senior software developer</p> 160 + <aside class="bio"> 161 + <p>Currently working as a frontend developer at the Bank of Montreal in Toronto.</p> 162 + <p>In my spare time I enjoy (re)watching tv shows, listening to music and playing video games.</p> 163 + <p>I guess I code from time to time as well. At the moment i&apos;m into all things <a href="https://atproto.com" target="_blank" rel="noopener noreferrer">AT Protocol</a>.</p> 164 + <p>Writing code in Typescript, Go, Rust and Gleam.</p> 165 + </aside> 166 + </section> 167 + <section class="links"> 168 + <h2>where to find me on the world wide web</h2> 169 + <ul role="list"> 170 + <li> 171 + <a href="https://bsky.app/profile/did:plc:qttsv4e7pu2jl3ilanfgc3zn" target="_blank" aria-label="Go to Dane's bluesky profile, opens in a new tab" rel="noopener noreferrer">Bluesky</a> 172 + </li> 173 + <li> 174 + <a href="https://tangled.org/did:plc:qttsv4e7pu2jl3ilanfgc3zn" target="_blank" aria-label="Go to Dane's Tangled profile, opens in a new tab" rel="noopener noreferrer">Tangled</a> 175 + </li> 176 + <li> 177 + <a href="mailto:me@dane.computer">E-mail</a> 178 + </li> 179 + </ul> 180 + </section> 181 + <section class="work-experience"> 182 + <h2>work experience</h2> 183 + <ul role="list"> 184 + <li class="job"> 185 + <div> 186 + <p class="company">Bank of Montreal</p> 187 + <small class="title">Senior Software Developer</small> 188 + </div> 189 + <p>2021 to present</p> 190 + </li> 191 + <li class="job"> 192 + <div> 193 + <p class="company">Black Professionals In Tech Network</p> 194 + <small class="title">Intermediate Software Developer</small> 195 + </div> 196 + <p>2021 to 2021</p> 197 + </li> 198 + <li class="job"> 199 + <div> 200 + <p class="company">Wise Publishing</p> 201 + <small class="title">Frontend Developer Intern</small> 202 + </div> 203 + <p>2020 to 2020</p> 204 + </li> 205 + </ul> 206 + </section> 207 + </main> 208 + </body> 209 + </html>
public/resume.pdf

This is a binary file and will not be displayed.

-2
public/robots.txt
··· 1 - User-Agent: * 2 - Allow: /
-25
src/components/BlogPost.astro
··· 1 - --- 2 - interface Props { 3 - title: string; 4 - published_at: Date; 5 - slug: string; 6 - } 7 - 8 - const { title, published_at, slug } = Astro.props; 9 - import Link from "../components/Link.astro"; 10 - --- 11 - 12 - <li> 13 - <article> 14 - <h2 15 - class="mb-1 font-bold text-blue-700 hover:text-blue-500 hover:underline" 16 - > 17 - <Link href={`/blogs/${slug}`}>{title}</Link> 18 - </h2> 19 - <footer class="text-sm text-gray-500"> 20 - <time datetime={published_at.toISOString()}> 21 - {new Intl.DateTimeFormat("en-us").format(new Date(published_at))} 22 - </time> 23 - </footer> 24 - </article> 25 - </li>
-13
src/components/Link.astro
··· 1 - --- 2 - interface Props { 3 - extraClasses?: string; 4 - [x: string]: unknown; 5 - } 6 - --- 7 - 8 - <a 9 - {...Astro.props} 10 - class={`text-blue-700 hover:(underline text-blue-600) focus-visible:(outline outline-[4px] outline-black underline [box-shadow:0_0_0_6px_white]) ${Astro.props.extraClasses}`} 11 - > 12 - <slot /> 13 - </a>
-28
src/components/Meta.astro
··· 1 - --- 2 - interface Props { 3 - title: string; 4 - description: string; 5 - } 6 - 7 - const { title, description } = Astro.props; 8 - const canonicalURL = new URL(Astro.url.pathname, Astro.site); 9 - --- 10 - 11 - <head> 12 - <meta charset="UTF-8" /> 13 - <meta name="description" content={description} /> 14 - <meta name="viewport" content="width=device-width, initial-scale=1" /> 15 - <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> 16 - <meta name="generator" content={Astro.generator} /> 17 - <meta property="og:type" content="website" /> 18 - <meta name="twitter:card" content="summary_large_image" /> 19 - <meta name="twitter:creator" content="@hybridearth" /> 20 - <meta property="og:title" content={title} /> 21 - <meta property="og:description" content={description} /> 22 - <meta name="twitter:title" content={title} /> 23 - <meta name="twitter:description" content={description} /> 24 - <link rel="sitemap" href="/sitemap-index.xml" /> 25 - <link rel="canonical" href={canonicalURL} /> 26 - <meta property="og:url" content={canonicalURL} /> 27 - <title>{title}</title> 28 - </head>
-23
src/components/Navbar.astro
··· 1 - --- 2 - const paths = [ 3 - { name: "home", path: "/" }, 4 - { name: "blogs", path: "/blogs" }, 5 - ]; 6 - import Link from "../components/Link.astro"; 7 - --- 8 - 9 - <header class="max-w-5xl mx-auto pt-2 md:pt-10 mb-2 px-3 md:px-0"> 10 - <nav> 11 - <ul class="flex gap-2"> 12 - { 13 - paths.map(({ name, path }) => ( 14 - <li> 15 - <Link href={path} extraClasses="font-bold"> 16 - {name} 17 - </Link>{" "} 18 - </li> 19 - )) 20 - } 21 - </ul> 22 - </nav> 23 - </header>
-61
src/content/blog/docker-for-frontend-developers.md
··· 1 - --- 2 - title: Docker for Frontend Developers 3 - description: A short walkthrough on how to create an API 4 - year: 2021 5 - published_at: 2021-03-17 6 - --- 7 - 8 - I'll be honest, it took me a while to understand what docker was and why/how one would even use it in a typical workflow. I've read the documentation months ago to understand the basics but never knew how I could apply it into my own workflow or projects until recently. That's when I started to use it wherever I could. 9 - 10 - ## A tl;dr of what docker is 11 - 12 - Docker is a platform for developing and deploying applications wherever docker is installed. Before docker there were VMs (such as virtualbox) where you could take an image, usually an operating system, and stick it on some virtual hardware that you would then configure to your needs and then use that image in production to run whatever service you configured it for. Docker is similar to that but much lighter and much easier to get up and running. 13 - 14 - With docker you're able to pull pre-configured images from the docker "hub" and get up and running in a matter of minutes. Docker also allows you to create an environment that is consistent no matter where the application is running which I think is a huge plus because I've run into situations where I switch computers and for whatever reason the thing I'm working on just doesn't work! 15 - 16 - ## Getting up and running, fast 17 - 18 - Typically when I start a new project, be it a website or a discord bot, I'll usually end up needing some sort of database. Usually I would download the software needed to run the database on my computer and maybe a client to view the data in the database. Now, I'd just use docker and pull whatever image I needed for the database I'm using. 19 - 20 - ``` 21 - docker pull postgres 22 - docker run --name -d -p 5432:5432 -e POSTGRES_PASSWORD=password postgres 23 - ``` 24 - 25 - That's it! That's all I would need to get a postgres database running. 26 - 27 - I'll explain what some of these command line options mean. 28 - 29 - ``` 30 - docker pull postgres 31 - ``` 32 - 33 - With this command I'm saying, "On docker hub, find the postgres image and download it". 34 - 35 - There are a ton of images on docker hub for services you may neeed such as redis, apache, mongoDB, etc. 36 - 37 - ``` 38 - docker run --name postgres -d -p 5432:5432 -e POSTGRES_PASSWORD=password postgres 39 - ``` 40 - 41 - This command is a little more involved so I'll break it down. 42 - 43 - `` docker run` --name postgres `` is how you would spin up a new container (a new, tiny instance of postgres) and the name of the container would be postgres. By default if no name is given then docker will generate a random one. It's good practice to give your containers a name because they become easier to identify and easy to remember should you need to stop or start the container. 44 - 45 - `-d` just means run the container in daemon mode, instead of in the foreground. 46 - 47 - `-p 5432:5432` this is where you would set the port for the container so that the docker host can communicate with the container. Postgres runs on the port 5432 so we would need to say port 5432 on the host maps to port 5432 on the container. 48 - 49 - `-e POSTGRES_PASSWORD=password` to set environment variables at runtime you would need to provide the -e flag. An alternative to this would be to have a file where your secrets live and use `--env-file .env` instead. 50 - 51 - `postgres` last but not least the image you want to run. You can see a list of images you have dowloaded on your machine with `docker images`. 52 - 53 - ## Conclusion 54 - 55 - This post is mostly just a tl;dr of how to get started with docker as well as showing how easy it is. There are other things I wanted to cover such as building your own image, pushing an image to docker hub as well as deploying an image but I felt that would be a lot for a blog post so I'll leave some resources that helped me a bunch when I was learning about docker. 56 - 57 - [Docker and Kubernetes for beginners (FreeCodeCamp)](https://www.youtube.com/watch?v=Wf2eSG3owoA&t=1999s) 58 - 59 - [Docker documentation](https://docs.docker.com/reference/) 60 - 61 - [Deploying docker images to Heroku](https://devcenter.heroku.com/categories/deploying-with-docker)
-101
src/content/blog/give-angular-a-second-chance.md
··· 1 - --- 2 - title: Give Angular a second chance 3 - description: Giving Angular an honest try with Angular 17 4 - year: 2023 5 - published_at: 2023-12-15 6 - --- 7 - 8 - You've seen the memes, you've seen the angry github comments, you've seen the negative press. I'll be honest, I fell victim to the propaganda online. Was some of it warranted? Probably, but some of it was a bit overexaggerated in my opinion. Seriously, Angular is a really good framework and I think the release of Angular 17 will bring it back into the light and a serious option for building websites. I've only been through the documentation briefly and did the tutorial but there are some things I _really_ like. 9 - 10 - ## The CLI 11 - 12 - One thing I've always admired and wished other frameworks/libraries would have adopted is their version of the Angular CLI. Not only can you use it to create new components with all of the boiler plate code all generated for you, you can also do things like open the docs or quickly add angular modules with `ng add`. I found with the short amount of time I've spent with it, it allows me to move a bit quicker and think less about creating my own scripts or thinking about the most optimal file structure. There are a lot of commands that are just great defaults to have that aren't unique from project to project such as testing. I tell people repeatedly that I wish there was something similar with React but maybe it wouldn't work out the same way as I imagine. 13 - 14 - ## Pipes 15 - 16 - Now if you're not really a Linux user you've probably never heard of the term `pipe` before and when I first saw it mentioned in the Angular docs I had no idea what to expect but it works exactly the same as it does in the terminal. Let's say I have a sentence and I want to count the amount of words in that sentence. In my terminal I could do `echo hello this is a sentence` _and then_ pipe that ( | ) to the `wc` program that's available ("wc" without any options outputs the amount of lines, words and characters from whatever is passed in). So the full command in my terminal would look like this. 17 - 18 - ```bash 19 - echo hello this is a sentence | wc 20 - // 1 5 25 21 - ``` 22 - 23 - It's the same concept in Angular, which is really cool in my opinion. For example by default Angular has an `uppercase` pipe that transforms some text to uppercase. 24 - 25 - ```ts 26 - import { Component } from "@angular/core"; 27 - import { UppercasePipe } from "@angular/common"; 28 - 29 - @Component({ 30 - standalone: true, 31 - templateUrl: ` 32 - <p>Hello my name is {{ name | uppercase }}</p> 33 - `, 34 - imports: [UppercasePipe], 35 - }) 36 - export class AppComponent { 37 - name = "Dane"; 38 - } 39 - ``` 40 - 41 - You can also make your own pipes to do whatever you need them to, like this capitalize pipe! 42 - 43 - ```ts 44 - // captialize.ts 45 - import { Pipe, PipeTransform } from "@angular/core"; 46 - 47 - @Pipe({ 48 - name: "capitalize", 49 - standalone: true, 50 - }) 51 - export class CapitalizePipe implements PipeTransform { 52 - transform(value: string): string { 53 - if (typeof value !== "string" || value.length <= 1) return value; 54 - let uppercasedFirstLetter = value.slice(0, 1).toUpperCase(); 55 - let restOfWord = value.substring(1, value.length); 56 - return `${uppercasedFirstLetter}${restOfWord}`; 57 - } 58 - } 59 - ``` 60 - 61 - ```ts 62 - // main.ts 63 - import { Component } from "@angular/core"; 64 - import { CapitalizePipe } from "./capitalize"; 65 - 66 - @Component({ 67 - selector: "app-root", 68 - standalone: true, 69 - template: ` Hello world, {{ name | capitalize }} `, 70 - imports: [CapitalizePipe], 71 - }) 72 - export class AppComponent { 73 - name = "dane"; 74 - } 75 - ``` 76 - 77 - Simple examples but you can imagine how useful this is and I honestly prefer writing reusable functions like this. 78 - 79 - ## Deferrable views 80 - 81 - This is something new in Angular and something most frameworks/libraries have included but the way it's been done in Angular is super cool and really simple to grasp. [In the documentation](https://angular.dev/guide/defer) they have a simple example showing how to defer something like a list of comments so that the page loads quicker. Sure, when there are maybe 1 or 2 comments it won't impact page performance much but when that list grows a user will have to wait for the main content _and_ the comments to be loaded. Angular 17 introduces deferrable views to help with this sort of thing. Let's say I want to defer the loading of a list of recipies, I would do something like this: 82 - 83 - ```ts 84 - @defer { 85 - <recipie-list /> 86 - } 87 - ``` 88 - 89 - That's literally it! In addition to the @defer syntax you can also specify a placeholder. Placeholders are good because it gives the user more information about what's happening and makes it so content doesn't just show up on the page. So combined with the last snippet it could look something like this: 90 - 91 - ```ts 92 - @defer { 93 - <recipe-list /> 94 - } @placeholder (minimum 500ms) { 95 - <p>Recipe list is loading...</p> 96 - } 97 - ``` 98 - 99 - The `minimum` parameter let's us say how long the placeholder should show before showing the resolved content. This is done so there isn't a weird flicker after the content is ready to be shown. This only scratches the surface of what Angular gives you to help improve the performance of your website, there are a few examples on how you get fine tuned performance even more with triggers which is definitely worth a read. 100 - 101 - I honestly believe Angular should be given another chance with this new release, there are a ton of great features you get out of the box that help with making a performant website. I plan on using Angular to make a side project so I can really explore all of the features in depth and I hope more people do the same!
-131
src/content/blog/running-a-containerized-application-in-the-cloud.md
··· 1 - --- 2 - title: Running a containerized application in the cloud using AWS App Runner 3 - description: Exploring the new AWS App Runner service 4 - published_at: 2021-05-19 5 - year: 2021 6 - --- 7 - 8 - I've been pretty deep in the cloud space for a few weeks now, researching different topics related to system design and playing around with different AWS services. So far I've been playing around with containers and figuring out ways I could deploy a simple containerized application to the cloud without much fuss. I've found AWS Elastic Container Service and AWS Elastic Kubernetes Service (more on kubernetes in another blog post, I've been having fun learning about it) but those are more for managing clusters of containers than just being able to deploy something simple and small. I've also looked at AWS Elastic Beanstalk and while it is possible to deploy docker containers through that service I haven't had much luck doing it through the UI or the Elastic Beanstalk CLI. 9 - 10 - ## Enter AWS App Runner 11 - 12 - This was actually just released a few days ago and is pretty much exactly what I needed for the application I wanted to run. It is pretty similar to Elastic Beanstalk in some ways but with Elastic Beanstalk there are still some things you need to configure yourself like SSL for example whereas with App Runner that's already ready and configured for you. You can simply upload a docker image to your AWS Container registry or link your github repository and any time the image is updated or new code is pushed it'll re-run the build process and deploy your application (automatic deployments are opt-in and a flat $1/month). There are some costs associated with provisioned / active instances + the amount of RAM and CPU you choose and you're billed by the hour but the cost is pretty low and depends on how much traffic your application is getting. 13 - 14 - ## Deploying an application to App Runner 15 - 16 - In these next few screenshots I'll show going from a simple node application to a deployed version in App Runner. I will be using docker to deploy so if you don't already have it installed and would like to follow along I'd suggest doing that now. 17 - 18 - ### Bootstrapping our application 19 - 20 - So, you've decided to feed your hotwheels addiction by making an application to trade hotwheels with other enthusiasts. Great idea! First we'll need to install some dependencies. 21 - 22 - ```bash 23 - mkdir hotwheels-trading-app && cd hotwheels-trading-app 24 - npm init -y 25 - npm install express 26 - ``` 27 - 28 - With our dependencies installed we can now start adding some code! 29 - 30 - ```javascript 31 - // index.js 32 - const express = require("express"); 33 - const app = express(); 34 - 35 - app.get("/", (_, response) => { 36 - response.status(200).json({ 37 - data: { 38 - message: "Welcome to my hotwheels app!", 39 - }, 40 - }); 41 - }); 42 - 43 - app.listen(4000, () => console.log("App running!")); 44 - ``` 45 - 46 - Beautiful, ain't it? You can test it out by running `node index.js` and navigating to `http://localhost:4000`. 47 - 48 - Next we'll containerize the application. Create a Dockerfile and add this to it. 49 - 50 - ```bash 51 - FROM node:alpine 52 - 53 - WORKDIR /app 54 - 55 - COPY package*.json /app/ 56 - 57 - RUN npm install 58 - 59 - COPY . /app/ 60 - 61 - CMD ["node", "index.js"] 62 - ``` 63 - 64 - Then build the image. 65 - 66 - ```bash 67 - docker build -t hotwheels-app:latest . 68 - ``` 69 - 70 - Then test it locally to make sure everything is still working. 71 - 72 - ```bash 73 - docker run --name hotwheels-app -p 4000:4000 -d hotwheels-app:latest 74 - ``` 75 - 76 - You should be able to navigate to the same URL that we used before and see the same message. Alright cool, we've finished setting up our nifty application and now we want to get it to the public. 77 - 78 - ### Uploading the image to AWS Elastic Container Registry 79 - 80 - In the AWS console navigate over to the Elastic Container Registry 81 - 82 - ![AWS Console search results](https://www.datocms-assets.com/44755/1621569095-console.png) 83 - 84 - Then click create repository 85 - 86 - ![Image of the AWS ECR main screen](https://www.datocms-assets.com/44755/1621569099-ecr1.png) 87 - 88 - You can just leave all the settings to default (I chose to turn scanning on just so it checks for vulnerabilites but for this you don't need to turn it on) 89 - 90 - ![Image of AWS ECR create repository page](https://www.datocms-assets.com/44755/1621569102-ecr2.png) 91 - 92 - Once the repository is created you should see it in the list on the main screen, click the repository name then in the top right click "View push commands". Copy and execute the commands one by one to push your image to the repository. After you're done you should see your image in the repository (click the refresh button if you don't). 93 - 94 - ![Image of docker container in the ECR repository](https://www.datocms-assets.com/44755/1621569528-ecr4.png) 95 - 96 - That's all that needs to be done for the docker image side of things. The last step would be to get everything set up in App Runner. 97 - 98 - ### Deploying our cool new app ๐Ÿš€ 99 - 100 - In the AWS console head over to AWS App runner. 101 - 102 - ![Image of AWS console](https://www.datocms-assets.com/44755/1621571455-runner1.png) 103 - 104 - Some more things App Runner includes out of the box are 105 - load balancing, auto-scaling and monitoring via cloud watch and since you're already in the AWS ecosystem you can make use of the many other services they offer. 106 - 107 - Click "Create an App Runner service" to get started. In the first step you're prompted with a few different options. We'll be using the docker image we uploaded to ECR so keep the repository type "Container registry" selected. The provider you can leave default also since we uploaded our image to a private repository but if you wanted to you could use public also so as long your image is in a public respository. 108 - 109 - ![Image of App Runner create service page](https://www.datocms-assets.com/44755/1621571459-runner2.png) 110 - 111 - For the docker image click browse and select the hotwheels-app from the dropdown and then click continue. 112 - 113 - ![Image of selecting docker image for App Runner](https://www.datocms-assets.com/44755/1621571463-runner3.png) 114 - 115 - For deployment settings you have the option between manual and automatic. As a reminder, **automatic deployments do cost money** ($1/month) so keep that in mind if you do select it. For this example I will but will also delete the application right after I am done as I don't think it incurs a cost. 116 - 117 - For step two all you need to do is give the application a name and fill out the port number. In this step you're also able to customize the auto-scaling settings, you can set minimum and maximum instances as well as the amount of concurrent requests your application should reach before adding more instances. 118 - 119 - ![Image of step two of App Runner settings](https://www.datocms-assets.com/44755/1621571466-runner4.png) 120 - 121 - Step three is just reviewing your configurations but you can also edit anything here if you wanted to. After you're done reviewing just click "create & deploy" and wait for your application to be created. 122 - 123 - ### Issues 124 - 125 - As of May 20th, 2021, creating a service role is a bit bugged and you'll get an error the first time you use App Runner when you get to the 3rd step. What I did was select "create service role" then fill out the information until the end then click create & deploy. You may or may not get an error depending on if it's fixed or not but if it isn't all you have to do is go back to step one and select "use existing role" and select the app runner role from the list then try deploying again. 126 - 127 - If everything goes well you should see a message saying the deployment was successful and there is a link provided under "default domain" to view your newly deployed application! Remember to tear down the environment after playing around with it also! 128 - 129 - ## Conclusion 130 - 131 - I think App Runner is pretty neat and I may use it in the future to host an application. Another free alternative would be Heroku but if you're looking for something equivalent in the AWS space this is it. I'd suggest to keep poking around and taking a look at the [pricing](https://aws.amazon.com/apprunner/pricing/) breakdown and find which configuration fits for you.
-57
src/content/blog/what-im-going-to-be-learning-in-2022.md
··· 1 - --- 2 - title: What I'm going to be learning in the year 2022 3 - description: Tech / frameworks / languages I'm focusing on in the new year 4 - published_at: 2021-12-15 5 - year: 2021 6 - --- 7 - 8 - This year has been a pretty wild ride for me, from not having a job for almost a year then having multiple offers and then now ending up at a place I feel comfortable in. All in all I think I've made good decisions 9 - and I'm looking forward to more growth in the new year! ๐Ÿš€ 10 - 11 - In terms of learning new things I don't feel like I have done that a lot this year. Things in tech move pretty fast and it gets exhausting trying to keep up with everything that is happening 12 - but for the new year I want to change that. I have an itch to build things and try out all the stuff I've read about in the past year, and maybe actually follow through with finishing my side projects. Okay 13 - who are we kidding that won't change. 14 - 15 - For real though, I want to take my knowledge to the next level. I struggle with figuring out where I stand in terms of experience, I'm not quite a junior but also I feel 16 - my skills aren't there yet to consider myself a senior developer. I know labels don't really matter much but for myself I'd just like to figure out where I am. So, in the new year I'm going to reinforce 17 - the skills I already have and tackle some new things. Here's what I plan to do. 18 - 19 - ## New languages 20 - 21 - I don't really have much for this section, I've been learning Go on and off for probably about a year now but I haven't really applied my learning. I hope to pair it with my learning of cloud technologies. Also I guess rust is all the rage now so maybe that will be worth while to learn, who knows. 22 - 23 - ## Open source 24 - 25 - One thing I'd really love to do is get involved with the open source commmunity whether it be something I make or contributing to another project. This is another thing I have fears about when it comes to being judged harshly for maybe not doing things the correct way. Also a lot of open source projects look pretty daunting. 26 - I know the contribution doesn't have to be code all the time though so maybe I'll focus my efforts on improving documentation first before trying to contribute some code. 27 - 28 - ## Getting really good at CSS 29 - 30 - I know people like to joke about CSS and say it's really hard to work with and while there might be some truth to that I think it's extremely worth while as a frontend developer to be really good at it. You 31 - can definitely get away with knowing the very basic stuff but I've seen some amazing website designs from people on twitter and I'd love to be able to get to that level. I did purchase Josh Comeau's css <a href="https://css-for-js.dev/" target="_blank" rel="noopener noreferrer" aria-label="Visit CSS for JS devs, opens in a new tab">course</a> back 32 - when it was in preview for a good price. I got through most of the sections but work got in the way so I didn't finish it. I plan on starting over from the beginning and finishing it. 33 - 34 - ## Head in the clouds 35 - 36 - After completing the <abbr title="Certified Cloud Practitioner">CCP</abbr> exam last year I started looking into possibly studying for the solutions architect exam for <abbr title="Amazon Web Services">AWS</abbr> next. It is slightly harder than the <abbr title="Certified Cloud Practitioner">CCP</abbr> exam but I have confidence that 37 - with enough preparation I will do fine. I do love learning about cloud technologies 38 - and this the career path I will likely end up going to sometime in the future. Kubernetes 39 - is another thing I tinkered with a bit this year which I plan on going back to and 40 - doing a deeper dive on also. Besides that I want to practice building out mock environments 41 - for small to medium business scenarios for fun and for practice. 42 - 43 - ## Frameworks on Frameworks 44 - 45 - As much as I love Next.js it would be foolish for me to not give kudos to the team behind Remix. My first impressions with it have been extremely positive and I want to try building some side projects with 46 - it as soon as possible! That isn't to say that Vercel hasn't been making some big moves this year either. Some new things introduced such as middleware, URL imports (holy shit), the new rust compiler and alpha support for React server components 47 - has me extremely excited for whats to come next year. Also them going on a hiring spree and picking up some of the brightest minds in tech seems pretty promising too. 48 - 49 - ## Shipping more 50 - 51 - The one thing I love about web development is how easy it is to get started with a project and share it with the world within a matter of minutes. I love the feeling of completing a project (which happens sometimes), hooking it up to a hosting site and then finding all of the bugs you missed during developement. There are 52 - definitely a ton of ideas I'd like to try shipping this year. A lot of this inspiration comes from watching people on twitter ship their side projects, sometimes they fail but they are quick to move onto something else and take the knowledge they've gained from a previous project 53 - and apply it to something new. I think what scared me before was the fear of failing or receiving harsh feedback on the ideas I have but I'm not going to let that stop me in the new year. 2022 is the year of shipping more! 54 - 55 - ## Conclusion 56 - 57 - I've definitely outlined a lot of stuff I want to do in the new year but I don't think it's impossible for me to complete. It's just a matter of creating a plan and sticking to it. I hope by this time next year that I've gained a ton of knowledge and completed all the objectives I've laid out in this post.
-12
src/content/blog/you-dont-have-to-code-all-the-tile.md
··· 1 - --- 2 - title: You don't have to code all the time 3 - description: Talking about burnout and how I recovered 4 - published_at: 2021-03-18 5 - year: 2021 6 - --- 7 - 8 - Honestly, this is something that I have to remind myself all the time. There's always this voice in the back of my head that tells me I'm wasting time if I'm not practicing or reading about the hip new javascript library that just came out. Being self-taught I always feel I lack a ton of skills that people that have a degree in computer science have and feel very insecure when I'm stuck on a task at work which makes me feel very dumb. 9 - 10 - I know it isn't true and there are endless examples of people that don't have a degree in CS that are extremely smart and are doing exceptionally well in the field and I guess this is something I just need to get over. Mostly what I think it is, is burnout from trying to get _in_ to the software development industry. I have a tech, non-CS background but worked manual labor jobs after college because I was still unsure of what I wanted to do career wise. Software / web development was something I always came back to because at the time it was really fun and I liked creating cool things in the browser. Two years ago I started studying endlessly to get a job as a frontend developer and would use any free time I had to learn. While it was very tiring at times and I would get frustrated I still enjoyed it and still do. 11 - 12 - I did end up getting a job as an intern last year but I think at that point the burnout had already set in. I did enjoy working at the place I was hired at but I would be really hard on myself when I couldn't do simple things and would have mini breakdowns some days. While I still love web development I think I need to turn my brain off for longer breaks and just relax a bit. I enjoy working hard but not to the point where I feel depressed all the time. If I have any advice for people that are in the same situation I was in I'd just say step away from the computer and do things that make you happy. No job / profession is worth driving yourself insane.
-15
src/content/config.ts
··· 1 - import { defineCollection, z } from "astro:content"; 2 - 3 - const blogCollection = defineCollection({ 4 - type: "content", 5 - schema: z.object({ 6 - title: z.string(), 7 - description: z.string(), 8 - year: z.number(), 9 - published_at: z.date(), 10 - }), 11 - }); 12 - 13 - export const collections = { 14 - blog: blogCollection, 15 - };
-2
src/env.d.ts
··· 1 - /// <reference path="../.astro/types.d.ts" /> 2 - /// <reference types="astro/client" />
src/images/dane.png

This is a binary file and will not be displayed.

-27
src/layouts/BlogLayout.astro
··· 1 - --- 2 - interface Props { 3 - title: string; 4 - description: string; 5 - } 6 - 7 - import Meta from "../components/Meta.astro"; 8 - import Navbar from "../components/Navbar.astro"; 9 - const { title, description } = Astro.props; 10 - --- 11 - 12 - <!doctype html> 13 - <html lang="en" class="font-sans" dir="ltr"> 14 - <Meta title={title} description={description} /> 15 - <body> 16 - <Navbar /> 17 - <main class="max-w-5xl px-3 mx-auto xl:px-0" id="maincontent"> 18 - <h1 class="mt-4 mb-1 text-4xl font-bold"> 19 - {title} 20 - </h1> 21 - <p class="mb-4 text-gray-500">{description}</p> 22 - <div class="pb-6 prose max-w-none"> 23 - <slot /> 24 - </div> 25 - </main> 26 - </body> 27 - </html>
-21
src/layouts/Layout.astro
··· 1 - --- 2 - import Meta from "../components/Meta.astro"; 3 - import Navbar from "../components/Navbar.astro"; 4 - interface Props { 5 - title: string; 6 - description: string; 7 - } 8 - 9 - const { title, description } = Astro.props; 10 - --- 11 - 12 - <!doctype html> 13 - <html lang="en" class="font-sans" dir="ltr"> 14 - <Meta title={title} description={description} /> 15 - <body class="bg-snes-light-gray"> 16 - <Navbar /> 17 - <main class="max-w-5xl px-3 mx-auto xl:px-0 pb-5 md:pb-0" id="maincontent"> 18 - <slot /> 19 - </main> 20 - </body> 21 - </html>
-20
src/pages/blogs/[blog].astro
··· 1 - --- 2 - import BlogLayout from "../../layouts/BlogLayout.astro"; 3 - import { type CollectionEntry, getCollection } from "astro:content"; 4 - 5 - export async function getStaticPaths() { 6 - const posts = await getCollection("blog"); 7 - return posts.map((post) => ({ 8 - params: { blog: post.slug }, 9 - props: post, 10 - })); 11 - } 12 - 13 - type Props = CollectionEntry<"blog">; 14 - const post = Astro.props; 15 - const { Content } = await post.render(); 16 - --- 17 - 18 - <BlogLayout {...post.data}> 19 - <Content /> 20 - </BlogLayout>
-27
src/pages/blogs/index.astro
··· 1 - --- 2 - import Layout from "../../layouts/Layout.astro"; 3 - import BlogPost from "../../components/BlogPost.astro"; 4 - import { getCollection } from "astro:content"; 5 - 6 - const posts = (await getCollection("blog")).sort( 7 - (a, b) => b.data.published_at.valueOf() - a.data.published_at.valueOf() 8 - ); 9 - --- 10 - 11 - <Layout 12 - title="Dane's Space | Blog" 13 - description="Where I write about things I've learned or found interesting" 14 - > 15 - <h1 class="mt-4 mb-4 text-2xl font-bold text-snes-black">Blog</h1> 16 - <ul class="space-y-4"> 17 - { 18 - posts.map((post) => ( 19 - <BlogPost 20 - title={post.data.title} 21 - slug={post.slug} 22 - published_at={post.data.published_at} 23 - /> 24 - )) 25 - } 26 - </ul> 27 - </Layout>
-119
src/pages/index.astro
··· 1 - --- 2 - import { Image } from "astro:assets"; 3 - import daneImage from "../images/dane.png"; 4 - import Layout from "../layouts/Layout.astro"; 5 - import Link from "../components/Link.astro"; 6 - 7 - import { getCollection } from "astro:content"; 8 - 9 - const posts = (await getCollection("blog")) 10 - .sort((a, b) => b.data.published_at.valueOf() - a.data.published_at.valueOf()) 11 - .slice(0, 4); 12 - --- 13 - 14 - <Layout 15 - title="Dane's Space | Home" 16 - description="Hey, I'm Dane. A frontend/fullstack developer from Toronto that enjoys building cool and accessible websites using the latest web technologies." 17 - > 18 - <h1 class="text-2xl font-bold mb-4">Dane</h1> 19 - <div class="mb-4 grid xl:grid-cols-2 gap-4"> 20 - <div> 21 - <div> 22 - <Image 23 - src={daneImage} 24 - alt="Dane staring down at his camera while on a boat" 25 - format="avif" 26 - quality={80} 27 - class="h-full w-sm rounded-sm border border-gray-300 mb-2" 28 - /> 29 - </div> 30 - <div> 31 - <p>He/They</p> 32 - <p>29 years old</p> 33 - <p>Toronto, ONTARIO, Canada</p> 34 - </div> 35 - </div> 36 - <div> 37 - <h2 class="font-bold mb-1">Dane&apos;s latest blog entires</h2> 38 - <ul> 39 - { 40 - posts.map((post) => ( 41 - <li class="mb-2"> 42 - <p class="mb-0 max-w-[60ch]"> 43 - {post.data.title} 44 - <Link 45 - href={`/blogs/${post.slug}`} 46 - extraClasses="text-sm font-bold ml-1" 47 - > 48 - (view more) 49 - </Link> 50 - </p> 51 - <span class="text-gray-500 text-sm"> 52 - posted on{" "} 53 - <time datetime={post.data.published_at.toISOString()}> 54 - {new Intl.DateTimeFormat("en-US").format( 55 - new Date(post.data.published_at) 56 - )} 57 - </time> 58 - </span> 59 - </li> 60 - )) 61 - } 62 - </ul> 63 - <Link href="/blogs" extraClasses="font-bold">View All Blog Entries</Link> 64 - </div> 65 - </div> 66 - <div class="grid xl:grid-cols-2"> 67 - <div class="border-2 border-blue-400 xl:w-[400px] h-min mb-4 xl:mb-0"> 68 - <h2 class="bg-blue-400 font-bold text-white px-2 py-0.5"> 69 - Contacting Dane 70 - </h2> 71 - <ul class="px-2 py-0.5"> 72 - <li class="flex items-center gap-1"> 73 - <div class="i-lucide-mailbox"></div> 74 - <Link href="mailto:khadane.miller@gmail.com?subject=Hey%20There"> 75 - Send Message 76 - </Link> 77 - </li> 78 - <li class="flex items-center gap-1"> 79 - <div class="i-lucide-square-user"></div> 80 - <Link 81 - href="https://www.linkedin.com/in/dmiller94/" 82 - target="_blank" 83 - rel="noopener noreferrer" 84 - > 85 - Add on LinkedIn 86 - </Link> 87 - </li> 88 - <li class="flex items-center gap-1"> 89 - <div class="i-lucide-at-sign"></div> 90 - <Link 91 - href="https://www.threads.net/@dane__m" 92 - target="_blank" 93 - rel="noopener noreferrer" 94 - > 95 - Follow on Threads 96 - </Link> 97 - </li> 98 - </ul> 99 - </div> 100 - <div> 101 - <h2 class="bg-orange-200 font-bold text-orange-500 px-2 py-0.5 mb-2"> 102 - Dane's Blurbs 103 - </h2> 104 - <h3 class="text-orange-500 font-bold">About me:</h3> 105 - <p class="mb-4"> 106 - I'm a developer from Toronto interested in making <i>cool</i> and <span 107 - class="font-bold">accessible</span 108 - > websites for everyone. 109 - </p> 110 - <p> 111 - I got my start in programming through video games and just being very 112 - curious about how things worked. Eventually that turned in to developing 113 - websites which I am still doing today but I have interests in other 114 - areas such as DevOps and Game Development. I also try to blog about 115 - things I've learned when I remember to do so. 116 - </p> 117 - </div> 118 - </div> 119 - </Layout>
-3
tsconfig.json
··· 1 - { 2 - "extends": "astro/tsconfigs/strict" 3 - }
-22
uno.config.ts
··· 1 - import { 2 - defineConfig, 3 - presetWebFonts, 4 - transformerVariantGroup, 5 - presetUno, 6 - presetIcons, 7 - presetTypography, 8 - } from "unocss"; 9 - 10 - export default defineConfig({ 11 - presets: [ 12 - presetUno(), 13 - presetWebFonts({ 14 - fonts: { 15 - sans: "Asap:100,300,400,600,700", 16 - }, 17 - }), 18 - presetIcons(), 19 - presetTypography(), 20 - ], 21 - transformers: [transformerVariantGroup()], 22 - });
+16
wrangler.jsonc
··· 1 + /** 2 + * For more details on how to configure Wrangler, refer to: 3 + * https://developers.cloudflare.com/workers/wrangler/configuration/ 4 + */ 5 + { 6 + "$schema": "node_modules/wrangler/config-schema.json", 7 + "name": "dane-computer", 8 + "compatibility_date": "2025-12-17", 9 + "assets": { 10 + // The path to the directory containing the `index.html` file to be served at `/` 11 + "directory": "./public" 12 + }, 13 + "observability": { 14 + "enabled": true 15 + } 16 + }