From 5ceae5e017f2d9082887b470709a25b1d1ea1dec Mon Sep 17 00:00:00 2001 From: Vlad Severin <0altazar0@gmail.com> Date: Thu, 5 Jun 2025 18:58:06 +0300 Subject: [PATCH 1/6] Add Tailwind setup --- .gitignore | 4 +++- Makefile | 10 ++++++++-- package.json | 7 +++++++ src/styles/tailwind.css | 3 +++ src/templates/home.html | 2 +- src/templates/new-blog.html | 2 +- src/templates/signin.html | 2 +- tailwind.config.js | 9 +++++++++ 8 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 package.json create mode 100644 src/styles/tailwind.css create mode 100644 tailwind.config.js diff --git a/.gitignore b/.gitignore index 86c9d74..d2fbaa5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ tmp pem blogs .DS_Store -*.db \ No newline at end of file +*.db +node_modules +public/styles.css diff --git a/Makefile b/Makefile index 684134d..dabf7dc 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,14 @@ run: go run ./src/ test: go test ./src -build: +build: tailwind-build env CGO_ENABLED=1 GOOS=${GOOS} GOARCH=${GOARCH} go build -o bin/mkblog ./src upload: gtar -czf repo.tar.gz --exclude-vcs-ignores --exclude=repo.tar.gz . - scp -i "${SSH_KEY_PATH}" repo.tar.gz "${SSH_USER}@${SSH_HOST}:/opt/mkblog/repo.tar.gz" \ No newline at end of file + scp -i "${SSH_KEY_PATH}" repo.tar.gz "${SSH_USER}@${SSH_HOST}:/opt/mkblog/repo.tar.gz" + +tailwind-build: + npx tailwindcss -i ./src/styles/tailwind.css -o ./public/styles.css --minify + +tailwind-watch: + npx tailwindcss -i ./src/styles/tailwind.css -o ./public/styles.css --watch diff --git a/package.json b/package.json new file mode 100644 index 0000000..7fb61ec --- /dev/null +++ b/package.json @@ -0,0 +1,7 @@ +{ + "name": "mkblog-platform", + "private": true, + "devDependencies": { + "tailwindcss": "^3.4.4" + } +} diff --git a/src/styles/tailwind.css b/src/styles/tailwind.css new file mode 100644 index 0000000..b5c61c9 --- /dev/null +++ b/src/styles/tailwind.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/src/templates/home.html b/src/templates/home.html index d8c7834..f863d38 100644 --- a/src/templates/home.html +++ b/src/templates/home.html @@ -4,7 +4,7 @@ Home | mkblog - + diff --git a/src/templates/new-blog.html b/src/templates/new-blog.html index d23b72e..bb43933 100644 --- a/src/templates/new-blog.html +++ b/src/templates/new-blog.html @@ -4,7 +4,7 @@ Create a new blog | mkblog - +

Create a new blog

diff --git a/src/templates/signin.html b/src/templates/signin.html index 8f18730..41eb204 100644 --- a/src/templates/signin.html +++ b/src/templates/signin.html @@ -4,7 +4,7 @@ Sign In | mkblog - + Sign in with GitHub diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..2d06262 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,9 @@ +module.exports = { + content: [ + './src/templates/**/*.html', + ], + theme: { + extend: {}, + }, + plugins: [], +} From 2022ecc8336f962a37abec874a52857aa848cab7 Mon Sep 17 00:00:00 2001 From: Vlad Severin <0altazar0@gmail.com> Date: Thu, 5 Jun 2025 20:14:19 +0300 Subject: [PATCH 2/6] style: improve templates with Tailwind --- src/styles/tailwind.css | 6 ++++++ src/templates/home.html | 14 +++++++++----- src/templates/new-blog.html | 30 ++++++++++++++++-------------- src/templates/signin.html | 4 ++-- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/styles/tailwind.css b/src/styles/tailwind.css index b5c61c9..ca84557 100644 --- a/src/styles/tailwind.css +++ b/src/styles/tailwind.css @@ -1,3 +1,9 @@ @tailwind base; @tailwind components; @tailwind utilities; + +@layer base { + body { + @apply bg-gray-50 text-gray-900 font-sans; + } +} diff --git a/src/templates/home.html b/src/templates/home.html index f863d38..6342e84 100644 --- a/src/templates/home.html +++ b/src/templates/home.html @@ -7,10 +7,14 @@ - -

Hello, {{ .User.Name }}

- Open my blog - Logout - + +
+

Hello, {{ .User.Name }}

+
+ Open my blog + Logout +
+ +
\ No newline at end of file diff --git a/src/templates/new-blog.html b/src/templates/new-blog.html index bb43933..9211378 100644 --- a/src/templates/new-blog.html +++ b/src/templates/new-blog.html @@ -6,19 +6,21 @@ Create a new blog | mkblog - -

Create a new blog

- Install our app on your GitHub account -
-
-
- .mkblog.dev -
-
- -
- -

{{ .Error }}

-
+ +
+

Create a new blog

+ Install our app on your GitHub account +
+
+ + .mkblog.dev +
+
+ +
+ +

{{ .Error }}

+
+
\ No newline at end of file diff --git a/src/templates/signin.html b/src/templates/signin.html index 41eb204..1bf26fa 100644 --- a/src/templates/signin.html +++ b/src/templates/signin.html @@ -6,7 +6,7 @@ Sign In | mkblog - - Sign in with GitHub + + Sign in with GitHub \ No newline at end of file From dae2161e196172137f48fad9aac083914936c5ac Mon Sep 17 00:00:00 2001 From: Vlad Severin Date: Thu, 5 Jun 2025 20:17:06 +0300 Subject: [PATCH 3/6] chore: add package-lock.json --- package-lock.json | 1381 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1381 insertions(+) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d5577f6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1381 @@ +{ + "name": "mkblog-platform", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "mkblog-platform", + "devDependencies": { + "tailwindcss": "^3.4.4" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz", + "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "dev": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yaml": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + } + } +} From 5f232bcce3cb64b899b9a3a0063aac9b54cd8040 Mon Sep 17 00:00:00 2001 From: Vlad Severin Date: Sat, 7 Jun 2025 16:36:43 +0300 Subject: [PATCH 4/6] chore: parse templates on each request in dev mode --- Makefile | 2 +- src/auth.go | 3 ++- src/blog.go | 11 ++++++----- src/main.go | 5 ----- src/templates/signin.html | 12 ------------ src/user.go | 3 ++- src/view/fs_dev.go | 10 ++++++++++ src/view/fs_prod.go | 8 ++++++++ src/view/renderer_dev.go | 16 ++++++++++++++++ src/view/renderer_prod.go | 14 ++++++++++++++ src/{ => view}/templates/home.html | 4 ++-- src/{ => view}/templates/new-blog.html | 0 src/view/templates/signin.html | 15 +++++++++++++++ 13 files changed, 76 insertions(+), 27 deletions(-) delete mode 100644 src/templates/signin.html create mode 100644 src/view/fs_dev.go create mode 100644 src/view/fs_prod.go create mode 100644 src/view/renderer_dev.go create mode 100644 src/view/renderer_prod.go rename src/{ => view}/templates/home.html (89%) rename src/{ => view}/templates/new-blog.html (100%) create mode 100644 src/view/templates/signin.html diff --git a/Makefile b/Makefile index dabf7dc..3d6f818 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ include .env run: - go run ./src/ + go run -tags=dev ./src/ test: go test ./src build: tailwind-build diff --git a/src/auth.go b/src/auth.go index 59f3da5..b7d342e 100644 --- a/src/auth.go +++ b/src/auth.go @@ -6,6 +6,7 @@ import ( "log/slog" "net/http" "net/url" + "platform/src/view" "time" "golang.org/x/oauth2" @@ -14,7 +15,7 @@ import ( /// API Handlers /// func handleSignin(w http.ResponseWriter, r *http.Request) { - pages.ExecuteTemplate(w, "signin.html", nil) + view.Execute(w, "signin.html", nil) } func handleLogout(w http.ResponseWriter, r *http.Request) { diff --git a/src/blog.go b/src/blog.go index 8b7f486..e64d2de 100644 --- a/src/blog.go +++ b/src/blog.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "os" + "platform/src/view" "strings" "time" ) @@ -47,13 +48,13 @@ func handleNewBlog(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: - pages.ExecuteTemplate(w, "new-blog.html", NewBlogPage{ + view.Execute(w, "new-blog.html", NewBlogPage{ GHInstallationURL: os.Getenv("GH_INSTALLLATION_URL"), }) case http.MethodPost: name := r.FormValue("name") if name == "" { - pages.ExecuteTemplate(w, "new-blog.html", NewBlogPage{ + view.Execute(w, "new-blog.html", NewBlogPage{ GHInstallationURL: os.Getenv("GH_INSTALLLATION_URL"), Error: "Name is required", }) @@ -62,7 +63,7 @@ func handleNewBlog(w http.ResponseWriter, r *http.Request) { repoName := r.FormValue("repo") if repoName == "" { - pages.ExecuteTemplate(w, "new-blog.html", NewBlogPage{ + view.Execute(w, "new-blog.html", NewBlogPage{ GHInstallationURL: os.Getenv("GH_INSTALLLATION_URL"), Error: "Repository name is required", }) @@ -76,7 +77,7 @@ func handleNewBlog(w http.ResponseWriter, r *http.Request) { } if !isAvailable { - pages.ExecuteTemplate(w, "new-blog.html", NewBlogPage{ + view.Execute(w, "new-blog.html", NewBlogPage{ Name: name, GHInstallationURL: os.Getenv("GH_INSTALLLATION_URL"), Error: fmt.Sprintf("The name '%s' is already taken", name), @@ -91,7 +92,7 @@ func handleNewBlog(w http.ResponseWriter, r *http.Request) { } if !weHaveAccessToRepo { - pages.ExecuteTemplate(w, "new-blog.html", + view.Execute(w, "new-blog.html", NewBlogPage{ Name: name, RepoName: repoName, diff --git a/src/main.go b/src/main.go index 1c13076..f439c28 100644 --- a/src/main.go +++ b/src/main.go @@ -1,7 +1,6 @@ package main import ( - "embed" "fmt" "log" "log/slog" @@ -9,7 +8,6 @@ import ( "os" "path/filepath" "strings" - "text/template" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" @@ -23,9 +21,6 @@ const pkceVerifierCookieName = "pkce_verifier" var ghOAuth *oauth2.Config -//go:embed templates/*.html -var tmplFS embed.FS -var pages = template.Must(template.ParseFS(tmplFS, "templates/*.html")) var logLevelMap = map[string]slog.Level{ "DEBUG": slog.LevelDebug, "INFO": slog.LevelInfo, diff --git a/src/templates/signin.html b/src/templates/signin.html deleted file mode 100644 index 1bf26fa..0000000 --- a/src/templates/signin.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - Sign In | mkblog - - - - Sign in with GitHub - - \ No newline at end of file diff --git a/src/user.go b/src/user.go index 98a32c9..01445eb 100644 --- a/src/user.go +++ b/src/user.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "net/http" + "platform/src/view" "time" @@ -49,7 +50,7 @@ func handleHome(w http.ResponseWriter, r *http.Request) { return } - pages.ExecuteTemplate(w, "home.html", HomePage{ + view.Execute(w, "home.html", HomePage{ User: *user, BlogURL: fmt.Sprintf("/b/%s", blog.Name), }) diff --git a/src/view/fs_dev.go b/src/view/fs_dev.go new file mode 100644 index 0000000..52147d4 --- /dev/null +++ b/src/view/fs_dev.go @@ -0,0 +1,10 @@ +//go:build dev + +package view + +import ( + "io/fs" + "os" +) + +var FS fs.FS = os.DirFS("src/view/templates") diff --git a/src/view/fs_prod.go b/src/view/fs_prod.go new file mode 100644 index 0000000..5182ac4 --- /dev/null +++ b/src/view/fs_prod.go @@ -0,0 +1,8 @@ +//go:build !dev + +package view + +import "embed" + +//go:embed templates/*.html +var FS embed.FS diff --git a/src/view/renderer_dev.go b/src/view/renderer_dev.go new file mode 100644 index 0000000..241b962 --- /dev/null +++ b/src/view/renderer_dev.go @@ -0,0 +1,16 @@ +//go:build dev + +package view + +import ( + "html/template" + "net/http" +) + +func Execute(w http.ResponseWriter, name string, data any) error { + t, err := template.ParseFS(FS, "*.html") // parse on every call + if err != nil { + return err + } + return t.ExecuteTemplate(w, name, data) +} diff --git a/src/view/renderer_prod.go b/src/view/renderer_prod.go new file mode 100644 index 0000000..16fc9ad --- /dev/null +++ b/src/view/renderer_prod.go @@ -0,0 +1,14 @@ +//go:build !dev + +package view + +import ( + "html/template" + "net/http" +) + +var tmpl = template.Must(template.ParseFS(FS, "./templates/*.html")) + +func Execute(w http.ResponseWriter, name string, data any) error { + return tmpl.ExecuteTemplate(w, name, data) +} diff --git a/src/templates/home.html b/src/view/templates/home.html similarity index 89% rename from src/templates/home.html rename to src/view/templates/home.html index 6342e84..65eec71 100644 --- a/src/templates/home.html +++ b/src/view/templates/home.html @@ -5,9 +5,9 @@ Home | mkblog - + - +

Hello, {{ .User.Name }}

diff --git a/src/templates/new-blog.html b/src/view/templates/new-blog.html similarity index 100% rename from src/templates/new-blog.html rename to src/view/templates/new-blog.html diff --git a/src/view/templates/signin.html b/src/view/templates/signin.html new file mode 100644 index 0000000..69200b6 --- /dev/null +++ b/src/view/templates/signin.html @@ -0,0 +1,15 @@ + + + + + + Sign In | mkblog + + + + + GitHub logo + Sign in with GitHub + + + \ No newline at end of file From 5423991e2b5670e0ef5d07acf8feead6496ba418 Mon Sep 17 00:00:00 2001 From: Vlad Severin Date: Sat, 7 Jun 2025 16:41:15 +0300 Subject: [PATCH 5/6] chore: add CLAUDE.md for claude code --- CLAUDE.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..7f8113a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,81 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Key Development Commands + +**Primary Build & Run Commands:** +- `make run` - Run in development mode with live template parsing (`go run -tags=dev ./src/`) +- `make test` - Run Go tests (`go test ./src`) +- `make build` - Production build (includes Tailwind CSS compilation, outputs to `bin/mkblog`) +- `make upload` - Deploy to remote server via SCP + +**CSS Development:** +- `make tailwind-build` - Compile Tailwind CSS for production (minified) +- `make tailwind-watch` - Watch mode for Tailwind CSS development + +**Database:** +- Uses Goose for migrations with SQLite (`GOOSE_DRIVER=sqlite3`) +- Migration files in `db/migrations/` + +## High-Level Architecture + +**Core Technology Stack:** +- **Backend**: Go with Chi router, SQLite database (sqlx), structured logging (slog) +- **Frontend**: HTML templates with Tailwind CSS, HTMX for interactivity +- **Authentication**: GitHub OAuth with PKCE for security +- **Deployment**: Caddy reverse proxy with REST API configuration +- **Blog Engine**: Custom mkblog engine for static site generation + +**Application Flow:** +1. **Authentication**: GitHub OAuth flow with PKCE verification, session management via cookies +2. **Blog Management**: Users create blogs linked to GitHub repositories +3. **Deployment Pipeline**: + - Downloads repository tarball from GitHub using app installation tokens + - Builds static site using mkblog engine + - Blue/green deployment with atomic symlinks + - Dynamic Caddy configuration for custom subdomains (*.mkblog.dev) + +## Key Architectural Patterns + +**Build Tags for Environment-Specific Code:** +- Development: Templates parsed on every request (`//go:build dev`) +- Production: Templates pre-compiled at startup (`//go:build !dev`) + +**Database Design:** +- Users table with GitHub integration (tokens, user info) +- Blogs table (one blog per user, linked to GitHub repo) +- Deployments table with status tracking and constraints ensuring single pending/running deployment per blog + +**Context-Based Request Handling:** +- Middleware injects session and user data into request context +- Type-safe context value helpers with generics +- Authentication middleware validates GitHub tokens on each request + +**Template System:** +- Embedded file system for templates in `src/view/` +- Environment-specific rendering (dev vs prod) +- FS configured as `os.DirFS("src/view/templates")` in dev mode +- Template parsing uses `*.html` pattern relative to FS root + +## Configuration Requirements + +**Essential Environment Variables:** +- `PORT=8080` - Application port +- `DB_SOURCE_NAME=./db/mkblog.db` - SQLite database path +- `GH_CLIENT_ID`, `GH_CLIENT_SECRET` - GitHub OAuth app credentials +- `GH_PRIVATE_KEY_PATH` - GitHub App private key for repository access +- `DPL_SRC_DIR`, `DPL_DIST_DIR` - Deployment directory paths +- `RESERVED_BLOG_NAMES` - Comma-separated list of reserved subdomain names + +**External Dependencies:** +- Caddy server running on port 2019 (REST API) and 443 (HTTP server) +- GitHub App installation for repository access +- Node.js/npm for Tailwind CSS compilation + +**Development Setup:** +1. Copy `example.env` to `.env` and configure GitHub OAuth +2. Install dependencies: `npm install` (for Tailwind) +3. Run database migrations using Goose +4. Start development server: `make run` +5. Use `make tailwind-watch` for CSS development \ No newline at end of file From b1bd37456cc8b2728c88bfc50d03e84d92576fb7 Mon Sep 17 00:00:00 2001 From: Vlad Severin Date: Sun, 8 Jun 2025 14:12:34 +0300 Subject: [PATCH 6/6] feat: improve UI (WIP) --- .gitignore | 2 +- Makefile | 4 +- public/{ => css}/simple.min.css | 0 public/fonts/CommitMono-400-Regular.woff2 | Bin 0 -> 40568 bytes public/fonts/CommitMono-700-Regular.woff2 | Bin 0 -> 39908 bytes public/imgs/favicon.ico | Bin 0 -> 15086 bytes public/imgs/github-mark-white.svg | 1 + public/imgs/github-mark.svg | 1 + public/imgs/logo.svg | 5 ++ public/js/htmx.min.js | 1 + src/main.go | 2 + src/styles/tailwind.css | 22 ++++- src/view/renderer_dev.go | 25 +++++- src/view/renderer_prod.go | 21 +++++ src/view/templates/base.html | 54 ++++++++++++ src/view/templates/home.html | 4 +- src/view/templates/new-blog.html | 96 ++++++++++++++++------ src/view/templates/signin.html | 51 ++++++++---- tailwind.config.js | 2 +- 19 files changed, 242 insertions(+), 49 deletions(-) rename public/{ => css}/simple.min.css (100%) create mode 100644 public/fonts/CommitMono-400-Regular.woff2 create mode 100644 public/fonts/CommitMono-700-Regular.woff2 create mode 100644 public/imgs/favicon.ico create mode 100644 public/imgs/github-mark-white.svg create mode 100644 public/imgs/github-mark.svg create mode 100644 public/imgs/logo.svg create mode 100644 public/js/htmx.min.js create mode 100644 src/view/templates/base.html diff --git a/.gitignore b/.gitignore index d2fbaa5..599d132 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ blogs .DS_Store *.db node_modules -public/styles.css +public/css/styles.css diff --git a/Makefile b/Makefile index 3d6f818..33136cb 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ upload: scp -i "${SSH_KEY_PATH}" repo.tar.gz "${SSH_USER}@${SSH_HOST}:/opt/mkblog/repo.tar.gz" tailwind-build: - npx tailwindcss -i ./src/styles/tailwind.css -o ./public/styles.css --minify + npx tailwindcss -i ./src/styles/tailwind.css -o ./public/css/styles.css --minify tailwind-watch: - npx tailwindcss -i ./src/styles/tailwind.css -o ./public/styles.css --watch + npx tailwindcss -i ./src/styles/*.css -o ./public/css/styles.css --watch diff --git a/public/simple.min.css b/public/css/simple.min.css similarity index 100% rename from public/simple.min.css rename to public/css/simple.min.css diff --git a/public/fonts/CommitMono-400-Regular.woff2 b/public/fonts/CommitMono-400-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..f9df93785d745986176ff077809db21f8713915e GIT binary patch literal 40568 zcmV)AK*YayPew8T0RR910G@aN4*&oF1I?5G0G<^90RR9100000000000000000000 z0000#Mn+Uk92yuKARL3{Vg_IUi+T|V3W=5+hTu;Nyfgp-HUcCAo*)Du1&|^Kfudz|NsC0|EgpXW18Iam;8rE5JXjLt#;eA-KwZ5M$;5?7V#QI`Zh#FG}%a%vDh?; z)xPwyjVgV0X_Qukv$$@{xGS={l>GK`0LN2pn`JK2a6opy6`%UPA44J{qRg{4WhMs9 z44FX^E-Na-fQ+5>gwEtbRh7}T>$90`7+x+7nQ2q@21z&)%@OJfMp?l8KJJ%wDNE#c zgYBaZ!!Q)-(<7b9{YeVgtGEvrDY(wbE#Z*7dweoN`AJI3s!vlr|582+?YFwRP))ET z9aiT>*ST!ltQS1sKiImv!`)vr2os*27g%IkO>b#j2@FkU1Wch~Cns0Crc4`?HpCU5 zl(FMgUg!m1q+#oNQBJAqi(Nd0h{A8CT$xz=w*&{rtq^ZjNO7rZ6;lOz>OXXp|M16~ z1F}L#wYxI@;1PX^p~vm)8E(Fwojfv%sNf@OMs(siJ>irvWcQBk8@YLYhxB`Xx9op# z;0LpNU_OwE{ zCtqg6^K1y>C}I}qVPYieofVj8^xauUg)Las z%Yh?EgCYbBj*#FH5+SkZckVxVtp?St85g(4K+B*^0E-L!_ogJfS+oDSAO0QStBjpl zhF8%<+9p1+iBG8i?|%UQ``2_B8ll<4XxR$;9A1FXej#=1Q zGYc$H*$Fq+w;K)0m7(92m>7*7Nf zI0TV)C+s30YCmdS!R{oi;IksL%LIiDEkSp#gWIB<5tZSCA%0?SA!+-VKL}!A-fzp2 zo+ovY2r%8wvQww04tLJH`>P9Dal~sfK%}Z4-v@%~|Y(Q-ly0z`>9^ zp7aN}*RFTpE}5Mq9wAW*r%(u|NPtabeg(jk7UuRqm6fB|Tocyn;PoglFA-+rytSq$ z3Q%y&1XdNl8;tF%wC}5$fCZ4!2Wf6MPM5yQRcSguKDth6QkcGGoinT#|Nm20y(ihw z=Ush!64fz8iXS9@u*%3-6t0f+RAM7hJG*-qV{(`rma`j3Z9^E3(1H%WqFF8tmY(~( z6=hK2_HfBWk4~>Te}?4?fWS;a&`v^SMHHn0K_bxqZ@T)@dMXJs7QXfR&ISqa|9Tf>yV-`XZoOCaOqHan zl0Z^PfJ7Sv&7T%(Ll0|ILU1G@=7_N{)~vUH#?jx>{jH7G853C(u0OdkKFc?9;fBe^ z*=~?o-+pP*wEd=dXC+;O%uOg07)B%OJ=wm~T_=#GwELf{vXi%$1$n4hoiQ`BC=VPN zzgwM3&2;8Z7WjbJ{rXk^|0JF614e~HAqj+KD? zO(Mj6`1|>Qmo~K&nQ%}q2`8RWrMBx9TEuqd$im~rP4;~{lRMMTO4lxn*hRKB zgpk@{7{ZVSE7to3``G@M{fzg*ax6?#b5Ai>YGE&axJa1|IJpDMGt$%Gf^|J!nZ zUg+S2t8Yyl=b8uAv8Y}CgcR0c6--xja3uf)z^nIl9RTp* zqx}DaoppxE77NQLI$D#?hsEqcfN+ZnoK9 zSacx!>ve)^8%Q&(6R`lb6w`}aO&D%ZTl%M9*Cce{yCxck+=Bg!WS!7BscDlUTaaKF zAwpqofJDSdBAGY|QpiQBqn$B$e7HHBxp3tMz>TZrKmeRd5GyHQ zep^8z%MBW~%|7E!x#)&_roHhE|An~7=EYwa0%3~M%dfF+%dNM|5vS-f-J&P-!Cw@z zv<@{U7yrEU0d1n%eOk8Tdd5<@QjN*Q2j_J^Z;e(|WAy_dsglKPKC65(lKfqT!8xjw zLY3agtg}p6{3oq@0@>dhKDU`EHYndF%tnUPQK8Ke8m?1pcG=vqh1*8h8f;r_x6O;~ zu^QWpw(n*-&BV>r%&eT*+qg5==Zl#;W|3x{m^E!@ZHIwP$&O?fZ&$y>%5JIMzHwW& zyJ+{$-pL*}nXu>EXWMt%Z(B3_3Hv87{O*AC9S9D(QK7>U+w5>Ybjsn0Biu2_QJ6X= zIyQo>bUZ|0%<-y|wG-_D9H-1V<*p158^j`C7ytgCdsv^yWc+&4TKa1Cpr9Y>m4DMX z0c!wY=oT3I6VlDE)55Yt^SX-GmkKMk)SPYPnaA6`=GiRTv%+JL0!G6&gS)ZwmFyAt zh;ZcCX4vNH&1*Mb-2Ct8`7MK63%4=1O>ghof!WaytN}o5$MaobyLar3+8=u0<-t#f zNk@*1?>iRz$CruUCzvOXo!&QDc=pZtO&4!nzI^4zHMgm&H)JDQCi3@!zQQe^HNz z!K{GEBM_F<&xIhL$)>&YYy0k~7{$d5MG`C2ZP~VC*V4+GbsIk8Jsc5ZF5uDvcpmC{>!q+8XWswVkv#wY2raK5Q+9v4TS+(X5e4m#0=M3`=D2 zWEwigCYGK=V+eGHP~?jPwIoqRqsfkVqe^`PLnC7oQw#aw5B`=3M3TQ@cJVKoKqwMR zq%yg}(+svot20iQ%yJ!Yd3=G;#nsK-!_$8}fk+pLB~o>REv@OR>8PQxxwYpckM5>f zr#CpQkc~!XFj;J|L<-2{3X`KQ`jMcGcdgHKdWP4eGMkriV!EW;=sVX{&* zCcyRF;&kJt4R4!VavE_-mC-{@n%&l%a~x!NdfPjfQW|L($l#fOdEb}bD#$=X#gs~JnTQZ00YZw5B+h%mi(c}w zSM>Frzhp&-5lrOKLr=X#h%`KHy7U<`7GK6lO|{k6KtrAKuxP7ow%cLCiJYwPr(5p0 z=Ru}jF_g!9+cNbnxau{hyzUKede;Y83R!R=gd$v-*-%1>nKGADa_Mpp22;?pGO$gA z`NmaSUG+88SX0dh9C*;dioeCw%)kC8B8j+I5FHa67oU)Vym^Nme&nG?HSPQ+&R?DG zOp~(&NF1pmNDeGI<0*d^BzlkivOeizfMVMz)DcC@m-5Hp3E~DK zH1^1ar4=>L@_XC+I|``jS4<*pPtbG+FK2ZZ?v{qPXl&$Iq&fzY{4A0`a2I(8#NAOU z@p>Qof_Ci>p(0Wr@BUGWQ8jCYMX5Sb&8&WU_tRSbT_V!>_lr31jHNPyBEp9^q7-n& zd@j-*RQB{E0r?{irlLnOO|*G96Y1&`gJgovz87t^&Fc>1f;2+mH6 z82O}ErWi__0U$#nDLVlP_2B?&(DML5J{&o!oe0QS4QTXmHriO(|A>6^b)!!!00)04 zOC$?H>(m1n9n?x18K#zky(*=Qfp?>X_#ls~vOEd%#f%o52Rc6_r^t^3rDK>|8Y;0l zAPIaSC`JLMgMyi{CYTFA*9ZZG% z`WbA9p+*{Svg!IAnbvE+#e3?V`uU#!#UAD8$Do8d>S>^nb`eoASyhd_QoOl0Je`%g z=g?<;<&Tz(5+}h}iIOB6r_`m%sp*+n**Qf!*No0B_dN2n7%gC%lkf=$H}DE*?>Bro z1tk?V4J{o#1EY8e5}BB--{xBiV4FnJvp*FZ zM7GBzzusyT|d3;wgR9D{UDVkU+H}urv@*s{ouDFi@!kTsRlk)opSc z9$NJe=Msue?h8M)FVdNTe{;S-C=yGgGPy#jQfst2y}{^IwtQ`12owfKAW>)x7KbMg zNn{F@MrW|t94?P9@DvydN20NKBAH5OvblVrSSnYl^*8}a2&agVOoCjbk()d)1PX&A zkSH_;i^CI$Br=6cqcfU`L2@*C#ZL;2!4*qo8kz>?Ud5gV^3mF2 zt2K@H#>FQjCUvhz&w5!Pkv!Z@-{qHi!`zz8q(iF@6)>cgf%$}0m#sd^tGNEgoT?seediA<*q|<69@m*{)pO;d!%< z+euF8I5SoPzt9m+#^!QS zDrw(;gWv0R4oJiNB27G-nRG?d$@}qJ&H4WVi-Y1T4Dn*@=>LcC{rs)vLR=79928$2 ziC5$BD3=JaU%&NSj2l;jTMQIm*^{!hKh*ABYzM*EC)#&#Hth#Xl_p)r=fu6U zmtRnr26xL^p&ipa#6#|GOe}5sXM3*h?OxstC3S=- z8|A~R89I17Lih#kSNBS)L<=`I^{`#s1s@R&#;uvRKUge#qMo?C2wN+Z@$xKXZdx~+T_DpsK;&8yf(8&~;h(yYp>sb*C%>0~lM z5Qt94*c=k4yihoBDdttxREwrT(0G|WnFhGE!PX9s9yrFl2k-2E!@11iH=X-kVrpLZ znCC;~XZ^^j!rYZ?we6F2e*6;pA-9x%jh6BJ3fdrohmUwowXYoGQXBvkAzp&+uNLD5Pvlxl#XlFYAOg>_pf=XeJh4sjEl zUhqwFap8BDN5kJc{u?NpMNe(8&v$9-`)NCicpYL8Ei5~U%Y`4M`Xow){$+Y-_1Vra7P+h2+elaW zx+2wS`s~60R~x(BA3iv|mM?QfMBB3j|2q?xhreITJJ1-H(WS;p_!k#4{oeI`jfPq5 zes5<}6Y>%yc5#O9bVa6PKBwh*vGD~g{6?jS9v@?=oVdI<@t@b7;K=Rh{cgwgZ99G1 z7e04+-RDcXL(OYFTH5g!yY4JmDWSObbZpEjOj?85x#W7xmy}tOZmO!T-yBm_`RziV zdPV9*%%@s2SfvV;o2NI}kv!|^xBIpH(O2`+Ge7E8d4zbBI8Hr;vBj!88B_C)vB4(S zj=qG+l+M#-i7ClxsTt{&tYbsff3jFhd*tt^4O!o<-@|7xjqly=%+W~G`&;koTC?+3 ziF$`(3NyH!Cy;sJLP62x6O)o^_IwN$c#sq^?Ew0}5hPI+eO zb-=Y{<&|Q~k@5KQbrN$!%9g+BJxlrKpb)RS-Z!x!8`~NgCAQASw_f@C8^&R)^?svo zhkSPsObLN}==D6%}9XMu!P2Cb`5-?(&$IyyFYShAZ6U zUOYh&L^yaT$f=;;nXhLlG8Cw{+K#C5S}l6M2mMpM>B3_rNLE5wun}?IUk&N5(hQSq zN?X&4$mjIgXCFQ(b-GM>g0o!aPww%ASG?ydWXoOL;y%3aBbW#XP*G6HfOFpnEEUY36qytHXOuU@OQ&{s4~-JoA2D3o6kP`3CL*BW5$!5;|hOq zpQpU$133k{Dz!X~^V#Ph5d|#< zEO?p=T;nzmdBz()5fM1oxd(T=2_%$gh%iu7!)jOFXoiR?F~NH0#Z{} z4Hg_E;?Pjb8lUiHHX>9*g6 zwWn%9%-WS+-ga-vtbqOfoj?44YDi7LS7NxkdQAoPd_wvEhXs`VP(*O*|NlMt14w^% z_7`9S0I=^H|LHAMfb^Z+XV@Ryzf+Lx|49CLGJw6BS<447O`fK=^!lih`Ry9X_8?KByoR9>qX$QDRgvY7uG#waw4U&)qM`FTyX$Z@%9Ozs-J! z{iggL`n~oC{*L~>{#bvazr;Vof4=`A|I_{-17HCj0oZ`~0owyE2mB5ULWiMuq7R@i zps%C?h&%j7h=W|_r_UE_mk0$RDTj zks6>L#?39l7hkcekFEiZR=V}kt@`M;SmN-%D2BNoRBG?j`FZ64rUQ1&1RPk1^mB4l zh5YjVv|q$dfefuq9~{lVUliCGhx zqUz!4Ww55-BhgqqkxZpC*<8L*ER}1(G${rE`hFPl2Nja8H7*#W{40I)zXrGVufQGr zwL0+xxq|(1!q6`-PG`>*;4Ogv?j)Mb;E6>NnN+S+Q>klcX=>}}8R#1t8=0F~ST^e} z88YQ|tOu-jhy32QDeq9aXPw=;JC6IOovS`h6DN4x?%impu~Ac?s}-F9ON$-et;YW7 zDs51D+atYc8=L4GG`Tsa6HR%SDfD{+bg2hBXlm6V28>0$ROo+_qtY%Vg~Mh0yJNaa zQ&H1Ym!6g)0Qw&Q0A*oo0e3L4|G=8VuK;qN0001fp#Z437R`U}w`r;|K+gs=`eqXh z0}y~*G_P~x9iuG7FA#}y8mUP|1lQpucxHW47ES|qH)Xb-&_tYQAk}36rJj4@t<1Du z;QaZ-#3fmT<~(suL?V^>NCWk$Y_6A!Buy)%8ZWGMOW0KXO*YXz%LQLhMPM3Efp^WO zii}pr7idLlEJ+;QWK=F>4jgg~lkg;~nLY0i%Z^+OVuPK!G|&WqvX1jds&>}ss?3C94yR%4is@g_qXRq$$zE+F2|6odFX=SQ$wLTy?1e4R9 zkK7$FQg~kai#Qia7*aRi8p9aAcuX6NG6j`Zb!y`*kN(oJM*k0_-WX4mQg8BxzA= z&D*n(dH!4VkH?AG2YrZ#E8;4@v~mJo6;-lg_YeX|NuWCFL(~*!QzC=}18RB%LyZJN z4yz){az9m~l=0dD`^95?TdeBt3kjr%c4$5;;B=U~N~ap(e6lBmiYSYtDi`sE*qc!R ziWF289Gee0#w!ayhLAQm6Xt|W$IO7tp-R9LuZo}CCp=FxDrTuNTeTVH=a*qL_tm@* zyyF%VGnuyS$dUa=04w!v^iZE^sMQu=%2k!#y2WUl(&z^k__bX{G*C0WG#$ zjqMm>8=J}T20*7CA1_-iq;FgxxP#1{fem_uJ4-Jo9^;h9^6gjnLLVgzX? zkOiuijyML0LuVWa08|=JxE#6Q>Pwt6<`8^7Ts5k;36D|GqL`sg<)WKCzE>DR>uc4g zWNEpx?aHjja<(y+7)cbI$RT9BI;!$o5d)^ZBN!Bvo4`eCK`>#ca=B7y*hd`8agNm! z<@v(vL$qc8A2s5Y5%b#jt8QVD=@zVF6mF&=52nZ-xiI=25Z^DKgPD=;sUO5WuQ$#HD% z%NyfuVWAk&{%-Ecz8JgC1#E#e_>wi<4UBqN5*OVVgHHx|1}7pA@NH@>ta%!|s+hMA z-=QdcoDDbAWDg{21vnF##Dik%eoNJBV>4+a$P-kCI~!HAGT5ku72#fhZo;79+c=xI zwkI5C5LzK~U=H__vk|Tp_~;IhfKY;f?#k}#yJlShk_A+R9}#3VcpNO2rGBAc?ha&7OzA_lB-=a~dz)30(dNneMAkq&D06nkpAH&_ z!1i8F_)O?CN&3WbAN_3PT~PkW!Cfr= zwx>$nmxbu(pt8XhOa|3Qt6|6~}--$d?=HkVj^nX}F?G8P8Q{DIAY*t4Rsq;D{~g3W*KscpJ1 zSL^bT^aK^Ouet2HQi4&{>`(!rj(i+~%)~Cpdblqot_~?mQJ!W9U0rqI)3{q+bzD#Q z4QLKI&JienUL!{6?$3tAg~WPAQLCxjXPP@> zo*p}=TF!WWQK>)7or0=pCmeWo{;L}T7?o`mIYBWlsAJiwf|To6_Le;RmjMH4=Wj10 z#hh4iXb7sPRhf_m`qh%8R1{d03{USjqs(+>Zu1-*M=mW(`Y!YpIXieM8Z_n!G7@bH%0&y<4 zWXH*oqQ|zkt%Of(3S2DG9KsM87NLnbq?m=QM{>NMG$dvXc|VUh$;B#!VgT-TzCABS zGG37g(8?@ZS0*CHq_BT_hhnv1Mcp+_-YwJvM^i!Np03E&E6@LwZt6ZIDuN;=;=-Jr*X;9Nu&&`w8;99*sGv$@-ac^MU;L3L$)5yjqp^C@F;pLsRe4xj3b|KRa_jrB$(KGN@#KX2!l! zS+y$fvePgQOi_8DZ5aX6(f7{j@jHTizBSsT9YIA0w7D%h zF6m_T{NvB5@*Iqtx(~kqmE1aLgWcnJR)KJe{#j5&?2V%jg@$JIGoTnwkrhfytlv(@ zdfYMtzCdOjD>hS>PS-4o61u}cwO^)!yww_mm6P$&;M^^}@Ad?b7QvGh#Xs&xEzVRs zueKMvpzR$^T1?coZb8SY37M1$fBVdNZx6FL+RaCDtUuN9%x)$GdmBn1a~cr({3E+m z7JK=Eywg_n;w)M_=`pkYRHxa85Pv!KD{EjUcRH`9UQO5KY$uhm1q@eN&Y$JEck*8P zI4H_}y*qY`2fw|op+yAVznL>lh`tZ6#WAa{YsBjHPFz;ePsGFcbhA6f8Au+Dtn1vG zV6{<43}o4j0nr`z)X+W_I2w%k;iK%K2t?$~t`DU}Fn}F9hY?%%#-b~CX({GKbhp-v zMFALOz}DUWs|Ll*CTvgv%vcnF0fM~-5HtX;wjO#vojNoBqur8zou0{anqm=uZl4xM zl2y!oDNG@vWBCkY#<*#1uCRKoJC!%hc?;ZySExHJ)V`qp9rUnBhCTNkzdfvZZYvfS z&bXn)&CQGMUibP-m1rOYE}-+Cn+@Koq#=%?>SudS_-L?TBs?=67gYvF%W8-PuDMbz z&fTdyZH=`mi$SA*XqJ_?ezS)gS@gCep#Z_V@d-VAjy zi{>PAkD21%cp_8d*L_%MY|UkGHyS{vqgglqrAZ_&7+lcfrwE4i5^g{L-!@-5%Zi-9 zYR2Dp*WaD7Fjx$Xc~2eLCdpW>iB2TWZ3TvLGtTD9yL;Tzkw+uPfK)XPZxv7geL^?G zgdtQ#gxyDX#VFOa(wz0_$XT?CMc2-clqtX{Cmb^8f}|PrlJwK9o8ecj&qC4A0q$Yj zX0=MUaImqI?K(5cxpp+eq#yj&q&TkKI@C0*@o`$KB=sUK6h_%F)fDF!kw1H{IOnm4 z_t{Qy;|a(LT`xQf_p(mmbR8A6K)LD@6YrXF#o2uP; zy95$Z@LbqqjOsN&@eVmh1a7)I$@uI*Hx=5WzA~C~xu+t0xMLA^-PsuIfsN_vGjw(L zCcBz>OgsoL*ZT&624NQp0I&CK70}u$m@ohPknFcv;X5sJ*#idc&TUcm$x7Em?;-YV z9_RwUK-0@YmZBGJ>A56%U6?&hbVf?ndl&kA^5|-unjI8$6Cw*m{@5V=t3t>%HWMKm zqJjtd2E$nvJzZ;@io|QnF2Qn<086Uq`Cx97Qb^81Fir1AkwSUjig4^^O}L83oCZ{f zCZ)@=M+HW63z8_7#>ewfHDjn~v}_tE4(qJZ+Cr}eK-CDqEi^y{?$XV&C1$0b1ol~= z_i6;BF9?(jGXigZ*oi%_9Mv`F>xT(pvp*MEpIwD=Qvdv5arz$!HDBwwhwNdyV(BF5 z@Bmu24`rZz&ImOZ8QAaHwtp5XszV6T8<@L8Y`8I*BLFhGkxFAKDUl_<4@?n<`%wfV z*?n9^V}}cIxh)kc4sImbe$`T$lX)1>G-}0^VU?MgG!INFfs=Dh5ET{YO3hp|h%94> zBATkMs|aAy8Y4m$-TW?X(_^Ly_=gxrj1Xwk|*!Y}4d zoE`hvcc4ng-$6fIpkh1_jg{nK>RyuSmkV{;A+OaKrfq*?p@soFCZq*Zjkom_q_Ma4 zV-Th!9#l)ZCng_a;8T8??G$t=Xla_&B~0dQGOnZzq1o(H#@pb{i5)-*RGS}r)5Tq} z_!OTc-fM~g(@sFe`e@|qAaL(mOki^d_ga8tgQq9H!Z-UAgv$S#Gp?c1(@UOA-%yT% zJX^%-3^fPEyf&NCWjki*xo~7;UuRx5B~MiyGLW;Hxqt=LKu!Y+_@{AqPMR_+sfz{2 z8@qE`%H2XsUqn=KyU2pQ?)U7deXOVK`mqzWy>ffnWS&@2&%YK7d1uuyZ)*;7x$$xT8B`n{MiS zPE2z{hrf44tFAJkk%;_nNPcj%xN;?%Z#;D;@PG@X>QY5dSHx^_%2SIck`(zQO_goh zzIfm&(lzo?2KB_ONWS$-6N4ySdX2Y6J0u%(^F>8mB!MQ2liu*Y^`=%41x>?+U3NNI zkzRLrj_;?*-I+=E#<7OPi^=*ZJ2Qq@bq#DZ?KBg?H0nPb{$i_bY`_?ot&=25^b)4E zZs4p7RSsePy+R_kGT_4+>3}wBp4Lpxs~p8#T}sMy=G-bOpPt8CJvPc(s9agu`&1NA)*>TfI1}beF6HgkCkn%63V-8sF0` z{TpF*$?t+OLfUgNFaN0{55aFY=TGwF#`mn1 z<5TcquN|E_j-;whPaS4I*;GLCk!g!I1;C>rS^Xt_#AW3AUnriPg@c< z9YI7oSIiuPO8c#6a$jNg6)dlah3)` z*s)yZdch?0N?Euu0}9m(`NQ?|3y9u%f5J`$eErhiDCQkyOCedjOXryZ*=hTV*iRWZ zWKSu7+{Q8Zjpj1`oniQ!8G_O^RUi^Smm3iS^ymCGQ1_fcEaO-c-}wxM(2~Oq(Q+yM z&m^ztb&MVvEiG&NIU`i&XkIpZhKrlx@F9b9s7)7H2T#wW)6QFfsb|bm- z51&bW>YJ2G?cs&a6=yNey^FO+Z*5%y`!;*$!Rh$D>qGT`a_NKsafkykI5VPMT3a`d zF49E(sdmTRk;JJ2=)eRDh-M2Lo@(tvGE_Wp$>yo@I{tQ1$Mn+CXomNf{U91!ihn<< zAA=KtB7no#n<2C9A2}kK29lJTwn+w@*vVZ0v&ueZdLPHgTd!q!>&Ez@r`DwC0g7Sc zzs>j6);wE=f7rD+)^9t`PfaAq{elu|v+Y^mrV-4^E7iL<5462j{gFMJ1Zj9T^_J}B z2ot%EQ2|F|@Uv>tHQ8i+JmyLP3@JfrRx0ro2JA(y;Qiu`~V;&DQSUotH%&NU~QQi(>cHbV}GO)w1 zt$XuM`Z|)lU7Yzs&u}Tqco2 z{y1Jzv{fXo9SNQXgV(Jlv=vMYU>4wgEHWfL$mudCi=Bnl{hJ{QmD!-2jf_5xv(qU* zmC#c@Z5Y~?1-+bnP-sW{6(F%K-onM!MK zaGTBgdk5;N1SD6Ri<LKfQ1j@Ne)uzLm0zOAf2FyLgchmm*jZ~-i4J@`x(#ey z_N8FKhli`nCG%CG`*w=c3A(WZ!=RN#Yw$zl1QiODC1D%%CAs8cXDhg(Z@ z?NUiOGxvKJtL_5=!_J?vuUu5QF!lGHJgkN#2`*X7r?nC*V~WLYjQRr5Scs*wWkt38 zb=(wp{MxmTHSB8_lc$>*ZR}7Uz2$GOrTvy1+mY#|vgt7`dxIM1j7e0sBi8L)lu`-` zXAqJaQypi{m4XB|y*ADXk#S*OFdnzT7onMb>FMJ!2CP#E{4k=-hw1`eHnPP&Oa3*@^tkP_&G+1^U=>Sz8NvseP*MJIm!D(zbkgBu^CzT^U$&Ouc0H zdy6J5yJfT1+2`f=QAmYp(SlR$o?2U;eFH*r401$h(|2C@uYcLp3$`(D9CDWG`-l5r zk-jy$9_Z4_gOuu$ruX`MRKe* z2{og3l~P$KAbW_{OhO*D71>7$Zuj^yM1sT92#SLbtf<`oEGdA{VUd=H8Is2tyg4I9 z;3x3C=;86T1U7F;HPWQR%oEJu%<)57y3*WTjeBrh0E20KP)$ODWJc-?&s{T8SK1rP zm!a(g;CP115YsrlI@7q3 zgkY2fY~%+9q&!?2QBxXSSja|-6p{=r89YKjh=AbflU9TAwo#4NjDqnuUM&DLZ;>ew zDZu22i5P}w>9~&Gvaq$-7}2O5plv2_aY!|ivAtDW zER($Is-<^-dyf&D%+e$?**1YRz<>Wipx*qbIDAw)mT*y%kC3s;J?2)dR$ojn>-_wy z+2MG4em=guoL`+rl}bg-6+juHks-X(DnIZbPQl?raI%qNHdL%@qe+MpQCe&v3UE)K z+`YQg4voFWM<{tVB3KLW|0uhXl&Z4zY%M^45^zHSwAvUiU5v4UNI%kQE$?BZel0z% za=uU_^mc%pCHDbX%NwpU%872)QqU+PLroubG)}DVwtPH| z8%;9x5S#ETN60sgy2?bzcSFLrOv2AK!k1FVsVI{alTZc6TXz&kv@NFfN^PY7K!Q*} zC#h5X4yM9mVevgzGgHOZxIkaG;j8r(S@0S8S!<4&JQ@rK#m z8BeJ#zGqMnD(qn2K@=Hx#dlQT+Z81B!unRsOX#TzfRv}wU0*x6`gyigzxul6tFO9x zx!uX(dK0V7NQQkU`i*M&hQx_(cqDOlUF5cUoJO<7>TcotjvG zq;*TmEzZdaun^fv7FjiD_1nT`NVQ(^$N3a#VLcEw+QS4Zr86lZsD*xF)aPg!kEPf$ zIKpvwRHcocTBdMGScv5coXP0AsZvXSS##C;)f?-^G>uTMuGRb7p#;VSO}eQS1*UY; z(eL_3xhigWv?_1Z+tdxoJLH6*q=-N?uEl4tLY))iZXgPjpeNVJ=L1d%YMb_e2O?w- zzqc=D7mRraD9_L@U5jbOI&SeT_D#+3C2=E(QSShw#r)O3m)Lm+<8~x;A4b-2wlns) z1YNVZf8h={JeMc_(m1)K5gR*pBRexRVqkip*(FZn;Ol*cho5bAXx=8J_3kLu`NjtE z!;Zr4U`+LuX*xT1R*0?~9j5df+tIOK3Xux#>jv?;4d^7sl!sUj_phY5$tCQJl-)5n zHC$qT%1iD`Gtx^KkSWSRlmDDFc!&h&j7uH4)l1?)hw?sr3h`9()Y;VHDXvc$pK@N~ zlOMlQ*Hg`1os+U#PpS~#&KOS(7?R^C8Oq1#DEB1NNFt47!jbpc0d6$1kVY1=kfoej zW$HC7!)pcyi~J|2;bRQ&Qh-yyeI9frraADj>V0_)@mi|p%4@4yW4M&{vH6gE?SJ5Z z>&^Q(fWEk^W0Y89i8a<(?X}O3V0g&gdufoMi6;82@%tF~7z1iAUYFV^&G996sEbwa z%WH_&Qax8*TlE^tp)_`7NHa$O$3HrowiHLnP~N9;z`-)6V(~HY zt>CS=@S}*F0`B9bhm3)vwh@bcaaT7cH{?>huVYb69u3Q5PW_nLvp`P0hH)^<8h*q; ziKYj9Ddcm6_x%&MWH{&Q*!3Z$CA7Mf)=N`eTKOd^LyUX;BOffe`^6CnNRe5l&=l;9 z$sHk|4(m}3xDN;jhmh2O!qru}ci_5J?GI7&wC%1oIga$4-tE5?#VRnB^_zKSOToEj z-NF$pj*mwuj12|AMPCaQjwWBCUWLN|YZ)FodtrRT&rBKd5WcNIlYR|9QJRU8dHH*T z8KbUWS-&XVCBJDq-^Jp3xsvKDiXySKPBlRfYsG3ZicMHSv6~O6S+CTpPJD?O#Zhck z3`L~3xjy2GA9{-y5;NZ`qo9htp@7QC-KgZ#-xW*pVL{gZST5y4B(%uCii8B1y6yZm z_t8Wfyt`6S4fBQe=zqc&M}i%3;8^q+EO+@ELf8J4AGuALfp`UMXvdJQ~5A%H$i2CWo0Y!*--2bRzuIP$rUFMY^j39-QviH`?q zI$KSTNq{awKl+FL6pKZ;vyB%%86LdKY@^Dk8}Px7!FbIN>W+@jo2Z0Q_aqge1S$PU z3mBh)CxH-LA7A}PoQ6T&iL>zsgopb+*uA5jKCY_c&hNS-^-DQAFt>v3`F&U=kCS;P z4dqbdGw9x!xO#YW7Dzvll|Z4P7js=SkS9Q?EE%%^7vq4@wgMgnUZ2OcCNW`{rZNWr z#SZ|8pWh0X^E}8=$o zU}g2j?i%0(iHX*9f(Vb6-G?@ZPOv#E-<0j!oSEhM_w5+f0T+ivo#n7k0 z>l=<|hf~dVNfVp}Mp`)p`MERV92IMMx2~Yx>({<$BDi}eyYG0g>b(=2Frq&Mco;5> z`uO2Ic?M1R;u+R~X>Xn!v_Y=LD67fwS~-467sYddDSymymp%*ceNmzk9`-%)mG zWdmQ$SMikr)u=>yMmC4Bt*K@v5ww5kpW#3i4_5OtN^9X5fgu~LLS<-r72t!;)H^k4BgF`CJ$0X=5c;C*NfIYh1HErQ#L)Xqz9YZj(gj(YU)E#PL zo=aZ=_+-WRCy<6JN@pW!C9?B#;>)DZ^JdO@glRSZ?}x-O4qr|_Un>4;BWdNyjITfL zIK;u>a-xUBzUhK_QV3HzK5;^119@|>T0et6612b2EP56w?0@rAn5g+|FDc}?gqL7@ zt5{JA^f$as{VL~3%xig;gCp#4(U=eK1J>UT9PyU&|BB+#DBKaJL$W;mSCp=kgTt<1?`G$aFv z1DOuMbTbfx#APes&$jZ?OF{0(Yi`VqYgOQS^mdwWNI=<&yL!cC`8lLXwHyY#OO|qY zUcJ5Ns2%o)f>PK$dn}>aL$X#+<5=p`WzLq-ONSB0el~?bFvbW*NResFqMT^?Lv75j zUt|OsqYYkRc3y#p!2Ml_?NM z9uRw#Xg$bT%5P#ajIzK)_S2ZV)7RTnPpqzpt^Vn8sjnfIJddxudt%5qe>4v*5@Y_? zH(gQoWT^fYuVv}eN7T6w=)NA&krXxvx3Pyb>Bulu_ihqzLOXuCLbRHS1>$6dT}113 za_KpZN2Z%%-U;Q!~=f=mhg(TLm`WoE?)3Ma|0j zfkMRjd_kqlstQ39^1R5wT?nB&{J2EV?s8q#1=u?wx`2^6V=QQuGBZ~*qlQ^4otd3v z$(HgCOny6o?NjF#>TN5T6^0pQIn8=wneV?s2G_U7kmvQN64&%X8FBWrJB&ndQn!gurHJ zwX{6lm{6Im$j=Cd@8!hDCA3y#q_pHIG`@;B8cQXnl4U{$Lr#g|(4uex7LmXwgWzF} z=ZWfb^|JbnnvIs{Ue~>^2WxgKAVw@xrR`K`m|8SjVvlJ^gFHPRMcGResv1+$TU#;` z>awj>fL^084T26UQf6&pbz^EqOG{e$+_4QK^Uqaj%F|{@;>Lee)aZ8Z|rRxo=XW;i^{U&4F&1KphyQte-5T#^;&l3wJ_xA zQjMvUD+%CO!bF;QQC9c%=7!ESxhDO65meK)<5d6Zy;GgJwR5cs9ehN=@a+-oP_j4% z=NJ@9k;Fv%f)eeGvC11`dg`g4ZqVg)DICO)ztQBU%ka^PVYr%Rq-#p@4eNUPA{M1~ zNA#gKM$|>2Q*K$)ljg&oi za&Z0fb5+{9G<&Ibt0)GiN$YKCNbHyJ^v#)oJ+2Q83e}J6*+FcODqDjZk}Z)9qE^cQ zdAAZJp;2fecFdmHvTO@oU174RJ_oEGOQWRb!O)H?GN#qp6%X{|pnhCm7$*aDTAgaV zq4fwHdTAI}>EP{0WlrF1BV9RO?3Myg-5i>&X<&`*%VlR7fE1O!dTny=Z$KghB#ndk zlHxtkYy2ptatDFIDLxm%4iFw!kpE3n?)~bl84{!w6-Md_$xTi7>*}!L+NPiadtQUR zZCj(Shwx>X^1zz}&53Y2)J9N*>AFj+lE4-DjvOOg1&8 z!y#3IoJ67t<6`0~+~-~nS)JHimX+R_4=f6=%YMqH3W4j`qm0((%dO2BkMxf?N)?N( zP;nlCPk)UW55~g}#_M+{z!!}vNFsQ{Loo#4WRctrXmn;Pc4^>I zNySi7ylClT7nh94A78%6Yz4T8u<}TnTE_(XX-xnem!6kYH}s`;D5)4<2+z>5+Lgrz zl*R4pl6~OtJhdIGSSiWvUh}DICWb7KqDwgMFsL{7~@s$=A ziSoQ`HHIFIavpV=t4fhDrSp;tGMY7o|e@2iut#O4%=+eaT8R`N}CXvXBAPG$(63CaV?;MhRytZC~I_Go5$9I&m#niuGWdHZjTs04XPxe6YhkS$5oI;2=;1X;oj6fDR$gu!=4$NvaJlwQeXW2cK%?rwLit?uce%IoJ(>X^o#1 zFUgt5Vo7eMmCj%NC%LUb%JuL_Qx;P#o59j0y9SU1i6W3ZPsI|3MdP1@_nnz#P> z86xnA2q!brExGWLfUFn+BsQm{!Hrghkt{Klpde6L;z+APxG^Qo%!fEJSpo18OD-cF zz(*%!6QB|wY@cx;{vO1T;3^Ow`ST%dTtJ@tEr}}$rn85P8^tn1=iKom`hg64z*n|@ z@AiM>T2-odD(ub6FI=g2EM*jN;i-y2&7h0RDh_W*do)wdgBR_ZE2ZZ!7s~0`K!_C> z{of)G%90$tt||jaR8&3*M_|&U9iVIN38eFa?QooLJa_I9<#XLEpR?Xlx>gzITm4@q zRtANw42j^=V!c*TgpnUHAqlQ-`)50#KwD_$Dw&ikm35_d$z)uaHar_2-6fU5(hM6# zjwXjT3@jR#ah9?CEw?K-XaX;48OpJ&5x_^6%a%*A;|lBKbp_ZQmgb8=6`OW+MFi6e2}p{ zhCn|ddvd0acW^Uk+D@rNdS_Cyypbcp{fWRv>X(s`j}6VOx!Bb`g_Or@Oem4UAx1Hz zMuAXfq(!m_Mj|`bJ@8KYoghz7F!GUNLlNaUzwmT-1)Ldzm|S)&ww!;IQ50smhY{Wp z8ZscpHp+8?IF*(P*&4B5TLT4M>EyOjy6@b>eYF*cHqhsy`-Ohm&jHNfGAh`3-i@jDm4Z4X{Gtd?5;r}iE>mJCrLi#z7w z&8>3J|AgsdH#F$6f``B8K^Yx_gA&B!AnUJibV*!up*Z z?|djv=ZLM;=J)alK4UrgV5Y^PqNMV!VsSVk>7m)MRl5pz8n9ZV%n}hYE^XUih}gy` z-yfx84&F21!jlg6J`pgjH@~$beG*l%M--ctifcwiv)QRZ3ARxma3ADX0Kki}4B4f7 zTV-3nU6T1$CMjCQju3R7T09Na;P0gI~!OUjPvope;wc5MWDcZK42NT0~vWkb*)J z(a7HXasJ&W>KiQE6CP?jm>-Q_kg5$!lVU$g09!Dw(Y1kLq!}1QvW6GxVp!T_M$Zym zpr!I2ohazBSFHz}i0c$8}v%py1u6Rb)kS@2-_g zVbjXa$N?W6CnTr>k|No;EFlXfT(g9vTQhoUL=NtKR(m^5sCit!cvxRlvI~3F5BI$o z#?d&%e^KCufeD#bT%D*d$koP1syE)?=LnOlYR&%hBqRh=DrYgJYB~uDCa?r#B7;dF zazwNsPajh@Y9bmrC1{)mL}2h zWSNP&NH1!HG!QXAS`;T&lOs5kuU0|DI)Q#!CF+NTfshsIeUZg4Qme^kOeNf1$Y|&9 zw2*}BgU}H=-NMM2$>?CFcSuZ<;EFmEbWR1mxiufmrlUtamLg{_Dcyx(i+*FFL@Gh* z4nk?cTwi7qlqf8xuQrnbS+#C|Z@8V8GOHQwi8CuK z{Z!a`P5@7=Ih$P5K9rTw*;ig%*B8%w=ocu!&lNDPwQKS>A)3QJ#MvXQ>cp@+JbdY7 zZD45Eq9L2VK|k5=nQ3W6u>Qul{38Z{>&i?!xx@)fli;DBb|aG5{M`s zO$=4yAwgqo-h<)b6>-hNjD9g5J_!30bQkv+7CAyw7>3&{)DOU&fK&5iVM~adrx+vN z%O+L&NW8{DRtc}DBBNlJp_m6>USYM3=U_0j@m@W32SIT}9TeT&l} zX3nC>7(KEBHmH%U){J3&Bn&eATDdqT3%PjM4A>hNPgkT*uMY;tC#s7I)Br366XCja zB<8Q=;1b3Xp+-n!(6(47$=L%w$><4mrXxHxfl5$k&&CflcS?NBHQq!z9GR236-eoY zX?;UMyvS0g9^U<{JW`@&P%MmzE`gG12NBx^>-7r`sfJ|hDoqL}B96;Y5GbX@{AW?+wUn!Q)_1P7uFOM5?YER;oC`os>E*wrysY$)2s)Gq z*|UWkxu_M_HaiEw{h6>dGDbN2TNpiTo_<~s<=ON5ruPZ*K^Jrdb%DHW1*7kwVbo8t zkB5%=Z*K!hmC~x3$#yD&B+O968HzMSxOnKE2v6a(SJr3|6S%h+l0SWbL9# z9f~pf0a}ratAxMw7igHvnuthim&%-zR_!Ii+KoIR4BSv6QZxHMrvu-;7ni;ZmYg-P z-05=&FzNNzcqFyU(SuX6l8639vAG`p&~r@Ea=Ozevqis-=V4T}s8-k3C#>3)`1p#~ z<5KX76g)*g>r|HFRQ8-W8JK6s(?@vZsA5ZK{1PhbmK&LHu5C)Oz^ifzo8u@>0nyph zCBiwALBNakI^l^q)iWx<=vZ+v!Zz8OB(k7Ud}UXfVwE#8W-_+2=E$-dhA_Jqb~ATU zknx0JuOdKn=AyAa3*%tc@^N6iir+$iQ{g^SG+nR981^H%;Y;k%EH3&Klm#c%^&lrol5MLNl^2w2Oux^HwMA1HUSt)ay)QvTaXLET_Df+3D-% z*|Ur5P_(6RO6NjVNXwdfK3B4V!j|CeDJJCJcobI1FZ{{q#r!Pd7lna_pZt_XWT#xz z#BUOEOh#xEx5=(kXW&+qWGjgPVsKcC#2O-m{-JG#Z5zCeMc!efBB zKd~@NL^3+=K4 zo8o*$2ai%H^No7}wZ_c7u<$GWlTvmqZS_OiC*?|inNXRvcRnF?82V5deK*cxuMr)C z`q(ag@1e?<@g+983`n|5I?q253?UO((#6PjH+>BY1c?IhdWIPHxHa23cx!l)mrP2A zA%^O(HKw9nP-oI+IhRGtqvGy$8rfs-1BgoxFz%A}vUrgmC#kG+9KUlwpJc|_=Tq{! z9u>j5EhTLXB!Mf%>$7zLX-kl;)d#}p6^hzgf)sAqJt&HlNIvJ26qmoUYGwM;0<&z8 z9jv`C>wvREW$TmX^&WkI<@1uhf;$Y}A-k`=5pD;W3#w80SyDt+y`R`2iTn2K()Uj; ztadC`3IURKntP@EwX@-6L`pfbpkQTjYK8%thKetuTQQq4=3Yy~yEsH3J1-mJ$V!)j z5DOE&umF4f#<)H|DBtV&GD(8}lmD|9T$1WPS$}sgm-aiI`U?emojlFHdf6QmwpjUR zGxv=vh3RkW-y*-i0-S)Iuw!2`%jPEAUD90|h21gpi}nkbV;ozpTRo=I$NkbOjC-CK z9}^v{(RGA{$Tkhheik)GIEK}lYgT_k=eMGs9!C*Z9!-~*?)j9{qg&a2bIW>I*7tzh zkvL`~I^cY?l&>Q4qJlAEJT-(B9k?Nfi2u`^Sz;Bw3nco|)7ziOpNso!SRnmI&;{ic_gH7re2ingJ^O(=qjKe#7m zL3C-Cya`@`!_mJEzAsTPOWDeP{Gp#hmM1nx`n(i~1Lot_EF3$a^mTnM%sE!YU zFYEU-{B^?b2N1edC*dvA57o1_JAtZIPzjVROX87Zlq^=cv|5tDr(~@|jI8u1@!hK4 z?m|@BuPmNZl`UsM@%%aP9)=(~DJR@<`VG=>%`BNMDUUHKyfXP+=vBRpRoB2ygO#7= zQB~8*%3Vgr_f#S8Eat4n@4M%DHYHm}Yfq zUSWju59*aiv)Tu0s@r?BZ20AtTJhY9wiOfjl^&6dHS1qi!7pu!q>v+2Hy5>6Y)Q30 zt~!zESUgz1DLN%)~8gm8-8XE7O{z^T2?u z+$R<8lPVWzhFX?U%T&~grAc9>XrwRUs^%)e(K`rRk`z-a(xuB=?u#tbJQ_JJoWq%I zWPyv-@$1 zE5Nl7GlX2Lbs>y2;^b_mK+hfrlLh-T*wR_*W6Vb6Y@bL%;ADo-*;#51o^lQ5czQ&? zeE0txk$>6Bk+bFVTM>hL*G$MJy4CoACxI?P7k0V4m4(-f1snow2JF78ryIf-v`F%v zHP_~%t-%eBbTzOd(JR0Nha+7*UEXAg_)>eoCmwtEX(`wy9S{NRlJ3yfL%8a0kx9?Y zl5ix}n zA(Q?pz(pG1O5JYa6D2``!ianmoGu`VGxMAV0i6%eDG=obbz{5@Oyl010lc^w8I!Ay z0qv*a=DQe{i+mMW?9rVH3~qK!apV2{L_q!uIs`d!9|pLwW^1Af&Gia+%Vt3;QobeaX^NpeGNSvbeJ~cUV-z8@VN%SpW|zc zhCPakyb?{|vSR2g{`|f>C}Vvrj9`gGz;M7pYD$PrFwsoLSfdFX+7kOb796c5+#}pg z=~O^^Gb7nYttcqUoU>tIdy`+7;qu+W&rCsr({>KzKnr0M`grI;>TY+@9QV^ct3l?z z@-iRT;hb+dzGGKG2c7Ut4aI^l>JxXU)mf|2)LPhf3M)d*sdXkl!a4VFiM8MYwraFXq3ehJ$1e-~%kq3$|KnOY6Yx9YD-tON>c$At4KM6W8CwNG+4 zy-K{;juaF~3ESXk9|_Rot%+5c@uQ7xlD3}Mh!8iSBpbDS-P&igg`s3Nm4Ihc$f47h zV}~4oeLFYSt*omn+2iN#aB=$h*-E?F97|6JXPbXam-|jyV={{%p{#Wg`V~f>+P%o7 zDux?w1+%jE1p93ns>B7V1V)@PfiF-dB-6N?<43q7@xr|0W7>(a?9ak3J}#1_Nfhu^ z@vJB=E}MT08@M7o@+>+W1T8AQF8l4iN|;tZ2MtgTlPuD4q^b3WAXyBA(0 z&s&|C;|U!iOYzn{r`mDag20j0a%6;=ThV9R^!409b4}y3HJ!9dzDVYkgkv}ffMmyNGB?^^Wfa;&GU7)&`q^G zJE>{(;z0k%rG~ll^voQ&yJtVpj9FzEDOx=Vm*S`Z}n5^+PT-0SP=3)t9s zoOCCyBXyC$^W6_LA6&+zZ*J1FDI7SMbDEk+Znd`RXzI@)E|*PF7VenZ);sS|X=-an zW@=5#_g7p^LL6Og;Bb}3dX*l`8GDS$f8+0ocBcTwQy{{nN6Mi1uXVCj%Db*IT!JU``eu;jE=*6z0FB4olveW1PeuX=u|NqpTyq)|cQ&*CSzY|bDu#JU^n-yRX z?Ug}iUM zf_pbV)V0)1YKNih8%4koT`U$*L{eQYqFC*`Svo6xXeb=vAM1aczMnrtIEepOv$;?) zjvV(1sgIR?XQ_3K*bD2s;(Kyy+r;T6e+RvS1lFSKt0}R%V?B8A=sT(^S3Es*!}`{P z>U%%&S-D~wx?z2^lx5TSqTcu4_eF*I2P^vkPyo^9C&~{Tn~I+&6rQ4>e#qQ=K2UHH z>$jd*G73#V*XR5=`Y!SKt1-mdA6Uo4eS~U456+7SOJ5tXRA-xC@o1JN5BjNZ322MO zkEz2#%5bZAFtlRwL;;c+?d$yyMMt>D?G!Paz&f(6QG`$iNKyQHA3SQLVZZK(@wVt% z8i-S?8!C=O&aJ)Wa4{5?e$ESQ@?++>4+b0cR=CGf> zyM}+v>hSIdp@O=kMa?DOH1YTQ{|X~mLj z`eK(<=1~dMzP`>fi3E~VLCie7uQJ$N_N#QGsQg#i9dX$Y(GTElqUmdEcWgGHrxgzk zJ#zS#xNVzSJvF6LnV&4Mh*{p9^}}pTy>ZcbIk1QURu~Pi!T<}?a?Nt*8y8c}#;hMe z8>w?m`-Fp@b!ZFAf29$@BdDcZgSiQ1l`!7OoL=1Pw>&W^C0+qZbMpJa6n#{XDwxom zWXB095sC=PwmGBI314we56x{yqNG{NMAWW&#yR7BrYh zac&#H3+6(cBVF&gSt;yrJRTU3t7?=?)_2jM!GPXyvCj>Egk2Cu3j^M76P`^)N;-G| zld_;!`xQ%QO8{10e7hDabe%%qXs$YU`SM&fH`-U&sROsq*u z9EVB3(?Hw@@&_O1@$muRQD!oBIUXP{lh6_b(%U0=J}zyJBJvh4noaN^&I$JL`tFVn z#pTRVM}LnY@JNDxE5&JR#c7q2^wp!0{19$ANAuUGyjU}Nas6V7nbKF^$Le>c_n)!p zcuRab*6VoD{;Uy}s7h4D%-U3ZfTiqEbpT?qc?#c~*p6?{>BYm3li5f-Q$^qDSo%pp zTujD4!BmWC%B85xH{QBpWAb=8&1%y)*d)c3Z;9CA&L@SM z8=^Lc^OZuAQfY=F!)#G`Q!BuRn>$ z!mebp)1*pq1`Ru%O=dsS!N$(W!Fk$WQQ#_{JapT3=OZMHm zO_pAtF53nIpV^pf?anCI^PZdXN6`sU3xXp_ton+HmwN$dUWhUN97l)9AYnneA-*hI zqz&az(r;tEKi{{<_5qDM5yA}VZS8T*Pn@SRs6<$Tn=RFj6ru( zM$^v3@kB2}i)aso<)49Xe+t!>AV<)ci^tDUfXyQg7&-t>8zD7u6~zV-TF`W3OXJfe z4KU|4uSz(lW}9o5yZn?&ph8UF8qZF35zBDBoQ2Q8&Qr4Pk_gK5#9-XGqU14>Rwa>Z zI3>H56F=sn*Z^BPw2Fvs(}(W90}DY;I?F)Lau$Jpw)|;h{Aa4^r+t;fr{(bU0v4?I zWj|u+{T^Bsv@d9o#5M$9!9L2^IKqhedel9Djt8csV?f(*$EHUb89(i!hYl*7x0cek z8Py?G;#+g++hUdEwJ}r7VAU~$Jfttcg<@>wi014^&VQiX09{i(f>=FYj4dFr1pOqN zpiEJ&8L3!<))lPv4id8~%cLY@EAg@_NI8(rtRyCdjm8aJ43Bk-110a zwFREs)?ECnt*gsGbZhj$ZtJf8H1I`)hFt?>19{-2;baCfKoGJIod{Kh!a|QjD;0^0 zoeVy_QX-95xcw_mUx0NYK(|S0L>je#ua)-pH!X+)!i%ViMQv@kI1aE6Q1APTq7G97 zi+DlOkhQee*>qV9J$QIt4$J4OuZ+bDq1DFig%SGESz(+;Z@podHoPyuA(Yooeb`6cFh;9d7}yCK?c7X7mr>T< zI4SEC9`4Q=tHAEsnycDcr@b1C!PGULo>B9=;%ZJ6NP*b?t5)KMG-94{wWcrFnYW># z3RAvHM=QQCqib%+52~&v43&@kGK#*?ihSJ0kZoIiA=L|QoQh+;_j>HoE|8sG8yc%H z8h`*n_T5nRXV~viKV{R8ot=bo%4{&GGIj>BM37W|U`vWcdjbpmqI zaBn)UPd`D7@-i;!26+g0=OGZbI1b42&(DCgr%nw|0Wy0i8ixBGP*7yp8QRD8@uNW1 z&cv@@H_^kS(5WecHHm%r;e*6l*+)1z@2PHa--q|_=ZG9kha!RyY{-))VfXCe+NP#H zZGJaXTA3k}`9qLpR7z(Oq~F_e6&|MdjJ=c2OppKbK9cRMJ4@9;A;;JJ%} zO@n=h^J?cW+gjaH-CfYUWEsAHeMWVD^Rn@y70X+DySII3(Q_{to!9~G!t8>K5*;1|_h(e+? zoiNs7FK{8L1=2~Up2JM8{FoeD0dLwIBen~gy9*6U;+rg*-9jy#w1uRk)K&sxtnH-K zq}0^xtaNF<($u8XQ%^aZaE9&8yj2(WZ{E%edpvLXd{yi6+%a>XT{>l`(N;)lqiofZ zt`e!3lAMD=SAl+Ceo$Jx(<(86?Ey!4W-dXwHAgb9Z43N}B^Gj6Mdch@K#t(qW)s z5EX%jK^I?DK2P*jP(6;M4f1e8+@HZwL>xq5fzKm^cTQfj^YJ3{0qzEQrRRt@V1dswLn^c@ zAYCOdGM^_$ywYjJBfdV>v~g?>ZHDe)d2oN2M>*mlLOt-bGJJ2z1OBE^DOWu$KQ3AL zj#1c($1M9XV}hsr_M7TJJFeZPnbvFuiEXFeP7^Ftbae8@$G1RRYQ~$m;`ZW!-H8o? ze^lnKt0rDeUL82X2fd>cRS9nCKhxkhqRo-j3)0dyyMh_Z+7qPMxrw%Cqgz@uPZZOb zt)nk_hpmRM*!08RLFU}_FS2^ML2~z`aPA4F=zxhmXG>A5N`yqfbP4|)mQevP_6Q7^~3;;VA`A|NFGQhT_;{!n>?eHPYqE!wy4sh#~ ze4G4f91MI2+>cLF$Tu(^r;ryG$}b*v1Nlgqthhuf>#7>8;&Q9LLPbU9>P$d3rE*2y z7^3JiE>%{i9?2#qdJ_Y1(J=mg2L{Ht7aDgDhQXTIj5{#;9gZ1o4Ch0hm`HJbgaqS3 zjtSQv5BsQ?iJruu#xG%qHECOS=2o5+m25y3a^UT5lQ>M!bh z>QmyiUwuEht*NmI1QNly##!Xtygo0?Q;i4wU}_zbFoeZutE?RMve2cv%8uF25#v1w z8SV_aen<^#!_v?>=_fIsNi*Gv+(a4?UqsPhwi~eNZEjE=7N|oM3Xu$r#iD%}S3rS9 zXhwNV?QWl!nj&jX%LFYr_FRTI2rDEQ$w2goB%&1PB%*m(vp{oRGp^ayuApetZvIK< zrZ=bi(_N|hW9`UJJwA}*twftF^f~$weV=||*lKi_ui>Ufd{Q&uw;M~m=81nC6+80I$3gbX9!`)Xh>oxjz5=p6n}*Sz7Btg zU&BvZcBMmQIl#SPg5i9_X2VeDP57tIr`_!PY&$pX9gFdg46p=P03Ha|yB;AH zY)t}ZD?|~mA<_?}E7Dn_ouMUaL$uy- zeiKi{pBng{;q;|5EV{krSehMZn|bLFgmma2j-=*{Kju1ZNyg_En29(1i$Z*%Rfas9 zZ(X3su?DJr$`U49TeeG6#%6&=FNy_9?q#$C69399GnlZsOQ%55m3(l#{s0gJ&TIM9!jm$C)$uu)a{ zD~8NYh>}=u+aaV=YN9Bw6-we=_am@aEA=81E26v%e3u94Ma_UZnG{9b4(_5T;}Urx za7|5rLbRFSFfPMUh}Rk_Z4Xrz6O=`>onS17UFr?l&6Z9$Zrf-1MMxHTe6a4_{BnFP2;A?l>20;xUPWY=uEr$6)#Lja>ak zLJ$)bgww>u26KGT_;|4IeOQ!PJ=`ZP9yWUkRL+TO=KS@Pag7%-Aw^%cqOhQ9r9O?6 zte3MY<=LyTpiBy2sXxXd+ma-tHc|yC=jhCnL@AHXuL(}Fs0p*qOSk?2 z4{~)sbrU)--TGrMd7ZkaW5qH8SoekVLZGm%>s8yG;a+gj?)D=Ot^zxBx~Q#@Z2XsN z-8+`v*RAdtp=H~Vr)5rOq*fM?3boSj%E&e&(?_*K&-cq&wH;-etO5lM#pHv| zdB?32kPwNNm88CZ|Fn0qytBg5f3t95f4m)m)Lc6tVe6FRh7eR!14=!aX*RRK%y~28 z$gcgS*4QcMvl?gg85auHUa|^gT-pM?Jz=t(Mh<5RjayOW*JJLP}Xgu1kGd?RJme+`D;^n*k29h}0{lUA$ zo5dr4EZ*0>mC#lQE;rgNPEeXBI`<9CfJ^{T@TxW@2x5>O`g%yoRbEWn_!%!ILm)^e zy_UGr#V>Ck5(|#hi+jT>&WNAbcf~IO#?)1DWL*Z-8r`-Jnu>0NLw;4S%A7!UffDTq z*}14aM+oVSGt1$~T%N#;qcY$E@E70;%!vIX6PqIPS_|Ml;0nNj9~VEFonL~sHi6?d z<88aPCCZxD##T zPL?(9q@(fD)Xcq?CZTa3WexWB@-MI>DGIW)^}F3Rk~w5&=r?i>P!?oo<2RCjx6~J= z%l5(oc?^Tx6G2p!g#;(UT9dR!OY;sv*Vxfc@kV&*#1|Juw6wU1lecV17Q3l-ty!ac zSwG7;0ZMSbcTZo_N(DaPO;JDaSSL}XlY9TaK=PIzOH}FPGyBb|7wPFMLgrffA#{F` z)>8KHnX>o^KSJlmEOm`DqJUK_#k1eD0=CTDcYe+Z052lB5 z@X5OTSNHs;$bzABvl2)N&zyNA<;msgf2}BJYHV89)Re_d3TZjE5(BqHgm&cAqVn)$ zExVoLJsgHlbx%ywaRa&6@pHKE^Q#>2HvBlg7avisXe%94Mve@q0@{G%z+PY^9A9UE zaF$6eRnJ#9sPn>YYa7?*{{9owQ6s?5&TGDkQSBOhO!8XSa{_4uNpu zMQO_ZHgPg>B8Pi4CrGJ=v_C}6;f`;?qP7SYX1OuoZ9r>)OOGl2Dm5QSdrt(N6;~Gq zmQ)HQK`WqnP}QGk^YafU8mk*jDebLio7=N$lRJBFrR}b%Rcf0Rnp%~X8J8xuyw9KH zYsA4GQ_neTQ0X}U<&JtaU^Ih%%NfWPSeTIE+oEt>b}oxUz5cPMNp9-5=&;(67(+4D-ek9oiuOYrM(3aZhH?il_VikoN?YGf z$UkG8#sIXvWDi(b%)3~XQm6wOgSJ6KNY4@bn>*~_K_*0_4w&?XyMalUJ6Gd{)xaVi z)sZHqHPcFHsbjab)V)U4QY{d16ioD7FL!}X9F;&s$xBi=Gc+8Ww@+7;SKJE(hZzp~H^jwXZ3$-9c9dze3KVoFCjWY@!Mky^snQItDrSJ~ zJq0=n&8FsP;1cK>(DX2g+c77aV!Ev<>j0cT6_?G)PXKJcyA#Hk47dbX0sjEcEE8&! zVwvsUu*UEL!;OaX!$9|Uo0u1r;<;F5Lj)M z`K0wOoLlpPFDca1T9d+>`pspep14Qr)H2a=lg)p4s`!uL>rpJech~TGJnT zR{u7(CpTZEEGZ*rt!(|{vHKM!!{tHGeH-q=?sr2k@B zb#8wmg2m7xzUk9Hi!pTLmGMWup+H)hlN&Dt3~JPwO09jwjARMknb0kTV-Uk?wTM(H zbn=d+e5U%;&hycFis3n@nhQ@Wl-oS?#TJ2pMVUbN#|P5NuZQn`nw#{PdLl0PAAXXd z5zXb9n**~Y=wJ|W${AXbi{z=f(k`h@N5 zJpK%Q{w}gSJ&D~JqX78_T~zpS*3(PR>dfV)z37AUz594C^FzD0NAFbXa4NsI*dhYQ z=I2gHwsP}XwRF~s+HU6GuhMs)a|$BaxL9?Hjg}vn2+yR+as0HL;s_B6@xmuIHPb&c z+s#y3*jDKHY+tF{R&@ukINlb>Ep+A=D|77VE zV46ghxCcjHnThvaSHr_yg zMs*zV8*z3Rd8~mTYUs>)pQ-!!C;$93A_Gxs;TAd!>KLJWA}S-q_)s}k`A{5aImxU( zBYCP}r0h5V)j)8Z(RVXExsxkU^^;n@ghE=lcZ5oB_ zFhINO97u8A&p-rfIrWet(ztnVg3I>jC~W_!gp)b3PaxS5!RF%3rh%VTa4FI zsV23~Vt=3;vKmVcaUFz@KS*Z^IS$Ausvp-4XOMua2`%7T9$kmH(JPbSFUb2VLev9- zm{k}kSZ^Gm`~kFtZrM*dNG)vU1%1N`WU*EpijE5DOkKb^Doj117$(KeYv)oJkQAa= zpm9P3JuXrP{)(cH(4X?Shuc%R%3e2pC9z(w_2E-nRu?{N5MjUlZt`hEf48|qY)6qd zn&2(J(-2`QJg#o2wY|T1F26$|m_yCd-~46y<~nYW7G=gj^=GDK%=lSei*bo9U-_l8 zvl$XVr(2GF!7ux;p>#1D1{7S~$qC1@VwLf2h>42)F5 zDG1hsw#=PVV4S(y$MD5!yrW5Z6ET)XWIvtYO>4;@RSBTTb8yYE+>55rAMTu$b+`g3 z0+W}3l5a05P`+|%z4ks~+NXRvWMta(Dr=)j8zp?$2dn7xDzSF@Wv?|DKr&1?5DZbC z@+=3x;=qzD=2!MOe<9-KgNfm&AuP~$qvhjD~SyPBv>F;yh$>9GEy z@3QsaGLVT3o9MZ0o^kRp&c|-1dGqJi8OYMA6d=n+dP^!m&4H)$#s6HpaL-zWV_8_U zfe-6yhCcrdc}z~f+q-bgVDkz3y0f&t`Twa3i3MVMu1}8CfBfA07R%s z)(gBMc!v$ZLTJt;aXqXrQ^Zjp%9v}2;Zj4%`T9YJ4$TsgnpDBJc~~t%(|s+NnPHx% z>%Mo8?6i;O^>p_p#;LWXspN-KjiRetvV>JrWkZiLuD&iiir}b&dW=L+o&IY1?)bVI zjmUcG*uax#!OI1zntZ~S8NYra8yAtRw;9dvY`Rid%D`kYmWS?7pjN&%+92EI4FE0D z@-c@ckO%08{r#(U0`8vD=BDl3hGzbxW7`yL#PT!L;G=k=MZ(#3fsgsE z;#%4>Dn|_A8U1H{z+P}flk#~q2*_19qa2!^o|bNcrXP~z6gy0hn;d=(?7SM1j=aZ6 zI-H3d$#%S>Kdd~lZQdfdgT-PSMjn=J>85}iXSp*{DJ9x2KNAMo-63rJM9xLY#EWEy z+-cKCWoC+Ke<4&Tc&T2u;Q#G}$CfNb?W7^8!&vT^RpP5&{fHo7ZpWm;R4ET2NG$cD zDSYs_G^f3BGG>FV2XJA(6~%oCPX|{_^<<5wNiKHCz^1%7x0AaqCKU_lD!{^=iqnQmf%L0*KPq zy>y#vlIU3`Hl`6AeAA}m)zG}8e|7sw9?5`>MGbq z9_(`0^jY)$pAkpQ1-0U`4S!e?31D6acc(EQ52}l|Os!=DLDA{It@!2Usjs-G$%w;Y zwlJiO018WN7b5S9w;4u)>M8I6^XLIHa~Tz}9^+=PlU_JG`&C?>?_igg@*qo(yk=w!eD}BwK$q0S@)dVZ0AFl`YSiA$Rj5{L|o6{+q<; zmHCXW&$h>lY>DsK=Y}}^+=lk5@$fmqG~ybPP1Gw7@S<*-dLm=Er5DNg5|DQVD6X0{cTB{!Ll&% z1IxX<}oR>^bd|sj(c3ccx~rRx4Qci=8UO)WBA1O1 zI$Yf3JD-rhETvj0mq6g4u~W0qe=x_@<|k&R<|bz)dU*whL9DcNDbovvMHdyw{})8O zh;enTV6u(#+F6?S;aly#9E4%qyw0Qk1Y4Qa``0#d5M`|-Ln5R4?ES}5=?W9=7<>Q@ zwGQHY+(af)wuZPOqootHlHt>fhbO%Mk4|19!Kq_|mI}c~klGq~@L>JKz-UPy@PCbRylqOt5J?BL^xji}=Yrh+hCEzG9kct>GK?)^(-VF}A2Q!!9l5wD}uZkZM+; zj((EHYJ;9=)O6JU;039!ovxzQ-!}BYC~MDb^>({m*ZvRW>gEMNUZ_6(+FAOK_DCn6 z$fLHX-c|xCt!||2XV08HpSvBnzA1jW>IdH-`e8)9VQu1YM!yrYh9y+~H=W3?9fR*m z1LqA<82A|>Wv&|W>)FN5@5}tJlG!a)ll`*%g~4xUOhJZb%=2V6SVuB{704Emh-3Oy zRnz6>Kcq-{^4bDdcO*+6>T^lGhjn=!n-m(JWuy|HAfncx$;{CuqmO#N$Fq$|(C< znA#XyncEpz?qUOi+;$57%G8Cv4-H`ks=@LFoM}uvp~HWtRZq^NsQ`cqJDEskySe{2 zUnC}K!ZA)y5g!861+UlFp^(*0=ay~>JIY!Hv^AIM0~DIb=+4?}Hql#&_<)LM^jUCP z4aYRVju>Ma0YMkj0c-u8=&Ir|Uk<41TZyK(?5Un^i$dP=LAIYNY$A#bEVPnfkWf%x z(MC(f#Uv!oKKG$nMdbHR(oDm3)JWw?)=K+RKu`Ww!c^U5#8CNB#!{`aELNu^du2L-(&3Q4@g|B?z_^!96*dr>{tG5SWAXnA|IJ#B+o2}qapjTY}b;c zhZ>GjDWy$$bjHF$IOwqIMsq)YV0oZsF-s!j(*H+V$X+KwGnS?dpoxBrTNt`G3)Yjd zCwP-~(b0h9X|nx^g1JnjfA9XKc)G&Uin}rqJ1mV;17QMHscCs|l(Y7kfq_gCf7tI# z?rjHP5>USK*tfw#G{rA|FUlru=jStOk1MH3Tk^}4Cfcfy-xH;Gt>bA&jmFH|1JoaC zoDUK}SKt>#S{J#13n7=&8R_+?=HjR53)@xPy@Q~}@3?F4HBHe!ADwX^A6liJ zq94mtyzjlmX_B5?qkUE>xj+f=kf@eB7c5y5Nb)7PU4xlUII_{y<_wc1zT=PS@c05P z0Al>we-b!gf#Ud$O`GaH?pgf;@5fHA_zI+qEpsz{_o-|l3BJt?D$mv%GTRXo%z;un zzeM@<8y8XA()T@@c?SD18ru5ci$P8#t_7-!Y3%?-sYI@}=Y3z8q6#MA4IIG$_GVk{ zRIj0{@~rOlePND~>p%iK16`U8NAj>{ozQG`!4_A$jpUyM*+d?zGUh>Fd)NAgfS|bw zk!#6*_0%NC(;;46lM^+Hz~3slr@cep>fmW=UWUsjIdFsORG0~e7U}iv#Cg@rKO>Z9 zN64bumy`gl+z`D^KII$m$z>6Fv^HYc#*-+~Y0;!c2X>BiwPCt0??;*|(3UOY8kRAxX!jb%`7~QrwgKec+(>wB>AP$zosb4Sq zrLVMfR6*gFM)m9zezqqHFlNysL+f!JFnW)H1a4Dsr|96v$YVhrLshdVWI3Bg{TM;Z zp2q#?AM_I&lR8?PT13pt#nu^+RwnWa7`lpnVA z9Gk8Z!1Ph7VS)9C@zaMbI-?fIc7;r?L(pAqLa80(#|6o*e3x8E5iP5;n_x~^P{eJ% zvOP!RJMNtR6^uxG)3zJv(bJ2q_{D809 zwFbuTpTY~c0HG)q|2ZCrg%BQY(*!EHf1Qke2-ri-aq_?tJI;SJ7434=2#`!u z`4z0b^yY!_Kg>}7HVgjCjCOWP6m>xoO$KmTAk;EbeM3+Tqt)O@ZRn|%~=iJcqs zb0fp@bnn*dTopEvqxjq3u}~{(Jd3a8wy$Yc_gjaYCrGHD)$+?KtFF$$CN<4M^V_OG z-@(&VIFILVBijlw!oXAcns0A}$CnQz`ha-&T=&s^Cu{M+k-DUz#~@!xLhOmbZ3 zJX{7OE$)l5L>d(`Mq=KW%>Otl#Vk#-Teq1I|7rM-E4*t1j5~&rI3Yfl`rqM;{cjc9 z0RL7I_;0i4f0+OB{dcenxIF%cb_V}c_n3H{F}%!q)IDlAw95GuQV76PIz6~%ui1e? z`K$3QI{W97o{%T)@cs20UY90%@+Vyj8(*KSz~%FKiYl@}H_f}wg8_65nC}NTGAI&H z-S@}04f2!``C;kX?yjFh$9(o@#3d7`RA;$npT}6u&2>`l4FL!NgjHmHY#8h)5^s;{ zY>f~@yoP-oMXK^Z49W7ARnvzJVN~HKqhC1*O*qn{e(+>w&pVFog86@Yi{wDwxB}3a zQj?W0KpakpBNL?@N6AQcsZ~a?d5YQM#)|OxW6$AhPT_@CTtzxEo_D0HrgkmZ=} z!ZJPjfcnSH0}LosCYAkO+lv@|i^0?S$uEX!a`w?t5cHtG6HQ%%fEw*otSac;U$ z-F%ROwWJVH@~iLS1cb9MZ}`i&rmjICCzID%)ebVwb&Sh9o{FlwJT7Z|{F!X=OX4Yi%J@hS6C-Nh#_I~SjA8WsVA zQW60GfPwB7GUpY0cZz6Iuw_GYUU_uFt<=7?7-^WCoh_>sT2yG@7f<4j`ta|G7kU;yrY?+3ckT6_tXK@5DjYzziYDcl ztAit(orm_IK)fZw-?_anx@Mu_dP@1w;4OG*?dO&(J6f!H@To0%A%d65wOA~X}Krb7Dp%IV#b`8g+qmSjvNm*yHetR8oF7u9ajbjzc@+S)d2YU@5 zt!_i?eJL=5Xj?Z#Hg9~h@64TLmza`+Gc9toW7wxieaq0d^p76cU3Dpy*&$w@4F*{(l93&zZZfJ;6UC;<7lZc9?BAUb+HbnXy} zZLSx{`2aSFsoMQooOS^2QrDl5Mu@6O&vcLp5aQNlJ~BRSldBJe?#3;`F*TGJSq_n z#N#hSIH4ENLrHRCDQ8-CyQLl9XXHjQHZd7aiSDp`mNh&)xIh}V47I>O2nvERZX;Ye zWvw3Qr%@@4NR-rs=PcrLNf>D9Gdy0XIYt^r+1%I|h@Z}RLtS!nlD?t{brQNO?%$vQ z!;_LE8%>AH%!WzjIU5|Z%jyJocne7=AfyYh4-E(9u7BYkzU{z(Jy> z4t_wVR~-tjK}v3CVO$9PrK|2nwEDe2iQt}XtnMYS;CZcPg}=GYI>`&@>EWepP9zpD z%_5FV$$-Y-G{@xVDm7vVr*fv6iCJwKNbmtwK}2KuOoYenhb3vV0Ljbb>1Zqoz?d@R*ufvJmk>KTV@w8c=Z*%REfhY1AXW2rv zc2n9&@HsDYfOcfE+x%-OV}UPN*`0NTEPOVaJWO)x3tK)NLvp@-;bW=?LCB!#^B(ye zN=R4N#Doe$9$kdfm`GJdwb}5uqvT?3bV|A*hpUkVoZk0Ooz~NcPow(wH3I$lQT%C@3tXFc zzbwPhgfVcaHY$ul|3pF|H+yE3#3H+fC30?EC$VfxsQTSNpu?mls7e9D>=9$(U805X#qP&BNv&6+N*1Dcz;W9+aPG{*ZNY( z{{R2~|NsA&B?}qT|AX9rk_4bAss&Zm+O_Mp3B{<~qerTgOOCq6=$Rc;N-lkpR8ol-8?2`>)s@|eK*m~5Jk#VzB*8B+119$6vI@~~XqLWTzi0I$f8;o+!{4sUTU95Clv#aef65?5&aoz4bZO)= zH=Trt!eCxS?J3vCFwDL8(zQ;^26yQ<{FbP?_;IQ&BuqB1?Znus1<;j}l3K$12P;b{ zs+0Ibc-|umh}a={4{jy2grYH6{ttI;{uSOO_=*kYhXrR>XpR})3JIfIa2BB%eg^U~ z5XX%RF~m~J7Drsslh?jH{QtP`_qhWjP5N{M7#ftA{+j&Rgizr&^$U7G&u{b33m%9H ziin6xlo*8wg4f8u>B6o5+)UQaUS#Pa0yoyJt}#AqqZj37{2^X9|AZiGgf#<%0AVB~ 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ÂojyJ#R+jF6Q9^#0aS1fac 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 F{vTqHgJl2! literal 0 HcmV?d00001 diff --git a/public/imgs/favicon.ico b/public/imgs/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..5479e57ed7c5f9e7653a997e6cfff3598bda6a71 GIT binary patch literal 15086 zcmeHO%W>N<5QWDsz$NGsNk^Y@P6H`HGdX4^HF&I38c-7{!AD=!L{vvkG#;fFt~XdN zXxb#5SC;lk2zfI-bc6CG2t_d#pw9O z(*51D>yr1XhrMcix7#&3J8Rm?)jVi>d?lV5K1(imOUa^V|KV`>hwXSgy7)n(6J$~D z&@%9M)(ra(KNE!ig#SeR>3o1SFAhiir=^-E{HL=8YvDiTXHlGgUfLy|zuYlR6X&;= zzTw3XjEDb(|HSjR^8wbpy%Xm*S}M+Ooh7;&;%c7{mHY?XeLNVO>ijb$eot4QO|0ja z7t>01g#A4}(CG9Y_@Tp^w>4+t8p>zU*Yx*cfsISHv3#HStu?ULtOln=(}$mUI1k{m zuxo5+gBJ2F9>~X-g{`K)gdZ|B9?qpyf)={^aQ5-l;IwEg{6nxn2IQAym2k6~5BxcC)_&lsJKKvc;4Q%$2{|4FK zCwK!JjEd7E^tX2*M)1#tyVc8k92x(Iy}!YGDB>=}lJ`UF@3cFxKjG&(r9H|k{6uQW}_kjGR*16uNWW$5qj`_$OBh9>ME{^#vGj>rCs{Wm1G zNBr@hk^fu#l`+Dan>-^}G>kd2)Ur$G8%-$)wNrH;P3nHsMYmG#ilqcs%-{AU_ m=FEBKMVCS;&woqEv*AKQ{|Y<J literal 0 HcmV?d00001 diff --git a/public/imgs/github-mark-white.svg b/public/imgs/github-mark-white.svg new file mode 100644 index 0000000..d5e6491 --- /dev/null +++ b/public/imgs/github-mark-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/imgs/github-mark.svg b/public/imgs/github-mark.svg new file mode 100644 index 0000000..37fa923 --- /dev/null +++ b/public/imgs/github-mark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/imgs/logo.svg b/public/imgs/logo.svg new file mode 100644 index 0000000..a13b309 --- /dev/null +++ b/public/imgs/logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/js/htmx.min.js b/public/js/htmx.min.js new file mode 100644 index 0000000..de5f0f1 --- /dev/null +++ b/public/js/htmx.min.js @@ -0,0 +1 @@ +(function(e,t){if(typeof define==="function"&&define.amd){define([],t)}else if(typeof module==="object"&&module.exports){module.exports=t()}else{e.htmx=e.htmx||t()}})(typeof self!=="undefined"?self:this,function(){return function(){"use strict";var Q={onLoad:F,process:zt,on:de,off:ge,trigger:ce,ajax:Nr,find:C,findAll:f,closest:v,values:function(e,t){var r=dr(e,t||"post");return r.values},remove:_,addClass:z,removeClass:n,toggleClass:$,takeClass:W,defineExtension:Ur,removeExtension:Br,logAll:V,logNone:j,logger:null,config:{historyEnabled:true,historyCacheSize:10,refreshOnHistoryMiss:false,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:20,includeIndicatorStyles:true,indicatorClass:"htmx-indicator",requestClass:"htmx-request",addedClass:"htmx-added",settlingClass:"htmx-settling",swappingClass:"htmx-swapping",allowEval:true,allowScriptTags:true,inlineScriptNonce:"",attributesToSettle:["class","style","width","height"],withCredentials:false,timeout:0,wsReconnectDelay:"full-jitter",wsBinaryType:"blob",disableSelector:"[hx-disable], [data-hx-disable]",useTemplateFragments:false,scrollBehavior:"smooth",defaultFocusScroll:false,getCacheBusterParam:false,globalViewTransitions:false,methodsThatUseUrlParams:["get"],selfRequestsOnly:false,ignoreTitle:false,scrollIntoViewOnBoost:true,triggerSpecsCache:null},parseInterval:d,_:t,createEventSource:function(e){return new EventSource(e,{withCredentials:true})},createWebSocket:function(e){var t=new WebSocket(e,[]);t.binaryType=Q.config.wsBinaryType;return t},version:"1.9.12"};var r={addTriggerHandler:Lt,bodyContains:se,canAccessLocalStorage:U,findThisElement:xe,filterValues:yr,hasAttribute:o,getAttributeValue:te,getClosestAttributeValue:ne,getClosestMatch:c,getExpressionVars:Hr,getHeaders:xr,getInputValues:dr,getInternalData:ae,getSwapSpecification:wr,getTriggerSpecs:it,getTarget:ye,makeFragment:l,mergeObjects:le,makeSettleInfo:T,oobSwap:Ee,querySelectorExt:ue,selectAndSwap:je,settleImmediately:nr,shouldCancel:ut,triggerEvent:ce,triggerErrorEvent:fe,withExtensions:R};var w=["get","post","put","delete","patch"];var i=w.map(function(e){return"[hx-"+e+"], [data-hx-"+e+"]"}).join(", ");var S=e("head"),q=e("title"),H=e("svg",true);function e(e,t){return new RegExp("<"+e+"(\\s[^>]*>|>)([\\s\\S]*?)<\\/"+e+">",!!t?"gim":"im")}function d(e){if(e==undefined){return undefined}let t=NaN;if(e.slice(-2)=="ms"){t=parseFloat(e.slice(0,-2))}else if(e.slice(-1)=="s"){t=parseFloat(e.slice(0,-1))*1e3}else if(e.slice(-1)=="m"){t=parseFloat(e.slice(0,-1))*1e3*60}else{t=parseFloat(e)}return isNaN(t)?undefined:t}function ee(e,t){return e.getAttribute&&e.getAttribute(t)}function o(e,t){return e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute("data-"+t))}function te(e,t){return ee(e,t)||ee(e,"data-"+t)}function u(e){return e.parentElement}function re(){return document}function c(e,t){while(e&&!t(e)){e=u(e)}return e?e:null}function L(e,t,r){var n=te(t,r);var i=te(t,"hx-disinherit");if(e!==t&&i&&(i==="*"||i.split(" ").indexOf(r)>=0)){return"unset"}else{return n}}function ne(t,r){var n=null;c(t,function(e){return n=L(t,e,r)});if(n!=="unset"){return n}}function h(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}function A(e){var t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i;var r=t.exec(e);if(r){return r[1].toLowerCase()}else{return""}}function s(e,t){var r=new DOMParser;var n=r.parseFromString(e,"text/html");var i=n.body;while(t>0){t--;i=i.firstChild}if(i==null){i=re().createDocumentFragment()}return i}function N(e){return/",0);var a=i.querySelector("template").content;if(Q.config.allowScriptTags){oe(a.querySelectorAll("script"),function(e){if(Q.config.inlineScriptNonce){e.nonce=Q.config.inlineScriptNonce}e.htmxExecuted=navigator.userAgent.indexOf("Firefox")===-1})}else{oe(a.querySelectorAll("script"),function(e){_(e)})}return a}switch(r){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return s(""+n+"
",1);case"col":return s(""+n+"
",2);case"tr":return s(""+n+"
",2);case"td":case"th":return s(""+n+"
",3);case"script":case"style":return s("
"+n+"
",1);default:return s(n,0)}}function ie(e){if(e){e()}}function I(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function k(e){return I(e,"Function")}function P(e){return I(e,"Object")}function ae(e){var t="htmx-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function M(e){var t=[];if(e){for(var r=0;r=0}function se(e){if(e.getRootNode&&e.getRootNode()instanceof window.ShadowRoot){return re().body.contains(e.getRootNode().host)}else{return re().body.contains(e)}}function D(e){return e.trim().split(/\s+/)}function le(e,t){for(var r in t){if(t.hasOwnProperty(r)){e[r]=t[r]}}return e}function E(e){try{return JSON.parse(e)}catch(e){b(e);return null}}function U(){var e="htmx:localStorageTest";try{localStorage.setItem(e,e);localStorage.removeItem(e);return true}catch(e){return false}}function B(t){try{var e=new URL(t);if(e){t=e.pathname+e.search}if(!/^\/$/.test(t)){t=t.replace(/\/+$/,"")}return t}catch(e){return t}}function t(e){return Tr(re().body,function(){return eval(e)})}function F(t){var e=Q.on("htmx:load",function(e){t(e.detail.elt)});return e}function V(){Q.logger=function(e,t,r){if(console){console.log(t,e,r)}}}function j(){Q.logger=null}function C(e,t){if(t){return e.querySelector(t)}else{return C(re(),e)}}function f(e,t){if(t){return e.querySelectorAll(t)}else{return f(re(),e)}}function _(e,t){e=p(e);if(t){setTimeout(function(){_(e);e=null},t)}else{e.parentElement.removeChild(e)}}function z(e,t,r){e=p(e);if(r){setTimeout(function(){z(e,t);e=null},r)}else{e.classList&&e.classList.add(t)}}function n(e,t,r){e=p(e);if(r){setTimeout(function(){n(e,t);e=null},r)}else{if(e.classList){e.classList.remove(t);if(e.classList.length===0){e.removeAttribute("class")}}}}function $(e,t){e=p(e);e.classList.toggle(t)}function W(e,t){e=p(e);oe(e.parentElement.children,function(e){n(e,t)});z(e,t)}function v(e,t){e=p(e);if(e.closest){return e.closest(t)}else{do{if(e==null||h(e,t)){return e}}while(e=e&&u(e));return null}}function g(e,t){return e.substring(0,t.length)===t}function G(e,t){return e.substring(e.length-t.length)===t}function J(e){var t=e.trim();if(g(t,"<")&&G(t,"/>")){return t.substring(1,t.length-2)}else{return t}}function Z(e,t){if(t.indexOf("closest ")===0){return[v(e,J(t.substr(8)))]}else if(t.indexOf("find ")===0){return[C(e,J(t.substr(5)))]}else if(t==="next"){return[e.nextElementSibling]}else if(t.indexOf("next ")===0){return[K(e,J(t.substr(5)))]}else if(t==="previous"){return[e.previousElementSibling]}else if(t.indexOf("previous ")===0){return[Y(e,J(t.substr(9)))]}else if(t==="document"){return[document]}else if(t==="window"){return[window]}else if(t==="body"){return[document.body]}else{return re().querySelectorAll(J(t))}}var K=function(e,t){var r=re().querySelectorAll(t);for(var n=0;n=0;n--){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_FOLLOWING){return i}}};function ue(e,t){if(t){return Z(e,t)[0]}else{return Z(re().body,e)[0]}}function p(e){if(I(e,"String")){return C(e)}else{return e}}function ve(e,t,r){if(k(t)){return{target:re().body,event:e,listener:t}}else{return{target:p(e),event:t,listener:r}}}function de(t,r,n){jr(function(){var e=ve(t,r,n);e.target.addEventListener(e.event,e.listener)});var e=k(r);return e?r:n}function ge(t,r,n){jr(function(){var e=ve(t,r,n);e.target.removeEventListener(e.event,e.listener)});return k(r)?r:n}var pe=re().createElement("output");function me(e,t){var r=ne(e,t);if(r){if(r==="this"){return[xe(e,t)]}else{var n=Z(e,r);if(n.length===0){b('The selector "'+r+'" on '+t+" returned no matches!");return[pe]}else{return n}}}}function xe(e,t){return c(e,function(e){return te(e,t)!=null})}function ye(e){var t=ne(e,"hx-target");if(t){if(t==="this"){return xe(e,"hx-target")}else{return ue(e,t)}}else{var r=ae(e);if(r.boosted){return re().body}else{return e}}}function be(e){var t=Q.config.attributesToSettle;for(var r=0;r0){o=e.substr(0,e.indexOf(":"));t=e.substr(e.indexOf(":")+1,e.length)}else{o=e}var r=re().querySelectorAll(t);if(r){oe(r,function(e){var t;var r=i.cloneNode(true);t=re().createDocumentFragment();t.appendChild(r);if(!Se(o,e)){t=r}var n={shouldSwap:true,target:e,fragment:t};if(!ce(e,"htmx:oobBeforeSwap",n))return;e=n.target;if(n["shouldSwap"]){Fe(o,e,e,t,a)}oe(a.elts,function(e){ce(e,"htmx:oobAfterSwap",n)})});i.parentNode.removeChild(i)}else{i.parentNode.removeChild(i);fe(re().body,"htmx:oobErrorNoTarget",{content:i})}return e}function Ce(e,t,r){var n=ne(e,"hx-select-oob");if(n){var i=n.split(",");for(var a=0;a0){var r=t.replace("'","\\'");var n=e.tagName.replace(":","\\:");var i=o.querySelector(n+"[id='"+r+"']");if(i&&i!==o){var a=e.cloneNode();we(e,i);s.tasks.push(function(){we(e,a)})}}})}function Oe(e){return function(){n(e,Q.config.addedClass);zt(e);Nt(e);qe(e);ce(e,"htmx:load")}}function qe(e){var t="[autofocus]";var r=h(e,t)?e:e.querySelector(t);if(r!=null){r.focus()}}function a(e,t,r,n){Te(e,r,n);while(r.childNodes.length>0){var i=r.firstChild;z(i,Q.config.addedClass);e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE&&i.nodeType!==Node.COMMENT_NODE){n.tasks.push(Oe(i))}}}function He(e,t){var r=0;while(r-1){var t=e.replace(H,"");var r=t.match(q);if(r){return r[2]}}}function je(e,t,r,n,i,a){i.title=Ve(n);var o=l(n);if(o){Ce(r,o,i);o=Be(r,o,a);Re(o);return Fe(e,r,t,o,i)}}function _e(e,t,r){var n=e.getResponseHeader(t);if(n.indexOf("{")===0){var i=E(n);for(var a in i){if(i.hasOwnProperty(a)){var o=i[a];if(!P(o)){o={value:o}}ce(r,a,o)}}}else{var s=n.split(",");for(var l=0;l0){var o=t[0];if(o==="]"){n--;if(n===0){if(a===null){i=i+"true"}t.shift();i+=")})";try{var s=Tr(e,function(){return Function(i)()},function(){return true});s.source=i;return s}catch(e){fe(re().body,"htmx:syntax:error",{error:e,source:i});return null}}}else if(o==="["){n++}if(Qe(o,a,r)){i+="(("+r+"."+o+") ? ("+r+"."+o+") : (window."+o+"))"}else{i=i+o}a=t.shift()}}}function y(e,t){var r="";while(e.length>0&&!t.test(e[0])){r+=e.shift()}return r}function tt(e){var t;if(e.length>0&&Ze.test(e[0])){e.shift();t=y(e,Ke).trim();e.shift()}else{t=y(e,x)}return t}var rt="input, textarea, select";function nt(e,t,r){var n=[];var i=Ye(t);do{y(i,Je);var a=i.length;var o=y(i,/[,\[\s]/);if(o!==""){if(o==="every"){var s={trigger:"every"};y(i,Je);s.pollInterval=d(y(i,/[,\[\s]/));y(i,Je);var l=et(e,i,"event");if(l){s.eventFilter=l}n.push(s)}else if(o.indexOf("sse:")===0){n.push({trigger:"sse",sseEvent:o.substr(4)})}else{var u={trigger:o};var l=et(e,i,"event");if(l){u.eventFilter=l}while(i.length>0&&i[0]!==","){y(i,Je);var f=i.shift();if(f==="changed"){u.changed=true}else if(f==="once"){u.once=true}else if(f==="consume"){u.consume=true}else if(f==="delay"&&i[0]===":"){i.shift();u.delay=d(y(i,x))}else if(f==="from"&&i[0]===":"){i.shift();if(Ze.test(i[0])){var c=tt(i)}else{var c=y(i,x);if(c==="closest"||c==="find"||c==="next"||c==="previous"){i.shift();var h=tt(i);if(h.length>0){c+=" "+h}}}u.from=c}else if(f==="target"&&i[0]===":"){i.shift();u.target=tt(i)}else if(f==="throttle"&&i[0]===":"){i.shift();u.throttle=d(y(i,x))}else if(f==="queue"&&i[0]===":"){i.shift();u.queue=y(i,x)}else if(f==="root"&&i[0]===":"){i.shift();u[f]=tt(i)}else if(f==="threshold"&&i[0]===":"){i.shift();u[f]=y(i,x)}else{fe(e,"htmx:syntax:error",{token:i.shift()})}}n.push(u)}}if(i.length===a){fe(e,"htmx:syntax:error",{token:i.shift()})}y(i,Je)}while(i[0]===","&&i.shift());if(r){r[t]=n}return n}function it(e){var t=te(e,"hx-trigger");var r=[];if(t){var n=Q.config.triggerSpecsCache;r=n&&n[t]||nt(e,t,n)}if(r.length>0){return r}else if(h(e,"form")){return[{trigger:"submit"}]}else if(h(e,'input[type="button"], input[type="submit"]')){return[{trigger:"click"}]}else if(h(e,rt)){return[{trigger:"change"}]}else{return[{trigger:"click"}]}}function at(e){ae(e).cancelled=true}function ot(e,t,r){var n=ae(e);n.timeout=setTimeout(function(){if(se(e)&&n.cancelled!==true){if(!ct(r,e,Wt("hx:poll:trigger",{triggerSpec:r,target:e}))){t(e)}ot(e,t,r)}},r.pollInterval)}function st(e){return location.hostname===e.hostname&&ee(e,"href")&&ee(e,"href").indexOf("#")!==0}function lt(t,r,e){if(t.tagName==="A"&&st(t)&&(t.target===""||t.target==="_self")||t.tagName==="FORM"){r.boosted=true;var n,i;if(t.tagName==="A"){n="get";i=ee(t,"href")}else{var a=ee(t,"method");n=a?a.toLowerCase():"get";if(n==="get"){}i=ee(t,"action")}e.forEach(function(e){ht(t,function(e,t){if(v(e,Q.config.disableSelector)){m(e);return}he(n,i,e,t)},r,e,true)})}}function ut(e,t){if(e.type==="submit"||e.type==="click"){if(t.tagName==="FORM"){return true}if(h(t,'input[type="submit"], button')&&v(t,"form")!==null){return true}if(t.tagName==="A"&&t.href&&(t.getAttribute("href")==="#"||t.getAttribute("href").indexOf("#")!==0)){return true}}return false}function ft(e,t){return ae(e).boosted&&e.tagName==="A"&&t.type==="click"&&(t.ctrlKey||t.metaKey)}function ct(e,t,r){var n=e.eventFilter;if(n){try{return n.call(t,r)!==true}catch(e){fe(re().body,"htmx:eventFilter:error",{error:e,source:n.source});return true}}return false}function ht(a,o,e,s,l){var u=ae(a);var t;if(s.from){t=Z(a,s.from)}else{t=[a]}if(s.changed){t.forEach(function(e){var t=ae(e);t.lastValue=e.value})}oe(t,function(n){var i=function(e){if(!se(a)){n.removeEventListener(s.trigger,i);return}if(ft(a,e)){return}if(l||ut(e,a)){e.preventDefault()}if(ct(s,a,e)){return}var t=ae(e);t.triggerSpec=s;if(t.handledFor==null){t.handledFor=[]}if(t.handledFor.indexOf(a)<0){t.handledFor.push(a);if(s.consume){e.stopPropagation()}if(s.target&&e.target){if(!h(e.target,s.target)){return}}if(s.once){if(u.triggeredOnce){return}else{u.triggeredOnce=true}}if(s.changed){var r=ae(n);if(r.lastValue===n.value){return}r.lastValue=n.value}if(u.delayed){clearTimeout(u.delayed)}if(u.throttle){return}if(s.throttle>0){if(!u.throttle){o(a,e);u.throttle=setTimeout(function(){u.throttle=null},s.throttle)}}else if(s.delay>0){u.delayed=setTimeout(function(){o(a,e)},s.delay)}else{ce(a,"htmx:trigger");o(a,e)}}};if(e.listenerInfos==null){e.listenerInfos=[]}e.listenerInfos.push({trigger:s.trigger,listener:i,on:n});n.addEventListener(s.trigger,i)})}var vt=false;var dt=null;function gt(){if(!dt){dt=function(){vt=true};window.addEventListener("scroll",dt);setInterval(function(){if(vt){vt=false;oe(re().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"),function(e){pt(e)})}},200)}}function pt(t){if(!o(t,"data-hx-revealed")&&X(t)){t.setAttribute("data-hx-revealed","true");var e=ae(t);if(e.initHash){ce(t,"revealed")}else{t.addEventListener("htmx:afterProcessNode",function(e){ce(t,"revealed")},{once:true})}}}function mt(e,t,r){var n=D(r);for(var i=0;i=0){var t=wt(n);setTimeout(function(){xt(s,r,n+1)},t)}};t.onopen=function(e){n=0};ae(s).webSocket=t;t.addEventListener("message",function(e){if(yt(s)){return}var t=e.data;R(s,function(e){t=e.transformResponse(t,null,s)});var r=T(s);var n=l(t);var i=M(n.children);for(var a=0;a0){ce(u,"htmx:validation:halted",i);return}t.send(JSON.stringify(l));if(ut(e,u)){e.preventDefault()}})}else{fe(u,"htmx:noWebSocketSourceError")}}function wt(e){var t=Q.config.wsReconnectDelay;if(typeof t==="function"){return t(e)}if(t==="full-jitter"){var r=Math.min(e,6);var n=1e3*Math.pow(2,r);return n*Math.random()}b('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"')}function St(e,t,r){var n=D(r);for(var i=0;i0){setTimeout(i,n)}else{i()}}function Ht(t,i,e){var a=false;oe(w,function(r){if(o(t,"hx-"+r)){var n=te(t,"hx-"+r);a=true;i.path=n;i.verb=r;e.forEach(function(e){Lt(t,e,i,function(e,t){if(v(e,Q.config.disableSelector)){m(e);return}he(r,n,e,t)})})}});return a}function Lt(n,e,t,r){if(e.sseEvent){Rt(n,r,e.sseEvent)}else if(e.trigger==="revealed"){gt();ht(n,r,t,e);pt(n)}else if(e.trigger==="intersect"){var i={};if(e.root){i.root=ue(n,e.root)}if(e.threshold){i.threshold=parseFloat(e.threshold)}var a=new IntersectionObserver(function(e){for(var t=0;t0){t.polling=true;ot(n,r,e)}else{ht(n,r,t,e)}}function At(e){if(!e.htmxExecuted&&Q.config.allowScriptTags&&(e.type==="text/javascript"||e.type==="module"||e.type==="")){var t=re().createElement("script");oe(e.attributes,function(e){t.setAttribute(e.name,e.value)});t.textContent=e.textContent;t.async=false;if(Q.config.inlineScriptNonce){t.nonce=Q.config.inlineScriptNonce}var r=e.parentElement;try{r.insertBefore(t,e)}catch(e){b(e)}finally{if(e.parentElement){e.parentElement.removeChild(e)}}}}function Nt(e){if(h(e,"script")){At(e)}oe(f(e,"script"),function(e){At(e)})}function It(e){var t=e.attributes;if(!t){return false}for(var r=0;r0){var o=n.shift();var s=o.match(/^\s*([a-zA-Z:\-\.]+:)(.*)/);if(a===0&&s){o.split(":");i=s[1].slice(0,-1);r[i]=s[2]}else{r[i]+=o}a+=Bt(o)}for(var l in r){Ft(e,l,r[l])}}}function jt(e){Ae(e);for(var t=0;tQ.config.historyCacheSize){i.shift()}while(i.length>0){try{localStorage.setItem("htmx-history-cache",JSON.stringify(i));break}catch(e){fe(re().body,"htmx:historyCacheError",{cause:e,cache:i});i.shift()}}}function Yt(e){if(!U()){return null}e=B(e);var t=E(localStorage.getItem("htmx-history-cache"))||[];for(var r=0;r=200&&this.status<400){ce(re().body,"htmx:historyCacheMissLoad",o);var e=l(this.response);e=e.querySelector("[hx-history-elt],[data-hx-history-elt]")||e;var t=Zt();var r=T(t);var n=Ve(this.response);if(n){var i=C("title");if(i){i.innerHTML=n}else{window.document.title=n}}Ue(t,e,r);nr(r.tasks);Jt=a;ce(re().body,"htmx:historyRestore",{path:a,cacheMiss:true,serverResponse:this.response})}else{fe(re().body,"htmx:historyCacheMissLoadError",o)}};e.send()}function ar(e){er();e=e||location.pathname+location.search;var t=Yt(e);if(t){var r=l(t.content);var n=Zt();var i=T(n);Ue(n,r,i);nr(i.tasks);document.title=t.title;setTimeout(function(){window.scrollTo(0,t.scroll)},0);Jt=e;ce(re().body,"htmx:historyRestore",{path:e,item:t})}else{if(Q.config.refreshOnHistoryMiss){window.location.reload(true)}else{ir(e)}}}function or(e){var t=me(e,"hx-indicator");if(t==null){t=[e]}oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)+1;e.classList["add"].call(e.classList,Q.config.requestClass)});return t}function sr(e){var t=me(e,"hx-disabled-elt");if(t==null){t=[]}oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)+1;e.setAttribute("disabled","")});return t}function lr(e,t){oe(e,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.classList["remove"].call(e.classList,Q.config.requestClass)}});oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.removeAttribute("disabled")}})}function ur(e,t){for(var r=0;r=0}function wr(e,t){var r=t?t:ne(e,"hx-swap");var n={swapStyle:ae(e).boosted?"innerHTML":Q.config.defaultSwapStyle,swapDelay:Q.config.defaultSwapDelay,settleDelay:Q.config.defaultSettleDelay};if(Q.config.scrollIntoViewOnBoost&&ae(e).boosted&&!br(e)){n["show"]="top"}if(r){var i=D(r);if(i.length>0){for(var a=0;a0?l.join(":"):null;n["scroll"]=u;n["scrollTarget"]=f}else if(o.indexOf("show:")===0){var c=o.substr(5);var l=c.split(":");var h=l.pop();var f=l.length>0?l.join(":"):null;n["show"]=h;n["showTarget"]=f}else if(o.indexOf("focus-scroll:")===0){var v=o.substr("focus-scroll:".length);n["focusScroll"]=v=="true"}else if(a==0){n["swapStyle"]=o}else{b("Unknown modifier in hx-swap: "+o)}}}}return n}function Sr(e){return ne(e,"hx-encoding")==="multipart/form-data"||h(e,"form")&&ee(e,"enctype")==="multipart/form-data"}function Er(t,r,n){var i=null;R(r,function(e){if(i==null){i=e.encodeParameters(t,n,r)}});if(i!=null){return i}else{if(Sr(r)){return mr(n)}else{return pr(n)}}}function T(e){return{tasks:[],elts:[e]}}function Cr(e,t){var r=e[0];var n=e[e.length-1];if(t.scroll){var i=null;if(t.scrollTarget){i=ue(r,t.scrollTarget)}if(t.scroll==="top"&&(r||i)){i=i||r;i.scrollTop=0}if(t.scroll==="bottom"&&(n||i)){i=i||n;i.scrollTop=i.scrollHeight}}if(t.show){var i=null;if(t.showTarget){var a=t.showTarget;if(t.showTarget==="window"){a="body"}i=ue(r,a)}if(t.show==="top"&&(r||i)){i=i||r;i.scrollIntoView({block:"start",behavior:Q.config.scrollBehavior})}if(t.show==="bottom"&&(n||i)){i=i||n;i.scrollIntoView({block:"end",behavior:Q.config.scrollBehavior})}}}function Rr(e,t,r,n){if(n==null){n={}}if(e==null){return n}var i=te(e,t);if(i){var a=i.trim();var o=r;if(a==="unset"){return null}if(a.indexOf("javascript:")===0){a=a.substr(11);o=true}else if(a.indexOf("js:")===0){a=a.substr(3);o=true}if(a.indexOf("{")!==0){a="{"+a+"}"}var s;if(o){s=Tr(e,function(){return Function("return ("+a+")")()},{})}else{s=E(a)}for(var l in s){if(s.hasOwnProperty(l)){if(n[l]==null){n[l]=s[l]}}}}return Rr(u(e),t,r,n)}function Tr(e,t,r){if(Q.config.allowEval){return t()}else{fe(e,"htmx:evalDisallowedError");return r}}function Or(e,t){return Rr(e,"hx-vars",true,t)}function qr(e,t){return Rr(e,"hx-vals",false,t)}function Hr(e){return le(Or(e),qr(e))}function Lr(t,r,n){if(n!==null){try{t.setRequestHeader(r,n)}catch(e){t.setRequestHeader(r,encodeURIComponent(n));t.setRequestHeader(r+"-URI-AutoEncoded","true")}}}function Ar(t){if(t.responseURL&&typeof URL!=="undefined"){try{var e=new URL(t.responseURL);return e.pathname+e.search}catch(e){fe(re().body,"htmx:badResponseUrl",{url:t.responseURL})}}}function O(e,t){return t.test(e.getAllResponseHeaders())}function Nr(e,t,r){e=e.toLowerCase();if(r){if(r instanceof Element||I(r,"String")){return he(e,t,null,null,{targetOverride:p(r),returnPromise:true})}else{return he(e,t,p(r.source),r.event,{handler:r.handler,headers:r.headers,values:r.values,targetOverride:p(r.target),swapOverride:r.swap,select:r.select,returnPromise:true})}}else{return he(e,t,null,null,{returnPromise:true})}}function Ir(e){var t=[];while(e){t.push(e);e=e.parentElement}return t}function kr(e,t,r){var n;var i;if(typeof URL==="function"){i=new URL(t,document.location.href);var a=document.location.origin;n=a===i.origin}else{i=t;n=g(t,document.location.origin)}if(Q.config.selfRequestsOnly){if(!n){return false}}return ce(e,"htmx:validateUrl",le({url:i,sameHost:n},r))}function he(t,r,n,i,a,e){var o=null;var s=null;a=a!=null?a:{};if(a.returnPromise&&typeof Promise!=="undefined"){var l=new Promise(function(e,t){o=e;s=t})}if(n==null){n=re().body}var M=a.handler||Mr;var X=a.select||null;if(!se(n)){ie(o);return l}var u=a.targetOverride||ye(n);if(u==null||u==pe){fe(n,"htmx:targetError",{target:te(n,"hx-target")});ie(s);return l}var f=ae(n);var c=f.lastButtonClicked;if(c){var h=ee(c,"formaction");if(h!=null){r=h}var v=ee(c,"formmethod");if(v!=null){if(v.toLowerCase()!=="dialog"){t=v}}}var d=ne(n,"hx-confirm");if(e===undefined){var D=function(e){return he(t,r,n,i,a,!!e)};var U={target:u,elt:n,path:r,verb:t,triggeringEvent:i,etc:a,issueRequest:D,question:d};if(ce(n,"htmx:confirm",U)===false){ie(o);return l}}var g=n;var p=ne(n,"hx-sync");var m=null;var x=false;if(p){var B=p.split(":");var F=B[0].trim();if(F==="this"){g=xe(n,"hx-sync")}else{g=ue(n,F)}p=(B[1]||"drop").trim();f=ae(g);if(p==="drop"&&f.xhr&&f.abortable!==true){ie(o);return l}else if(p==="abort"){if(f.xhr){ie(o);return l}else{x=true}}else if(p==="replace"){ce(g,"htmx:abort")}else if(p.indexOf("queue")===0){var V=p.split(" ");m=(V[1]||"last").trim()}}if(f.xhr){if(f.abortable){ce(g,"htmx:abort")}else{if(m==null){if(i){var y=ae(i);if(y&&y.triggerSpec&&y.triggerSpec.queue){m=y.triggerSpec.queue}}if(m==null){m="last"}}if(f.queuedRequests==null){f.queuedRequests=[]}if(m==="first"&&f.queuedRequests.length===0){f.queuedRequests.push(function(){he(t,r,n,i,a)})}else if(m==="all"){f.queuedRequests.push(function(){he(t,r,n,i,a)})}else if(m==="last"){f.queuedRequests=[];f.queuedRequests.push(function(){he(t,r,n,i,a)})}ie(o);return l}}var b=new XMLHttpRequest;f.xhr=b;f.abortable=x;var w=function(){f.xhr=null;f.abortable=false;if(f.queuedRequests!=null&&f.queuedRequests.length>0){var e=f.queuedRequests.shift();e()}};var j=ne(n,"hx-prompt");if(j){var S=prompt(j);if(S===null||!ce(n,"htmx:prompt",{prompt:S,target:u})){ie(o);w();return l}}if(d&&!e){if(!confirm(d)){ie(o);w();return l}}var E=xr(n,u,S);if(t!=="get"&&!Sr(n)){E["Content-Type"]="application/x-www-form-urlencoded"}if(a.headers){E=le(E,a.headers)}var _=dr(n,t);var C=_.errors;var R=_.values;if(a.values){R=le(R,a.values)}var z=Hr(n);var $=le(R,z);var T=yr($,n);if(Q.config.getCacheBusterParam&&t==="get"){T["org.htmx.cache-buster"]=ee(u,"id")||"true"}if(r==null||r===""){r=re().location.href}var O=Rr(n,"hx-request");var W=ae(n).boosted;var q=Q.config.methodsThatUseUrlParams.indexOf(t)>=0;var H={boosted:W,useUrlParams:q,parameters:T,unfilteredParameters:$,headers:E,target:u,verb:t,errors:C,withCredentials:a.credentials||O.credentials||Q.config.withCredentials,timeout:a.timeout||O.timeout||Q.config.timeout,path:r,triggeringEvent:i};if(!ce(n,"htmx:configRequest",H)){ie(o);w();return l}r=H.path;t=H.verb;E=H.headers;T=H.parameters;C=H.errors;q=H.useUrlParams;if(C&&C.length>0){ce(n,"htmx:validation:halted",H);ie(o);w();return l}var G=r.split("#");var J=G[0];var L=G[1];var A=r;if(q){A=J;var Z=Object.keys(T).length!==0;if(Z){if(A.indexOf("?")<0){A+="?"}else{A+="&"}A+=pr(T);if(L){A+="#"+L}}}if(!kr(n,A,H)){fe(n,"htmx:invalidPath",H);ie(s);return l}b.open(t.toUpperCase(),A,true);b.overrideMimeType("text/html");b.withCredentials=H.withCredentials;b.timeout=H.timeout;if(O.noHeaders){}else{for(var N in E){if(E.hasOwnProperty(N)){var K=E[N];Lr(b,N,K)}}}var I={xhr:b,target:u,requestConfig:H,etc:a,boosted:W,select:X,pathInfo:{requestPath:r,finalRequestPath:A,anchor:L}};b.onload=function(){try{var e=Ir(n);I.pathInfo.responsePath=Ar(b);M(n,I);lr(k,P);ce(n,"htmx:afterRequest",I);ce(n,"htmx:afterOnLoad",I);if(!se(n)){var t=null;while(e.length>0&&t==null){var r=e.shift();if(se(r)){t=r}}if(t){ce(t,"htmx:afterRequest",I);ce(t,"htmx:afterOnLoad",I)}}ie(o);w()}catch(e){fe(n,"htmx:onLoadError",le({error:e},I));throw e}};b.onerror=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:sendError",I);ie(s);w()};b.onabort=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:sendAbort",I);ie(s);w()};b.ontimeout=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:timeout",I);ie(s);w()};if(!ce(n,"htmx:beforeRequest",I)){ie(o);w();return l}var k=or(n);var P=sr(n);oe(["loadstart","loadend","progress","abort"],function(t){oe([b,b.upload],function(e){e.addEventListener(t,function(e){ce(n,"htmx:xhr:"+t,{lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total})})})});ce(n,"htmx:beforeSend",I);var Y=q?null:Er(b,n,T);b.send(Y);return l}function Pr(e,t){var r=t.xhr;var n=null;var i=null;if(O(r,/HX-Push:/i)){n=r.getResponseHeader("HX-Push");i="push"}else if(O(r,/HX-Push-Url:/i)){n=r.getResponseHeader("HX-Push-Url");i="push"}else if(O(r,/HX-Replace-Url:/i)){n=r.getResponseHeader("HX-Replace-Url");i="replace"}if(n){if(n==="false"){return{}}else{return{type:i,path:n}}}var a=t.pathInfo.finalRequestPath;var o=t.pathInfo.responsePath;var s=ne(e,"hx-push-url");var l=ne(e,"hx-replace-url");var u=ae(e).boosted;var f=null;var c=null;if(s){f="push";c=s}else if(l){f="replace";c=l}else if(u){f="push";c=o||a}if(c){if(c==="false"){return{}}if(c==="true"){c=o||a}if(t.pathInfo.anchor&&c.indexOf("#")===-1){c=c+"#"+t.pathInfo.anchor}return{type:f,path:c}}else{return{}}}function Mr(l,u){var f=u.xhr;var c=u.target;var e=u.etc;var t=u.requestConfig;var h=u.select;if(!ce(l,"htmx:beforeOnLoad",u))return;if(O(f,/HX-Trigger:/i)){_e(f,"HX-Trigger",l)}if(O(f,/HX-Location:/i)){er();var r=f.getResponseHeader("HX-Location");var v;if(r.indexOf("{")===0){v=E(r);r=v["path"];delete v["path"]}Nr("GET",r,v).then(function(){tr(r)});return}var n=O(f,/HX-Refresh:/i)&&"true"===f.getResponseHeader("HX-Refresh");if(O(f,/HX-Redirect:/i)){location.href=f.getResponseHeader("HX-Redirect");n&&location.reload();return}if(n){location.reload();return}if(O(f,/HX-Retarget:/i)){if(f.getResponseHeader("HX-Retarget")==="this"){u.target=l}else{u.target=ue(l,f.getResponseHeader("HX-Retarget"))}}var d=Pr(l,u);var i=f.status>=200&&f.status<400&&f.status!==204;var g=f.response;var a=f.status>=400;var p=Q.config.ignoreTitle;var o=le({shouldSwap:i,serverResponse:g,isError:a,ignoreTitle:p},u);if(!ce(c,"htmx:beforeSwap",o))return;c=o.target;g=o.serverResponse;a=o.isError;p=o.ignoreTitle;u.target=c;u.failed=a;u.successful=!a;if(o.shouldSwap){if(f.status===286){at(l)}R(l,function(e){g=e.transformResponse(g,f,l)});if(d.type){er()}var s=e.swapOverride;if(O(f,/HX-Reswap:/i)){s=f.getResponseHeader("HX-Reswap")}var v=wr(l,s);if(v.hasOwnProperty("ignoreTitle")){p=v.ignoreTitle}c.classList.add(Q.config.swappingClass);var m=null;var x=null;var y=function(){try{var e=document.activeElement;var t={};try{t={elt:e,start:e?e.selectionStart:null,end:e?e.selectionEnd:null}}catch(e){}var r;if(h){r=h}if(O(f,/HX-Reselect:/i)){r=f.getResponseHeader("HX-Reselect")}if(d.type){ce(re().body,"htmx:beforeHistoryUpdate",le({history:d},u));if(d.type==="push"){tr(d.path);ce(re().body,"htmx:pushedIntoHistory",{path:d.path})}else{rr(d.path);ce(re().body,"htmx:replacedInHistory",{path:d.path})}}var n=T(c);je(v.swapStyle,c,l,g,n,r);if(t.elt&&!se(t.elt)&&ee(t.elt,"id")){var i=document.getElementById(ee(t.elt,"id"));var a={preventScroll:v.focusScroll!==undefined?!v.focusScroll:!Q.config.defaultFocusScroll};if(i){if(t.start&&i.setSelectionRange){try{i.setSelectionRange(t.start,t.end)}catch(e){}}i.focus(a)}}c.classList.remove(Q.config.swappingClass);oe(n.elts,function(e){if(e.classList){e.classList.add(Q.config.settlingClass)}ce(e,"htmx:afterSwap",u)});if(O(f,/HX-Trigger-After-Swap:/i)){var o=l;if(!se(l)){o=re().body}_e(f,"HX-Trigger-After-Swap",o)}var s=function(){oe(n.tasks,function(e){e.call()});oe(n.elts,function(e){if(e.classList){e.classList.remove(Q.config.settlingClass)}ce(e,"htmx:afterSettle",u)});if(u.pathInfo.anchor){var e=re().getElementById(u.pathInfo.anchor);if(e){e.scrollIntoView({block:"start",behavior:"auto"})}}if(n.title&&!p){var t=C("title");if(t){t.innerHTML=n.title}else{window.document.title=n.title}}Cr(n.elts,v);if(O(f,/HX-Trigger-After-Settle:/i)){var r=l;if(!se(l)){r=re().body}_e(f,"HX-Trigger-After-Settle",r)}ie(m)};if(v.settleDelay>0){setTimeout(s,v.settleDelay)}else{s()}}catch(e){fe(l,"htmx:swapError",u);ie(x);throw e}};var b=Q.config.globalViewTransitions;if(v.hasOwnProperty("transition")){b=v.transition}if(b&&ce(l,"htmx:beforeTransition",u)&&typeof Promise!=="undefined"&&document.startViewTransition){var w=new Promise(function(e,t){m=e;x=t});var S=y;y=function(){document.startViewTransition(function(){S();return w})}}if(v.swapDelay>0){setTimeout(y,v.swapDelay)}else{y()}}if(a){fe(l,"htmx:responseError",le({error:"Response Status Error Code "+f.status+" from "+u.pathInfo.requestPath},u))}}var Xr={};function Dr(){return{init:function(e){return null},onEvent:function(e,t){return true},transformResponse:function(e,t,r){return e},isInlineSwap:function(e){return false},handleSwap:function(e,t,r,n){return false},encodeParameters:function(e,t,r){return null}}}function Ur(e,t){if(t.init){t.init(r)}Xr[e]=le(Dr(),t)}function Br(e){delete Xr[e]}function Fr(e,r,n){if(e==undefined){return r}if(r==undefined){r=[]}if(n==undefined){n=[]}var t=te(e,"hx-ext");if(t){oe(t.split(","),function(e){e=e.replace(/ /g,"");if(e.slice(0,7)=="ignore:"){n.push(e.slice(7));return}if(n.indexOf(e)<0){var t=Xr[e];if(t&&r.indexOf(t)<0){r.push(t)}}})}return Fr(u(e),r,n)}var Vr=false;re().addEventListener("DOMContentLoaded",function(){Vr=true});function jr(e){if(Vr||re().readyState==="complete"){e()}else{re().addEventListener("DOMContentLoaded",e)}}function _r(){if(Q.config.includeIndicatorStyles!==false){re().head.insertAdjacentHTML("beforeend","")}}function zr(){var e=re().querySelector('meta[name="htmx-config"]');if(e){return E(e.content)}else{return null}}function $r(){var e=zr();if(e){Q.config=le(Q.config,e)}}jr(function(){$r();_r();var e=re().body;zt(e);var t=re().querySelectorAll("[hx-trigger='restored'],[data-hx-trigger='restored']");e.addEventListener("htmx:abort",function(e){var t=e.target;var r=ae(t);if(r&&r.xhr){r.xhr.abort()}});const r=window.onpopstate?window.onpopstate.bind(window):null;window.onpopstate=function(e){if(e.state&&e.state.htmx){ar();oe(t,function(e){ce(e,"htmx:restored",{document:re(),triggerEvent:ce})})}else{if(r){r(e)}}};setTimeout(function(){ce(e,"htmx:load",{});e=null},0)});return Q}()}); \ No newline at end of file diff --git a/src/main.go b/src/main.go index f439c28..6e55891 100644 --- a/src/main.go +++ b/src/main.go @@ -7,6 +7,7 @@ import ( "net/http" "os" "path/filepath" + "platform/src/view" "strings" "github.com/go-chi/chi/v5" @@ -38,6 +39,7 @@ func initialize() { if err != nil { log.Fatalf("failed to setup caddy: %v", err) } + view.InitTemplates() } func initEnv() { diff --git a/src/styles/tailwind.css b/src/styles/tailwind.css index ca84557..eb7e591 100644 --- a/src/styles/tailwind.css +++ b/src/styles/tailwind.css @@ -4,6 +4,26 @@ @layer base { body { - @apply bg-gray-50 text-gray-900 font-sans; + @apply bg-zinc-800 text-gray-200 font-sans; } } + +@font-face { + font-family: "CommitMono"; + src: url("/public/fonts/CommitMono-400-Regular.woff2") format("woff2"); + font-weight: normal; +} + +@font-face { + font-family: "CommitMono"; + src: url("/public/fonts/CommitMono-700-Regular.woff2") format("woff2"); + font-weight: 700; +} + +input { + @apply bg-transparent py-2 px-3 text-sm outline-none border border-gray-500 rounded-md focus:border-blue-700 focus:ring-1 focus:ring-blue-700; +} + +hr { + @apply border-gray-500 my-2; +} \ No newline at end of file diff --git a/src/view/renderer_dev.go b/src/view/renderer_dev.go index 241b962..3de724f 100644 --- a/src/view/renderer_dev.go +++ b/src/view/renderer_dev.go @@ -4,13 +4,32 @@ package view import ( "html/template" + "io/fs" + "log" "net/http" ) +var pages map[string]*template.Template + func Execute(w http.ResponseWriter, name string, data any) error { - t, err := template.ParseFS(FS, "*.html") // parse on every call + InitTemplates() + return pages[name].ExecuteTemplate(w, name, data) +} + +func InitTemplates() { + pages = make(map[string]*template.Template) + base := template.Must(template.ParseFS(FS, "base.html")) + entries, err := fs.ReadDir(FS, ".") if err != nil { - return err + log.Fatalf("read templates dir: %v", err) + } + for _, e := range entries { + name := e.Name() + if name == "base.html" { + continue + } + t := template.Must(base.Clone()) + t = template.Must(t.ParseFS(FS, name)) + pages[name] = t } - return t.ExecuteTemplate(w, name, data) } diff --git a/src/view/renderer_prod.go b/src/view/renderer_prod.go index 16fc9ad..a645a69 100644 --- a/src/view/renderer_prod.go +++ b/src/view/renderer_prod.go @@ -4,11 +4,32 @@ package view import ( "html/template" + "io/fs" + "log" "net/http" ) var tmpl = template.Must(template.ParseFS(FS, "./templates/*.html")) +var pages map[string]*template.Template func Execute(w http.ResponseWriter, name string, data any) error { return tmpl.ExecuteTemplate(w, name, data) } + +func InitTemplates() { + pages = make(map[string]*template.Template) + base := template.Must(template.ParseFS(FS, "base.html")) + entries, err := fs.ReadDir(FS, "templates") + if err != nil { + log.Fatalf("read templates dir: %v", err) + } + for _, e := range entries { + name := e.Name() + if name == "base.html" { + continue + } + t := template.Must(base.Clone()) + t = template.Must(t.ParseFS(FS, name)) + pages[name] = t + } +} diff --git a/src/view/templates/base.html b/src/view/templates/base.html new file mode 100644 index 0000000..356b2ec --- /dev/null +++ b/src/view/templates/base.html @@ -0,0 +1,54 @@ +{{define "base"}} + + + + + + {{block "title" .}}mkblog{{end}} + + + + + {{block "content" .}}{{end}} + + + +{{end}} + +{{define "page"}} + {{template "base" .}} +{{end}} + +{{define "content"}} +
+
+ {{block "page-content" .}}{{end}} +
+ +{{end}} + +{{define "user-name"}} +{{ .User.Name }} +{{end}} diff --git a/src/view/templates/home.html b/src/view/templates/home.html index 65eec71..c554c6d 100644 --- a/src/view/templates/home.html +++ b/src/view/templates/home.html @@ -4,8 +4,8 @@ Home | mkblog - - + +
diff --git a/src/view/templates/new-blog.html b/src/view/templates/new-blog.html index 9211378..7046b1c 100644 --- a/src/view/templates/new-blog.html +++ b/src/view/templates/new-blog.html @@ -1,26 +1,74 @@ - - - - - - Create a new blog | mkblog - - - -
-

Create a new blog

- Install our app on your GitHub account -
-
- - .mkblog.dev -
+{{define "title"}}New blog{{end}} +{{define "page-content"}} +
+

Create a new blog

+

Required fields are marked with an asterisk (*).

+
+ +
+

Deploy a blog from a GitHub repository

+

Select a repository to connect as your blog's source. New commits will trigger Mkblog to automatically build and deploy your changes.

+
- + + {{if .Repos}} + {{range .Repos}} +
+ + {{.Name}} +
+
+

+ If your repository is not shown, configure repository access for the + Mkblog + app on GitHub. +

+
+ {{end}} + {{else}} +

+ No repositories found, configure repository access for the + Mkblog + app on GitHub. +

+ {{end}} +
+ +
+
+
+ +
+ + .mkblog.dev
- -

{{ .Error }}

- -
- - \ No newline at end of file + Checking availability... +
+
+
+ +
+

{{ .Error }}

+ +
+{{end}} +{{define "new-blog.html"}}{{template "page" .}}{{end}} + \ No newline at end of file diff --git a/src/view/templates/signin.html b/src/view/templates/signin.html index 69200b6..e2f05c3 100644 --- a/src/view/templates/signin.html +++ b/src/view/templates/signin.html @@ -1,15 +1,36 @@ - - - - - - Sign In | mkblog - - - - - GitHub logo - Sign in with GitHub - - - \ No newline at end of file +{{define "title"}}Sign In{{end}} +{{define "content"}} +
+
+
+
+ mkblog logo +

Sign in/up to mkblog

+ + + GitHub logo + Continue with GitHub + + +
+

+ By continuing, you agree to our Terms of Service. +

+
+
+
+
+ +
+{{end}} +{{define "signin.html"}}{{template "base" .}}{{end}} diff --git a/tailwind.config.js b/tailwind.config.js index 2d06262..6b451e2 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,6 +1,6 @@ module.exports = { content: [ - './src/templates/**/*.html', + './src/view/templates/**/*.html', ], theme: { extend: {},
+
+ + mkblog logo + + {{block "title" .}}{{end}} +
+ + {{block "user-name" .}}{{end}} + Sign out + +