summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2025-09-24 09:12:44 +0200
committerYuval Adam <_@yuv.al>2025-09-24 09:12:44 +0200
commit4c5be8cf8d942743398581b46ac2c76d0ff273d8 (patch)
treeb182383a63302f24910c5534953d3624cb24f00d
parent490214f0a9be03130cf535bc5ae0b8aa3c6c16db (diff)
Initial migration
-rw-r--r--astro.config.mjs2
-rw-r--r--package-lock.json1803
-rw-r--r--package.json9
-rw-r--r--public/apple-touch-icon.pngbin0 -> 1059 bytes
-rw-r--r--public/favicon.icobin0 -> 32038 bytes
-rw-r--r--public/manifest.json15
-rw-r--r--public/screenshot.pngbin0 -> 382294 bytes
-rw-r--r--src/components/Datetime.tsx28
-rw-r--r--src/components/Geshem.tsx65
-rw-r--r--src/components/Map.tsx108
-rw-r--r--src/components/Slider.tsx43
-rw-r--r--src/config.ts19
-rw-r--r--src/functions/scheduled.ts178
-rw-r--r--src/pages/404.astro67
-rw-r--r--src/pages/api/update.ts200
-rw-r--r--src/pages/history/[date].astro23
-rw-r--r--src/pages/index.astro11
-rw-r--r--src/pages/privacy.astro38
-rw-r--r--src/styles/geshem.css45
19 files changed, 2612 insertions, 42 deletions
diff --git a/astro.config.mjs b/astro.config.mjs
index 35434a8..2658cfe 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -14,5 +14,5 @@ export default defineConfig({
plugins: [tailwindcss()]
},
- adapter: cloudflare()
+ adapter: cloudflare({})
}); \ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 74849a6..8e508a5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,9 +14,18 @@
"@types/react": "^19.1.13",
"@types/react-dom": "^19.1.9",
"astro": "^5.13.10",
+ "axios": "^1.12.2",
+ "luxon": "^3.7.2",
+ "mapbox-gl": "^3.15.0",
+ "rc-slider": "^11.1.9",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"tailwindcss": "^4.1.13"
+ },
+ "devDependencies": {
+ "@types/luxon": "^3.7.1",
+ "@types/mapbox-gl": "^3.4.1",
+ "wrangler": "^4.39.0"
}
},
"node_modules/@astrojs/cloudflare": {
@@ -36,6 +45,1042 @@
"astro": "^5.7.0"
}
},
+ "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/unenv-preset": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.7.3.tgz",
+ "integrity": "sha512-tsQQagBKjvpd9baa6nWVIv399ejiqcrUBBW6SZx6Z22+ymm+Odv5+cFimyuCsD/fC1fQTwfRmwXBNpzvHSeGCw==",
+ "license": "MIT OR Apache-2.0",
+ "peerDependencies": {
+ "unenv": "2.0.0-rc.21",
+ "workerd": "^1.20250828.1"
+ },
+ "peerDependenciesMeta": {
+ "workerd": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-darwin-64": {
+ "version": "1.20250906.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20250906.0.tgz",
+ "integrity": "sha512-E+X/YYH9BmX0ew2j/mAWFif2z05NMNuhCTlNYEGLkqMe99K15UewBqajL9pMcMUKxylnlrEoK3VNxl33DkbnPA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-darwin-arm64": {
+ "version": "1.20250906.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20250906.0.tgz",
+ "integrity": "sha512-X5apsZ1SFW4FYTM19ISHf8005FJMPfrcf4U5rO0tdj+TeJgQgXuZ57IG0WeW7SpLVeBo8hM6WC8CovZh41AfnA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-linux-64": {
+ "version": "1.20250906.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20250906.0.tgz",
+ "integrity": "sha512-rlKzWgsLnlQ5Nt9W69YBJKcmTmZbOGu0edUsenXPmc6wzULUxoQpi7ZE9k3TfTonJx4WoQsQlzCUamRYFsX+0Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-linux-arm64": {
+ "version": "1.20250906.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20250906.0.tgz",
+ "integrity": "sha512-DdedhiQ+SeLzpg7BpcLrIPEZ33QKioJQ1wvL4X7nuLzEB9rWzS37NNNahQzc1+44rhG4fyiHbXBPOeox4B9XVA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-windows-64": {
+ "version": "1.20250906.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20250906.0.tgz",
+ "integrity": "sha512-Q8Qjfs8jGVILnZL6vUpQ90q/8MTCYaGR3d1LGxZMBqte8Vr7xF3KFHPEy7tFs0j0mMjnqCYzlofmPNY+9ZaDRg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz",
+ "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/android-arm": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz",
+ "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/android-arm64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz",
+ "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/android-x64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz",
+ "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz",
+ "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz",
+ "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz",
+ "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz",
+ "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-arm": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz",
+ "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz",
+ "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz",
+ "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz",
+ "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz",
+ "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz",
+ "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz",
+ "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz",
+ "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-x64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz",
+ "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz",
+ "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz",
+ "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz",
+ "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz",
+ "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz",
+ "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz",
+ "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz",
+ "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@esbuild/win32-x64": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz",
+ "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
+ "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.0.4"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-darwin-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz",
+ "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.0.4"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz",
+ "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz",
+ "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz",
+ "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz",
+ "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz",
+ "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz",
+ "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz",
+ "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz",
+ "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linux-arm": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz",
+ "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.0.5"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linux-arm64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz",
+ "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.0.4"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linux-s390x": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz",
+ "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.0.4"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linux-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz",
+ "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.0.4"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz",
+ "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.4"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz",
+ "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.4"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-wasm32": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz",
+ "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.2.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-win32-ia32": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz",
+ "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-win32-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz",
+ "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/acorn": {
+ "version": "8.14.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/esbuild": {
+ "version": "0.25.4",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz",
+ "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.4",
+ "@esbuild/android-arm": "0.25.4",
+ "@esbuild/android-arm64": "0.25.4",
+ "@esbuild/android-x64": "0.25.4",
+ "@esbuild/darwin-arm64": "0.25.4",
+ "@esbuild/darwin-x64": "0.25.4",
+ "@esbuild/freebsd-arm64": "0.25.4",
+ "@esbuild/freebsd-x64": "0.25.4",
+ "@esbuild/linux-arm": "0.25.4",
+ "@esbuild/linux-arm64": "0.25.4",
+ "@esbuild/linux-ia32": "0.25.4",
+ "@esbuild/linux-loong64": "0.25.4",
+ "@esbuild/linux-mips64el": "0.25.4",
+ "@esbuild/linux-ppc64": "0.25.4",
+ "@esbuild/linux-riscv64": "0.25.4",
+ "@esbuild/linux-s390x": "0.25.4",
+ "@esbuild/linux-x64": "0.25.4",
+ "@esbuild/netbsd-arm64": "0.25.4",
+ "@esbuild/netbsd-x64": "0.25.4",
+ "@esbuild/openbsd-arm64": "0.25.4",
+ "@esbuild/openbsd-x64": "0.25.4",
+ "@esbuild/sunos-x64": "0.25.4",
+ "@esbuild/win32-arm64": "0.25.4",
+ "@esbuild/win32-ia32": "0.25.4",
+ "@esbuild/win32-x64": "0.25.4"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/miniflare": {
+ "version": "4.20250906.2",
+ "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20250906.2.tgz",
+ "integrity": "sha512-SXGv8Rdd91b6UXZ5eW3rde/gSJM6WVLItMNFV7u9axUVhACvpT4CB5p80OBfi2OOsGfOuFQ6M6s8tMxJbzioVw==",
+ "license": "MIT",
+ "dependencies": {
+ "@cspotcode/source-map-support": "0.8.1",
+ "acorn": "8.14.0",
+ "acorn-walk": "8.3.2",
+ "exit-hook": "2.2.1",
+ "glob-to-regexp": "0.4.1",
+ "sharp": "^0.33.5",
+ "stoppable": "1.1.0",
+ "undici": "7.14.0",
+ "workerd": "1.20250906.0",
+ "ws": "8.18.0",
+ "youch": "4.1.0-beta.10",
+ "zod": "3.22.3"
+ },
+ "bin": {
+ "miniflare": "bootstrap.js"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/sharp": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz",
+ "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "color": "^4.2.3",
+ "detect-libc": "^2.0.3",
+ "semver": "^7.6.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.33.5",
+ "@img/sharp-darwin-x64": "0.33.5",
+ "@img/sharp-libvips-darwin-arm64": "1.0.4",
+ "@img/sharp-libvips-darwin-x64": "1.0.4",
+ "@img/sharp-libvips-linux-arm": "1.0.5",
+ "@img/sharp-libvips-linux-arm64": "1.0.4",
+ "@img/sharp-libvips-linux-s390x": "1.0.4",
+ "@img/sharp-libvips-linux-x64": "1.0.4",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.4",
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.4",
+ "@img/sharp-linux-arm": "0.33.5",
+ "@img/sharp-linux-arm64": "0.33.5",
+ "@img/sharp-linux-s390x": "0.33.5",
+ "@img/sharp-linux-x64": "0.33.5",
+ "@img/sharp-linuxmusl-arm64": "0.33.5",
+ "@img/sharp-linuxmusl-x64": "0.33.5",
+ "@img/sharp-wasm32": "0.33.5",
+ "@img/sharp-win32-ia32": "0.33.5",
+ "@img/sharp-win32-x64": "0.33.5"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/workerd": {
+ "version": "1.20250906.0",
+ "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20250906.0.tgz",
+ "integrity": "sha512-ryVyEaqXPPsr/AxccRmYZZmDAkfQVjhfRqrNTlEeN8aftBk6Ca1u7/VqmfOayjCXrA+O547TauebU+J3IpvFXw==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "workerd": "bin/workerd"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "optionalDependencies": {
+ "@cloudflare/workerd-darwin-64": "1.20250906.0",
+ "@cloudflare/workerd-darwin-arm64": "1.20250906.0",
+ "@cloudflare/workerd-linux-64": "1.20250906.0",
+ "@cloudflare/workerd-linux-arm64": "1.20250906.0",
+ "@cloudflare/workerd-windows-64": "1.20250906.0"
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/wrangler": {
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.37.0.tgz",
+ "integrity": "sha512-W8IbQohQbUHFn4Hz2kh8gi0SdyFV/jyi9Uus+WrTz0F0Dc9W5qKPCjLbxibeE53+YPHyoI25l65O7nSlwX+Z6Q==",
+ "license": "MIT OR Apache-2.0",
+ "dependencies": {
+ "@cloudflare/kv-asset-handler": "0.4.0",
+ "@cloudflare/unenv-preset": "2.7.3",
+ "blake3-wasm": "2.1.5",
+ "esbuild": "0.25.4",
+ "miniflare": "4.20250906.2",
+ "path-to-regexp": "6.3.0",
+ "unenv": "2.0.0-rc.21",
+ "workerd": "1.20250906.0"
+ },
+ "bin": {
+ "wrangler": "bin/wrangler.js",
+ "wrangler2": "bin/wrangler.js"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ },
+ "peerDependencies": {
+ "@cloudflare/workers-types": "^4.20250906.0"
+ },
+ "peerDependenciesMeta": {
+ "@cloudflare/workers-types": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@astrojs/cloudflare/node_modules/zod": {
+ "version": "3.22.3",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz",
+ "integrity": "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
"node_modules/@astrojs/compiler": {
"version": "2.13.0",
"resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.0.tgz",
@@ -378,6 +1423,15 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/runtime": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
+ "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/template": {
"version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
@@ -447,13 +1501,14 @@
}
},
"node_modules/@cloudflare/unenv-preset": {
- "version": "2.7.3",
- "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.7.3.tgz",
- "integrity": "sha512-tsQQagBKjvpd9baa6nWVIv399ejiqcrUBBW6SZx6Z22+ymm+Odv5+cFimyuCsD/fC1fQTwfRmwXBNpzvHSeGCw==",
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.7.4.tgz",
+ "integrity": "sha512-KIjbu/Dt50zseJIoOOK5y4eYpSojD9+xxkePYVK1Rg9k/p/st4YyMtz1Clju/zrenJHrOH+AAcjNArOPMwH4Bw==",
+ "dev": true,
"license": "MIT OR Apache-2.0",
"peerDependencies": {
"unenv": "2.0.0-rc.21",
- "workerd": "^1.20250828.1"
+ "workerd": "^1.20250912.0"
},
"peerDependenciesMeta": {
"workerd": {
@@ -462,12 +1517,13 @@
}
},
"node_modules/@cloudflare/workerd-darwin-64": {
- "version": "1.20250906.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20250906.0.tgz",
- "integrity": "sha512-E+X/YYH9BmX0ew2j/mAWFif2z05NMNuhCTlNYEGLkqMe99K15UewBqajL9pMcMUKxylnlrEoK3VNxl33DkbnPA==",
+ "version": "1.20250923.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20250923.0.tgz",
+ "integrity": "sha512-CUyVkdTaREdT/wynh5/VX3prawWpYeoqGjcEyo920/HqXaRuA/owp9ijg1vh1rmHyxN0XvsjHuRwBfnrptGmrg==",
"cpu": [
"x64"
],
+ "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -478,12 +1534,13 @@
}
},
"node_modules/@cloudflare/workerd-darwin-arm64": {
- "version": "1.20250906.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20250906.0.tgz",
- "integrity": "sha512-X5apsZ1SFW4FYTM19ISHf8005FJMPfrcf4U5rO0tdj+TeJgQgXuZ57IG0WeW7SpLVeBo8hM6WC8CovZh41AfnA==",
+ "version": "1.20250923.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20250923.0.tgz",
+ "integrity": "sha512-wblU5WYlNRnrTMupeWFRoysJH/Y7d6h+Wc1G+GTmaMV6TcxyXj804Hk8Tk3jqvaS0SXmkh5sIQ38MBVrBs7sag==",
"cpu": [
"arm64"
],
+ "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -494,12 +1551,13 @@
}
},
"node_modules/@cloudflare/workerd-linux-64": {
- "version": "1.20250906.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20250906.0.tgz",
- "integrity": "sha512-rlKzWgsLnlQ5Nt9W69YBJKcmTmZbOGu0edUsenXPmc6wzULUxoQpi7ZE9k3TfTonJx4WoQsQlzCUamRYFsX+0Q==",
+ "version": "1.20250923.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20250923.0.tgz",
+ "integrity": "sha512-WFP0KBJWhdDJWChIw3HJmrtYLNQDB8X9R3o548FcE5NiD05J0rI5Pnhno008lanjmXzia1lghWIQErfpjpmQzg==",
"cpu": [
"x64"
],
+ "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -510,12 +1568,13 @@
}
},
"node_modules/@cloudflare/workerd-linux-arm64": {
- "version": "1.20250906.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20250906.0.tgz",
- "integrity": "sha512-DdedhiQ+SeLzpg7BpcLrIPEZ33QKioJQ1wvL4X7nuLzEB9rWzS37NNNahQzc1+44rhG4fyiHbXBPOeox4B9XVA==",
+ "version": "1.20250923.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20250923.0.tgz",
+ "integrity": "sha512-h5VegEhn9CPfGnTc4JTFLGzR806naeIcKUHWi8ejc1hO38YthC6mBNsOjbZrSkp4B3H/kstuhuW16x2rGX0oBg==",
"cpu": [
"arm64"
],
+ "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -526,12 +1585,13 @@
}
},
"node_modules/@cloudflare/workerd-windows-64": {
- "version": "1.20250906.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20250906.0.tgz",
- "integrity": "sha512-Q8Qjfs8jGVILnZL6vUpQ90q/8MTCYaGR3d1LGxZMBqte8Vr7xF3KFHPEy7tFs0j0mMjnqCYzlofmPNY+9ZaDRg==",
+ "version": "1.20250923.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20250923.0.tgz",
+ "integrity": "sha512-S1E2Vm11ClrwHLqbVO59pKpxllHkq3APRdt3wCbVZNG7jGctxEYLH2uE0K1O1JBfbk2fKMaa+sbmtMpXDXi1tw==",
"cpu": [
"x64"
],
+ "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -1480,6 +2540,58 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "node_modules/@mapbox/jsonlint-lines-primitives": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz",
+ "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@mapbox/mapbox-gl-supported": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-3.0.0.tgz",
+ "integrity": "sha512-2XghOwu16ZwPJLOFVuIOaLbN0iKMn867evzXFyf0P22dqugezfJwLmdanAgU25ITvz1TvOfVP4jsDImlDJzcWg==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@mapbox/point-geometry": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-1.1.0.tgz",
+ "integrity": "sha512-YGcBz1cg4ATXDCM/71L9xveh4dynfGmcLDqufR+nQQy3fKwsAZsWd/x4621/6uJaeB9mwOHE6hPeDgXz9uViUQ==",
+ "license": "ISC"
+ },
+ "node_modules/@mapbox/tiny-sdf": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.7.tgz",
+ "integrity": "sha512-25gQLQMcpivjOSA40g3gO6qgiFPDpWRoMfd+G/GoppPIeP6JDaMMkMrEJnMZhKyyS6iKwVt5YKu02vCUyJM3Ug==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/@mapbox/unitbezier": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz",
+ "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/@mapbox/vector-tile": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-2.0.4.tgz",
+ "integrity": "sha512-AkOLcbgGTdXScosBWwmmD7cDlvOjkg/DetGva26pIRiZPdeJYjYKarIlb4uxVzi6bwHO6EWH82eZ5Nuv4T5DUg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@mapbox/point-geometry": "~1.1.0",
+ "@types/geojson": "^7946.0.16",
+ "pbf": "^4.0.1"
+ }
+ },
+ "node_modules/@mapbox/whoots-js": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz",
+ "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/@oslojs/encoding": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz",
@@ -2253,6 +3365,21 @@
"@types/node": "*"
}
},
+ "node_modules/@types/geojson": {
+ "version": "7946.0.16",
+ "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz",
+ "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/geojson-vt": {
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/@types/geojson-vt/-/geojson-vt-3.2.5.tgz",
+ "integrity": "sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/geojson": "*"
+ }
+ },
"node_modules/@types/hast": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
@@ -2262,6 +3389,29 @@
"@types/unist": "*"
}
},
+ "node_modules/@types/luxon": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.7.1.tgz",
+ "integrity": "sha512-H3iskjFIAn5SlJU7OuxUmTEpebK6TKB8rxZShDslBMZJ5u9S//KM1sbdAisiSrqwLQncVjnpi2OK2J51h+4lsg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/mapbox__point-geometry": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.4.tgz",
+ "integrity": "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/mapbox-gl": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-3.4.1.tgz",
+ "integrity": "sha512-NsGKKtgW93B+UaLPti6B7NwlxYlES5DpV5Gzj9F75rK5ALKsqSk15CiEHbOnTr09RGbr6ZYiCdI+59NNNcAImg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/geojson": "*"
+ }
+ },
"node_modules/@types/mdast": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
@@ -2295,6 +3445,12 @@
"undici-types": "~7.12.0"
}
},
+ "node_modules/@types/pbf": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz",
+ "integrity": "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==",
+ "license": "MIT"
+ },
"node_modules/@types/react": {
"version": "19.1.13",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.13.tgz",
@@ -2313,6 +3469,15 @@
"@types/react": "^19.0.0"
}
},
+ "node_modules/@types/supercluster": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz",
+ "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/geojson": "*"
+ }
+ },
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
@@ -2575,6 +3740,23 @@
"sharp": "^0.34.0"
}
},
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
+ "node_modules/axios": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
+ "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.4",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
"node_modules/axobject-query": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
@@ -2719,6 +3901,19 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/camelcase": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz",
@@ -2803,6 +3998,12 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/cheap-ruler": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cheap-ruler/-/cheap-ruler-4.0.0.tgz",
+ "integrity": "sha512-0BJa8f4t141BYKQyn9NSQt1PguFQXMXwZiA5shfoaBYHAb2fFk2RAX+tiWMoQU+Agtzt3mdt0JtuyshAXqZ+Vw==",
+ "license": "ISC"
+ },
"node_modules/chokidar": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
@@ -2842,6 +4043,12 @@
"node": ">=8"
}
},
+ "node_modules/classnames": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
+ "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
+ "license": "MIT"
+ },
"node_modules/cli-boxes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz",
@@ -2913,6 +4120,18 @@
"simple-swizzle": "^0.2.2"
}
},
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/comma-separated-tokens": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
@@ -2981,6 +4200,12 @@
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
}
},
+ "node_modules/csscolorparser": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
+ "integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==",
+ "license": "MIT"
+ },
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
@@ -3035,6 +4260,15 @@
"integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
"license": "MIT"
},
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/dequal": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
@@ -3120,6 +4354,26 @@
"node": ">=4"
}
},
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/earcut": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz",
+ "integrity": "sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ==",
+ "license": "ISC"
+ },
"node_modules/electron-to-chromium": {
"version": "1.5.223",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.223.tgz",
@@ -3166,12 +4420,57 @@
"url": "https://github.com/sponsors/antfu"
}
},
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/es-module-lexer": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
"integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
"license": "MIT"
},
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/esbuild": {
"version": "0.25.10",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz",
@@ -3305,6 +4604,26 @@
"node": ">=8"
}
},
+ "node_modules/follow-redirects": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
+ "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
"node_modules/fontace": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/fontace/-/fontace-0.3.0.tgz",
@@ -3332,6 +4651,22 @@
"unicode-trie": "^2.0.0"
}
},
+ "node_modules/form-data": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
+ "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -3346,6 +4681,15 @@
"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==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -3355,6 +4699,12 @@
"node": ">=6.9.0"
}
},
+ "node_modules/geojson-vt": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz",
+ "integrity": "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==",
+ "license": "ISC"
+ },
"node_modules/get-east-asian-width": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz",
@@ -3367,24 +4717,85 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/github-slugger": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
"integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==",
"license": "ISC"
},
+ "node_modules/gl-matrix": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.4.tgz",
+ "integrity": "sha512-latSnyDNt/8zYUB6VIJ6PCh2jBjJX6gnDsoCZ7LyW7GkqrD51EWwa9qCoGixj8YqBtETQK/xY7OmpTF8xz1DdQ==",
+ "license": "MIT"
+ },
"node_modules/glob-to-regexp": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
"license": "BSD-2-Clause"
},
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"license": "ISC"
},
+ "node_modules/grid-index": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/grid-index/-/grid-index-1.1.0.tgz",
+ "integrity": "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==",
+ "license": "ISC"
+ },
"node_modules/h3": {
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/h3/-/h3-1.15.4.tgz",
@@ -3402,6 +4813,45 @@
"uncrypto": "^0.1.3"
}
},
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/hast-util-from-html": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz",
@@ -3756,6 +5206,12 @@
"node": ">=6"
}
},
+ "node_modules/kdbush": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz",
+ "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==",
+ "license": "ISC"
+ },
"node_modules/kleur": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
@@ -4009,6 +5465,15 @@
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"license": "ISC"
},
+ "node_modules/luxon": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz",
+ "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/magic-string": {
"version": "0.30.19",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz",
@@ -4029,6 +5494,45 @@
"source-map-js": "^1.2.0"
}
},
+ "node_modules/mapbox-gl": {
+ "version": "3.15.0",
+ "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-3.15.0.tgz",
+ "integrity": "sha512-I42ffZpiXwt0PG3PO6gMYQnoz+AInkirLe/+zoHjcfBTFoFkKYtu5gFwT1WGeSvNrVTqG2Bwp9zUjPw0PFGY+w==",
+ "license": "SEE LICENSE IN LICENSE.txt",
+ "workspaces": [
+ "src/style-spec",
+ "test/build/typings"
+ ],
+ "dependencies": {
+ "@mapbox/jsonlint-lines-primitives": "^2.0.2",
+ "@mapbox/mapbox-gl-supported": "^3.0.0",
+ "@mapbox/point-geometry": "^1.1.0",
+ "@mapbox/tiny-sdf": "^2.0.6",
+ "@mapbox/unitbezier": "^0.0.1",
+ "@mapbox/vector-tile": "^2.0.4",
+ "@mapbox/whoots-js": "^3.1.0",
+ "@types/geojson": "^7946.0.16",
+ "@types/geojson-vt": "^3.2.5",
+ "@types/mapbox__point-geometry": "^0.1.4",
+ "@types/pbf": "^3.0.5",
+ "@types/supercluster": "^7.1.3",
+ "cheap-ruler": "^4.0.0",
+ "csscolorparser": "~1.0.3",
+ "earcut": "^3.0.1",
+ "geojson-vt": "^4.0.2",
+ "gl-matrix": "^3.4.4",
+ "grid-index": "^1.1.0",
+ "kdbush": "^4.0.2",
+ "martinez-polygon-clipping": "^0.7.4",
+ "murmurhash-js": "^1.0.0",
+ "pbf": "^4.0.1",
+ "potpack": "^2.0.0",
+ "quickselect": "^3.0.0",
+ "serialize-to-js": "^3.1.2",
+ "supercluster": "^8.0.1",
+ "tinyqueue": "^3.0.0"
+ }
+ },
"node_modules/markdown-table": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz",
@@ -4039,6 +5543,32 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/martinez-polygon-clipping": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/martinez-polygon-clipping/-/martinez-polygon-clipping-0.7.4.tgz",
+ "integrity": "sha512-jBEwrKtA0jTagUZj2bnmb4Yg2s4KnJGRePStgI7bAVjtcipKiF39R4LZ2V/UT61jMYWrTcBhPazexeqd6JAVtw==",
+ "license": "MIT",
+ "dependencies": {
+ "robust-predicates": "^2.0.4",
+ "splaytree": "^0.1.4",
+ "tinyqueue": "^1.2.0"
+ }
+ },
+ "node_modules/martinez-polygon-clipping/node_modules/tinyqueue": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-1.2.3.tgz",
+ "integrity": "sha512-Qz9RgWuO9l8lT+Y9xvbzhPT2efIUIFd69N7eF7tJ9lnQl0iLj1M7peK7IoUGZL9DJHw9XftqLreccfxcQgYLxA==",
+ "license": "ISC"
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/mdast-util-definitions": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz",
@@ -4845,10 +6375,32 @@
"node": ">=10.0.0"
}
},
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/miniflare": {
- "version": "4.20250906.2",
- "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20250906.2.tgz",
- "integrity": "sha512-SXGv8Rdd91b6UXZ5eW3rde/gSJM6WVLItMNFV7u9axUVhACvpT4CB5p80OBfi2OOsGfOuFQ6M6s8tMxJbzioVw==",
+ "version": "4.20250923.0",
+ "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20250923.0.tgz",
+ "integrity": "sha512-CtO0w3tKr8rl5nS5TchYNGQaXuYLfl1T+IqKQiEoIRAUpVWdiziK49+mKV+Vz6yRENqHEGMYV8EjhfvmEHrJpA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@cspotcode/source-map-support": "0.8.1",
@@ -4859,7 +6411,7 @@
"sharp": "^0.33.5",
"stoppable": "1.1.0",
"undici": "7.14.0",
- "workerd": "1.20250906.0",
+ "workerd": "1.20250923.0",
"ws": "8.18.0",
"youch": "4.1.0-beta.10",
"zod": "3.22.3"
@@ -4878,6 +6430,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -4900,6 +6453,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -4922,6 +6476,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -4938,6 +6493,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -4954,6 +6510,7 @@
"cpu": [
"arm"
],
+ "dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -4970,6 +6527,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -4986,6 +6544,7 @@
"cpu": [
"s390x"
],
+ "dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -5002,6 +6561,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -5018,6 +6578,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -5034,6 +6595,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -5050,6 +6612,7 @@
"cpu": [
"arm"
],
+ "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -5072,6 +6635,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -5094,6 +6658,7 @@
"cpu": [
"s390x"
],
+ "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -5116,6 +6681,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -5138,6 +6704,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -5160,6 +6727,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -5182,6 +6750,7 @@
"cpu": [
"wasm32"
],
+ "dev": true,
"license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
"optional": true,
"dependencies": {
@@ -5201,6 +6770,7 @@
"cpu": [
"ia32"
],
+ "dev": true,
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -5220,6 +6790,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -5236,6 +6807,7 @@
"version": "8.14.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
+ "dev": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -5248,6 +6820,7 @@
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz",
"integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==",
+ "dev": true,
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
@@ -5287,6 +6860,7 @@
"version": "3.22.3",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz",
"integrity": "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==",
+ "dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
@@ -5328,6 +6902,12 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
+ "node_modules/murmurhash-js": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz",
+ "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==",
+ "license": "MIT"
+ },
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
@@ -5546,6 +7126,18 @@
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
"license": "MIT"
},
+ "node_modules/pbf": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz",
+ "integrity": "sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "resolve-protobuf-schema": "^2.1.0"
+ },
+ "bin": {
+ "pbf": "bin/pbf"
+ }
+ },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -5592,6 +7184,12 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/potpack": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.1.0.tgz",
+ "integrity": "sha512-pcaShQc1Shq0y+E7GqJqvZj8DTthWV1KeHGdi0Z6IAin2Oi3JnLCOfwnCo84qc+HAp52wT9nK9H7FAJp5a44GQ==",
+ "license": "ISC"
+ },
"node_modules/prismjs": {
"version": "1.30.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
@@ -5633,12 +7231,62 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/protocol-buffers-schema": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz",
+ "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==",
+ "license": "MIT"
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
+ },
+ "node_modules/quickselect": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz",
+ "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==",
+ "license": "ISC"
+ },
"node_modules/radix3": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz",
"integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==",
"license": "MIT"
},
+ "node_modules/rc-slider": {
+ "version": "11.1.9",
+ "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-11.1.9.tgz",
+ "integrity": "sha512-h8IknhzSh3FEM9u8ivkskh+Ef4Yo4JRIY2nj7MrH6GQmrwV6mcpJf5/4KgH5JaVI1H3E52yCdpOlVyGZIeph5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.5",
+ "rc-util": "^5.36.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-util": {
+ "version": "5.44.4",
+ "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.44.4.tgz",
+ "integrity": "sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.18.3",
+ "react-is": "^18.2.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
"node_modules/react": {
"version": "19.1.1",
"resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz",
@@ -5660,6 +7308,12 @@
"react": "^19.1.1"
}
},
+ "node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "license": "MIT"
+ },
"node_modules/react-refresh": {
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
@@ -5848,6 +7502,15 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/resolve-protobuf-schema": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
+ "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "protocol-buffers-schema": "^3.3.1"
+ }
+ },
"node_modules/restructure": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/restructure/-/restructure-3.0.2.tgz",
@@ -5915,6 +7578,12 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/robust-predicates": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz",
+ "integrity": "sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg==",
+ "license": "Unlicense"
+ },
"node_modules/rollup": {
"version": "4.52.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.2.tgz",
@@ -5974,6 +7643,15 @@
"node": ">=10"
}
},
+ "node_modules/serialize-to-js": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/serialize-to-js/-/serialize-to-js-3.1.2.tgz",
+ "integrity": "sha512-owllqNuDDEimQat7EPG0tH7JjO090xKNzUtYz6X+Sk2BXDnOCilDdNLwjWeFywG9xkJul1ULvtUQa9O4pUaY0w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
"node_modules/sharp": {
"version": "0.34.4",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.4.tgz",
@@ -6079,6 +7757,12 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/splaytree": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/splaytree/-/splaytree-0.1.4.tgz",
+ "integrity": "sha512-D50hKrjZgBzqD3FT2Ek53f2dcDLAQT8SSGrzj3vidNH5ISRgceeGVJ2dQIthKOuayqFXfFjXheHNo4bbt9LhRQ==",
+ "license": "MIT"
+ },
"node_modules/stoppable": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz",
@@ -6135,6 +7819,15 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
+ "node_modules/supercluster": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz",
+ "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==",
+ "license": "ISC",
+ "dependencies": {
+ "kdbush": "^4.0.2"
+ }
+ },
"node_modules/supports-color": {
"version": "10.2.2",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz",
@@ -6219,6 +7912,12 @@
"url": "https://github.com/sponsors/SuperchupuDev"
}
},
+ "node_modules/tinyqueue": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz",
+ "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==",
+ "license": "ISC"
+ },
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@@ -6828,9 +8527,10 @@
}
},
"node_modules/workerd": {
- "version": "1.20250906.0",
- "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20250906.0.tgz",
- "integrity": "sha512-ryVyEaqXPPsr/AxccRmYZZmDAkfQVjhfRqrNTlEeN8aftBk6Ca1u7/VqmfOayjCXrA+O547TauebU+J3IpvFXw==",
+ "version": "1.20250923.0",
+ "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20250923.0.tgz",
+ "integrity": "sha512-avGZgJe3Vug0ff8oq5Hpa//x0dF9b12jKhDKqaEZaWl7mVGQk+GaA9lrO8TyJxzlfPIr/rXdvcRYJi/hbdgIJw==",
+ "dev": true,
"hasInstallScript": true,
"license": "Apache-2.0",
"bin": {
@@ -6840,27 +8540,28 @@
"node": ">=16"
},
"optionalDependencies": {
- "@cloudflare/workerd-darwin-64": "1.20250906.0",
- "@cloudflare/workerd-darwin-arm64": "1.20250906.0",
- "@cloudflare/workerd-linux-64": "1.20250906.0",
- "@cloudflare/workerd-linux-arm64": "1.20250906.0",
- "@cloudflare/workerd-windows-64": "1.20250906.0"
+ "@cloudflare/workerd-darwin-64": "1.20250923.0",
+ "@cloudflare/workerd-darwin-arm64": "1.20250923.0",
+ "@cloudflare/workerd-linux-64": "1.20250923.0",
+ "@cloudflare/workerd-linux-arm64": "1.20250923.0",
+ "@cloudflare/workerd-windows-64": "1.20250923.0"
}
},
"node_modules/wrangler": {
- "version": "4.37.0",
- "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.37.0.tgz",
- "integrity": "sha512-W8IbQohQbUHFn4Hz2kh8gi0SdyFV/jyi9Uus+WrTz0F0Dc9W5qKPCjLbxibeE53+YPHyoI25l65O7nSlwX+Z6Q==",
+ "version": "4.39.0",
+ "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.39.0.tgz",
+ "integrity": "sha512-DP/iJdxXiLCCSshCwsMl7PjOTZNJq5vzeN/hgEHHU7m85GIjPCLH0VvR/T2IFO5twyd4CukPveM4blhVUmRy2A==",
+ "dev": true,
"license": "MIT OR Apache-2.0",
"dependencies": {
"@cloudflare/kv-asset-handler": "0.4.0",
- "@cloudflare/unenv-preset": "2.7.3",
+ "@cloudflare/unenv-preset": "2.7.4",
"blake3-wasm": "2.1.5",
"esbuild": "0.25.4",
- "miniflare": "4.20250906.2",
+ "miniflare": "4.20250923.0",
"path-to-regexp": "6.3.0",
"unenv": "2.0.0-rc.21",
- "workerd": "1.20250906.0"
+ "workerd": "1.20250923.0"
},
"bin": {
"wrangler": "bin/wrangler.js",
@@ -6873,7 +8574,7 @@
"fsevents": "~2.3.2"
},
"peerDependencies": {
- "@cloudflare/workers-types": "^4.20250906.0"
+ "@cloudflare/workers-types": "^4.20250923.0"
},
"peerDependenciesMeta": {
"@cloudflare/workers-types": {
@@ -6888,6 +8589,7 @@
"cpu": [
"ppc64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6904,6 +8606,7 @@
"cpu": [
"arm"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6920,6 +8623,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6936,6 +8640,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6952,6 +8657,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6968,6 +8674,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6984,6 +8691,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7000,6 +8708,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7016,6 +8725,7 @@
"cpu": [
"arm"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7032,6 +8742,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7048,6 +8759,7 @@
"cpu": [
"ia32"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7064,6 +8776,7 @@
"cpu": [
"loong64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7080,6 +8793,7 @@
"cpu": [
"mips64el"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7096,6 +8810,7 @@
"cpu": [
"ppc64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7112,6 +8827,7 @@
"cpu": [
"riscv64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7128,6 +8844,7 @@
"cpu": [
"s390x"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7144,6 +8861,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7160,6 +8878,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7176,6 +8895,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7192,6 +8912,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7208,6 +8929,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7224,6 +8946,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7240,6 +8963,7 @@
"cpu": [
"arm64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7256,6 +8980,7 @@
"cpu": [
"ia32"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7272,6 +8997,7 @@
"cpu": [
"x64"
],
+ "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -7285,6 +9011,7 @@
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz",
"integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==",
+ "dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
diff --git a/package.json b/package.json
index 5792e0a..8e16464 100644
--- a/package.json
+++ b/package.json
@@ -15,8 +15,17 @@
"@types/react": "^19.1.13",
"@types/react-dom": "^19.1.9",
"astro": "^5.13.10",
+ "axios": "^1.12.2",
+ "luxon": "^3.7.2",
+ "mapbox-gl": "^3.15.0",
+ "rc-slider": "^11.1.9",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"tailwindcss": "^4.1.13"
+ },
+ "devDependencies": {
+ "@types/luxon": "^3.7.1",
+ "@types/mapbox-gl": "^3.4.1",
+ "wrangler": "^4.39.0"
}
}
diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png
new file mode 100644
index 0000000..7c93f47
--- /dev/null
+++ b/public/apple-touch-icon.png
Binary files differ
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..a97277e
--- /dev/null
+++ b/public/favicon.ico
Binary files differ
diff --git a/public/manifest.json b/public/manifest.json
new file mode 100644
index 0000000..20d2b0d
--- /dev/null
+++ b/public/manifest.json
@@ -0,0 +1,15 @@
+{
+ "short_name": "Geshem",
+ "name": "Geshem.space Rain Radar",
+ "icons": [
+ {
+ "src": "favicon.ico",
+ "sizes": "64x64 32x32 24x24 16x16",
+ "type": "image/x-icon"
+ }
+ ],
+ "start_url": ".",
+ "display": "standalone",
+ "theme_color": "#000000",
+ "background_color": "#ffffff"
+}
diff --git a/public/screenshot.png b/public/screenshot.png
new file mode 100644
index 0000000..7fd104c
--- /dev/null
+++ b/public/screenshot.png
Binary files differ
diff --git a/src/components/Datetime.tsx b/src/components/Datetime.tsx
new file mode 100644
index 0000000..2010f8b
--- /dev/null
+++ b/src/components/Datetime.tsx
@@ -0,0 +1,28 @@
+import React from "react";
+import { DateTime as LuxonDateTime } from "luxon";
+
+interface DateTimeProps {
+ images: string[];
+ slider: number;
+}
+
+export function DateTime({ images, slider }: DateTimeProps) {
+ let datetime: LuxonDateTime | null = null;
+
+ if (images.length > 0 && images[slider]) {
+ const ds = images[slider].substring(5, 18);
+ datetime = LuxonDateTime.fromFormat(ds, "yyyyMMdd/HHmm", {
+ zone: "utc",
+ }).setZone("Asia/Jerusalem");
+ }
+
+ const date = datetime ? datetime.toFormat("dd/MM/y") : "";
+ const time = datetime ? datetime.toFormat("HH:mm") : "";
+
+ return (
+ <div id="datetime">
+ <div id="date">{date}</div>
+ <div id="time">{time}</div>
+ </div>
+ );
+} \ No newline at end of file
diff --git a/src/components/Geshem.tsx b/src/components/Geshem.tsx
new file mode 100644
index 0000000..acd2bc6
--- /dev/null
+++ b/src/components/Geshem.tsx
@@ -0,0 +1,65 @@
+import React, { useState, useEffect } from "react";
+
+import { Map } from "./Map";
+import { Slider } from "./Slider";
+import { DateTime } from "./Datetime";
+
+import { IMAGES_BASE_URL, PLAYBACK_HOURS, PLAYBACK_SLOTS } from "../config";
+
+interface GeshemProps {
+ date?: string;
+}
+
+export function Geshem({ date }: GeshemProps) {
+ const [images, setImages] = useState<string[]>([]);
+ const [playback] = useState(
+ date ||
+ (typeof window !== 'undefined' ? new URL(window.location.toString()).searchParams.get("history") : null) ||
+ undefined
+ );
+ const [slider, setSlider] = useState(playback ? PLAYBACK_SLOTS : 9);
+
+ useEffect(() => {
+ const fetchImages = async () =>
+ fetch(`${IMAGES_BASE_URL}/imgs.json`)
+ .then(res => res.json())
+ .then(imgs => imgs["280"])
+ .then(setImages);
+
+ const buildPlayback = async () => {
+ const date = playback;
+ const hours = Array.from(Array(PLAYBACK_HOURS).keys()).map(
+ h => `${String(h).padStart(2, "0")}`
+ );
+ const minutes = Array.from(Array(6).keys()).map(
+ m => `${String(m * 10).padStart(2, "0")}`
+ );
+ const paths = hours.reduce<string[]>(
+ (acc, h) =>
+ acc.concat(minutes.map(m => `imgs/${date}/${h}${m}/280.png`)),
+ []
+ );
+ setImages(paths);
+ };
+
+ let timer: number;
+ if (playback) {
+ buildPlayback();
+ } else {
+ fetchImages();
+ timer = window.setInterval(fetchImages, 60 * 1000);
+ }
+
+ return () => {
+ if (timer !== undefined) clearInterval(timer);
+ };
+ }, [playback]);
+
+ return (
+ <>
+ <Map images={images} slider={slider} />
+ <DateTime images={images} slider={slider} />
+ <Slider slider={slider} playback={playback} setSlider={setSlider} />
+ </>
+ );
+} \ No newline at end of file
diff --git a/src/components/Map.tsx b/src/components/Map.tsx
new file mode 100644
index 0000000..0e39308
--- /dev/null
+++ b/src/components/Map.tsx
@@ -0,0 +1,108 @@
+import React, { useState, useEffect, useRef } from "react";
+import mapboxgl from 'mapbox-gl';
+
+import {
+ MAPBOX_ACCESS_TOKEN,
+ IMAGE_COORDINATES,
+ IMAGES_BASE_URL
+} from "../config";
+
+import "mapbox-gl/dist/mapbox-gl.css";
+
+interface MapProps {
+ slider: number;
+ images: string[];
+}
+
+export function Map({ slider, images }: MapProps) {
+ const mapContainer = useRef<HTMLDivElement>(null);
+ const map = useRef<mapboxgl.Map | null>(null);
+
+ const [lng] = useState(35);
+ const [lat] = useState(31.9);
+ const [zoom] = useState(6.3);
+ const [loaded, setLoaded] = useState(false);
+
+ const prevImages = useRef(images).current;
+
+ useEffect(() => {
+ if (map.current || !mapContainer.current) return;
+
+ map.current = new mapboxgl.Map({
+ accessToken: MAPBOX_ACCESS_TOKEN,
+ container: mapContainer.current,
+ style: "mapbox://styles/mapbox/dark-v9",
+ center: [lng, lat],
+ zoom: zoom,
+ minZoom: 5,
+ maxZoom: 10,
+ hash: false,
+ });
+
+ map.current.on("style.load", () => {
+ setLoaded(true);
+ });
+ }, [lng, lat, zoom]);
+
+ useEffect(() => {
+ if (!loaded || !map.current) return;
+
+ // remove old layers
+ prevImages.forEach((img) => {
+ if (!images.includes(img)) {
+ if (map.current?.getLayer(`layer-${img}`)) {
+ map.current.removeLayer(`layer-${img}`);
+ }
+ if (map.current?.getSource(`source-${img}`)) {
+ map.current.removeSource(`source-${img}`);
+ }
+ }
+ });
+
+ // add new layers
+ images.forEach((img, i) => {
+ if (!prevImages.includes(img) && !map.current?.getSource(`source-${img}`)) {
+ map.current?.addSource(`source-${img}`, {
+ type: "image",
+ url: `${IMAGES_BASE_URL}/${img}`,
+ coordinates: IMAGE_COORDINATES
+ });
+ map.current?.addLayer({
+ id: `layer-${img}`,
+ source: `source-${img}`,
+ type: "raster",
+ paint: {
+ "raster-opacity": 0,
+ "raster-opacity-transition": {
+ duration: 0
+ }
+ }
+ });
+ }
+ });
+ }, [loaded, prevImages, images]);
+
+ useEffect(() => {
+ if (!loaded || !images.length || !map.current) return;
+
+ if (images[slider]) {
+ map.current.setPaintProperty(`layer-${images[slider]}`, "raster-opacity", 0.85);
+ }
+
+ return () => {
+ // callback will hide the previous layer with the previous slider value
+ if (images[slider] && map.current?.getLayer(`layer-${images[slider]}`)) {
+ map.current.setPaintProperty(`layer-${images[slider]}`, "raster-opacity", 0);
+ }
+ };
+ }, [loaded, slider, images]);
+
+ return (
+ <div>
+ <div ref={mapContainer} className="map-container" style={{
+ height: "100vh",
+ width: "100vw"
+ }} />
+ </div>
+ );
+} \ No newline at end of file
diff --git a/src/components/Slider.tsx b/src/components/Slider.tsx
new file mode 100644
index 0000000..2ee3fa1
--- /dev/null
+++ b/src/components/Slider.tsx
@@ -0,0 +1,43 @@
+import React from "react";
+import RcSlider from 'rc-slider';
+import { PLAYBACK_SLOTS } from "../config";
+import "rc-slider/assets/index.css";
+
+interface GeshemSliderProps {
+ playback?: string;
+ slider: number;
+ setSlider: React.Dispatch<React.SetStateAction<number>>;
+}
+
+export function Slider({ playback, slider, setSlider }: GeshemSliderProps) {
+ const handleStyle = {
+ height: 40,
+ width: 40,
+ border: 0,
+ marginTop: -10,
+ boxShadow: ".5px .5px 2px 1px rgba(0,0,0,.32)"
+ };
+
+ const railStyle = {
+ height: 20,
+ backgroundColor: "#3498db"
+ };
+
+ const trackStyle = {
+ display: "none"
+ };
+
+ return (
+ <div id="slider">
+ <RcSlider
+ min={0}
+ max={playback ? PLAYBACK_SLOTS : 9}
+ defaultValue={slider}
+ handleStyle={handleStyle}
+ railStyle={railStyle}
+ trackStyle={trackStyle}
+ onChange={(val) => setSlider(val as number)}
+ />
+ </div>
+ );
+} \ No newline at end of file
diff --git a/src/config.ts b/src/config.ts
new file mode 100644
index 0000000..6d838be
--- /dev/null
+++ b/src/config.ts
@@ -0,0 +1,19 @@
+const hostname = typeof window !== 'undefined' && window.location && window.location.hostname;
+
+const PRODUCTION = hostname ? hostname.includes("geshem") : false;
+
+export const IMAGES_BASE_URL = PRODUCTION ? "https://imgs.geshem.space" : "";
+
+export const MAPBOX_ACCESS_TOKEN =
+ "pk.eyJ1IjoieXV2YWRtIiwiYSI6ImNpcnMxbzBuaTAwZWdoa25oczlzZmkwbHcifQ.UHtLngbKm9O8945pJm23Nw";
+
+export const IMAGE_COORDINATES: [number, number][] = [
+ [31.7503896894, 34.4878044232],
+ [37.8574239563, 34.5078463729],
+ [37.7157066403, 29.4538271687],
+ [31.9347389087, 29.4373462909]
+];
+
+export const PLAYBACK_HOURS = 2;
+
+export const PLAYBACK_SLOTS = (PLAYBACK_HOURS * 6) - 1; \ No newline at end of file
diff --git a/src/functions/scheduled.ts b/src/functions/scheduled.ts
new file mode 100644
index 0000000..5aa3fa0
--- /dev/null
+++ b/src/functions/scheduled.ts
@@ -0,0 +1,178 @@
+// Cloudflare Workers scheduled handler for cron jobs
+import type { ScheduledController, ScheduledEvent } from '@cloudflare/workers-types';
+
+interface Env {
+ BASE_URL: string;
+ AUTH_USER: string;
+ AUTH_PASS: string;
+ IMGS_BUCKET: R2Bucket;
+}
+
+interface ImageData {
+ [key: string]: string[];
+}
+
+class GeshemUpdate {
+ private bucket: R2Bucket;
+ private env: Env;
+
+ constructor(bucket: R2Bucket, env: Env) {
+ this.bucket = bucket;
+ this.env = env;
+ }
+
+ private async authenticate(request: Request): Promise<Request> {
+ const headers = new Headers(request.headers);
+ const credentials = btoa(`${this.env.AUTH_USER}:${this.env.AUTH_PASS}`);
+ headers.set('Authorization', `Basic ${credentials}`);
+
+ return new Request(request.url, {
+ method: request.method,
+ headers,
+ body: request.body
+ });
+ }
+
+ private async getLatestImages(): Promise<string[]> {
+ const authenticatedRequest = await this.authenticate(new Request(this.env.BASE_URL));
+ const response = await fetch(authenticatedRequest);
+ const html = await response.text();
+
+ const regex = /radar280comp_\d+\.png/g;
+ const matches = html.match(regex) || [];
+ const uniqueImages = [...new Set(matches)];
+
+ return uniqueImages.sort().slice(-10);
+ }
+
+ private async getLatestBucketKeys(): Promise<string[]> {
+ const yesterday = new Date();
+ yesterday.setDate(yesterday.getDate() - 1);
+ const yesterdayStr = yesterday.toISOString().slice(0, 10).replace(/-/g, '');
+
+ try {
+ const objects = await this.bucket.list({
+ prefix: 'imgs/',
+ startAfter: `imgs/${yesterdayStr}`
+ });
+
+ return objects.objects.map(obj => obj.key);
+ } catch (error) {
+ console.error('Error listing bucket objects:', error);
+ return [];
+ }
+ }
+
+ private async fetchMissingImages(): Promise<boolean> {
+ const images = await this.getLatestImages();
+ const s3Images = await this.getLatestBucketKeys();
+ let updated = false;
+
+ for (const img of images) {
+ const key = this.keyFromFilename(img);
+ if (!s3Images.includes(key)) {
+ await this.fetchImage(img, key);
+ updated = true;
+ }
+ }
+
+ return updated;
+ }
+
+ private async fetchImage(imgName: string, key: string): Promise<void> {
+ console.log(`Downloading ${imgName} from web server`);
+
+ const imageUrl = `${this.env.BASE_URL}/${imgName}`;
+ const authenticatedRequest = await this.authenticate(new Request(imageUrl));
+ const response = await fetch(authenticatedRequest);
+
+ if (!response.ok) {
+ throw new Error(`Failed to fetch image: ${response.statusText}`);
+ }
+
+ const imageData = await response.arrayBuffer();
+
+ console.log(`Uploading to ${key}`);
+ await this.bucket.put(key, imageData, {
+ httpMetadata: {
+ contentType: 'image/png',
+ cacheControl: 'public, max-age=31536000'
+ }
+ });
+ }
+
+ private keyFromFilename(filename: string): string {
+ const [name, dateStr] = filename.split('.')[0].split('_');
+ const res = 280;
+
+ // Parse date: YYYYMMDDHHMM
+ const year = dateStr.slice(0, 4);
+ const month = dateStr.slice(4, 6);
+ const day = dateStr.slice(6, 8);
+ const hour = dateStr.slice(8, 10);
+ const minute = dateStr.slice(10, 12);
+
+ const d = `${year}${month}${day}`;
+ const t = `${hour}${minute}`;
+
+ return `imgs/${d}/${t}/${res}.png`;
+ }
+
+ private async generateJson(): Promise<void> {
+ const latestKeys = await this.getLatestBucketKeys();
+ const keys = latestKeys
+ .filter(key => key.endsWith('280.png'))
+ .sort()
+ .slice(-10);
+
+ const index: ImageData = { '280': keys };
+
+ await this.bucket.put('imgs.json', JSON.stringify(index), {
+ httpMetadata: {
+ contentType: 'application/json',
+ cacheControl: 'public, max-age=60'
+ }
+ });
+ }
+
+ async run(): Promise<string> {
+ try {
+ const updated = await this.fetchMissingImages();
+ if (updated) {
+ await this.generateJson();
+ }
+ return `Updated: ${updated}`;
+ } catch (error) {
+ console.error('Error in GeshemUpdate.run():', error);
+ throw error;
+ }
+ }
+}
+
+export default {
+ async scheduled(
+ controller: ScheduledController,
+ env: Env,
+ ctx: ExecutionContext
+ ): Promise<void> {
+ console.log('Cron job triggered at', new Date().toISOString());
+
+ try {
+ if (!env?.BASE_URL || !env?.AUTH_USER || !env?.AUTH_PASS) {
+ throw new Error('Missing environment variables');
+ }
+
+ if (!env.IMGS_BUCKET) {
+ throw new Error('R2 bucket not configured');
+ }
+
+ const updater = new GeshemUpdate(env.IMGS_BUCKET, env);
+ const result = await updater.run();
+
+ console.log(`Cron job completed: ${result}`);
+ } catch (error) {
+ console.error('Error in scheduled function:', error);
+ throw error;
+ }
+ }
+}; \ No newline at end of file
diff --git a/src/pages/404.astro b/src/pages/404.astro
new file mode 100644
index 0000000..4db6121
--- /dev/null
+++ b/src/pages/404.astro
@@ -0,0 +1,67 @@
+---
+---
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="shortcut icon" href="/favicon.ico">
+ <title>404 - Page Not Found | geshem.space</title>
+ <style>
+ body {
+ margin: 0;
+ padding: 0;
+ background-color: #1a1a1a;
+ color: white;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
+ "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ text-align: center;
+ }
+
+ .container {
+ max-width: 500px;
+ }
+
+ h1 {
+ font-size: 6rem;
+ margin: 0;
+ font-weight: bold;
+ opacity: 0.8;
+ }
+
+ h2 {
+ font-size: 1.5rem;
+ margin: 1rem 0;
+ font-weight: normal;
+ }
+
+ p {
+ margin: 1rem 0;
+ opacity: 0.7;
+ line-height: 1.5;
+ }
+
+ a {
+ color: #3498db;
+ text-decoration: none;
+ font-weight: 500;
+ }
+
+ a:hover {
+ text-decoration: underline;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="container">
+ <h1>404</h1>
+ <h2>Page Not Found</h2>
+ <p>The page you're looking for doesn't exist.</p>
+ <p><a href="/">← Back to Rain Radar</a></p>
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/src/pages/api/update.ts b/src/pages/api/update.ts
new file mode 100644
index 0000000..88dfa3c
--- /dev/null
+++ b/src/pages/api/update.ts
@@ -0,0 +1,200 @@
+import type { APIRoute } from 'astro';
+
+export const prerender = false;
+
+interface ImageData {
+ [key: string]: string[];
+}
+
+interface CloudflareEnv {
+ BASE_URL: string;
+ AUTH_USER: string;
+ AUTH_PASS: string;
+ BUCKET_NAME: string;
+ SCHEDULED?: boolean;
+}
+
+class GeshemUpdate {
+ private bucket: R2Bucket;
+ private env: CloudflareEnv;
+
+ constructor(bucket: R2Bucket, env: CloudflareEnv) {
+ this.bucket = bucket;
+ this.env = env;
+ }
+
+ private async authenticate(request: Request): Promise<Request> {
+ const headers = new Headers(request.headers);
+ const credentials = btoa(`${this.env.AUTH_USER}:${this.env.AUTH_PASS}`);
+ headers.set('Authorization', `Basic ${credentials}`);
+
+ return new Request(request.url, {
+ method: request.method,
+ headers,
+ body: request.body
+ });
+ }
+
+ private async getLatestImages(): Promise<string[]> {
+ const authenticatedRequest = await this.authenticate(new Request(this.env.BASE_URL));
+ const response = await fetch(authenticatedRequest);
+ const html = await response.text();
+
+ const regex = /radar280comp_\d+\.png/g;
+ const matches = html.match(regex) || [];
+ const uniqueImages = [...new Set(matches)];
+
+ return uniqueImages.sort().slice(-10);
+ }
+
+ private async getLatestBucketKeys(): Promise<string[]> {
+ const yesterday = new Date();
+ yesterday.setDate(yesterday.getDate() - 1);
+ const yesterdayStr = yesterday.toISOString().slice(0, 10).replace(/-/g, '');
+
+ try {
+ const objects = await this.bucket.list({
+ prefix: 'imgs/',
+ startAfter: `imgs/${yesterdayStr}`
+ });
+
+ return objects.objects.map(obj => obj.key);
+ } catch (error) {
+ console.error('Error listing bucket objects:', error);
+ return [];
+ }
+ }
+
+ private async fetchMissingImages(): Promise<boolean> {
+ const images = await this.getLatestImages();
+ const s3Images = await this.getLatestBucketKeys();
+ let updated = false;
+
+ for (const img of images) {
+ const key = this.keyFromFilename(img);
+ if (!s3Images.includes(key)) {
+ await this.fetchImage(img, key);
+ updated = true;
+ }
+ }
+
+ return updated;
+ }
+
+ private async fetchImage(imgName: string, key: string): Promise<void> {
+ console.log(`Downloading ${imgName} from web server`);
+
+ const imageUrl = `${this.env.BASE_URL}/${imgName}`;
+ const authenticatedRequest = await this.authenticate(new Request(imageUrl));
+ const response = await fetch(authenticatedRequest);
+
+ if (!response.ok) {
+ throw new Error(`Failed to fetch image: ${response.statusText}`);
+ }
+
+ const imageData = await response.arrayBuffer();
+
+ console.log(`Uploading to ${key}`);
+ await this.bucket.put(key, imageData, {
+ httpMetadata: {
+ contentType: 'image/png',
+ cacheControl: 'public, max-age=31536000'
+ }
+ });
+ }
+
+ private keyFromFilename(filename: string): string {
+ const [name, dateStr] = filename.split('.')[0].split('_');
+ const res = 280;
+
+ // Parse date: YYYYMMDDHHMM
+ const year = dateStr.slice(0, 4);
+ const month = dateStr.slice(4, 6);
+ const day = dateStr.slice(6, 8);
+ const hour = dateStr.slice(8, 10);
+ const minute = dateStr.slice(10, 12);
+
+ const d = `${year}${month}${day}`;
+ const t = `${hour}${minute}`;
+
+ return `imgs/${d}/${t}/${res}.png`;
+ }
+
+ private async generateJson(): Promise<void> {
+ const latestKeys = await this.getLatestBucketKeys();
+ const keys = latestKeys
+ .filter(key => key.endsWith('280.png'))
+ .sort()
+ .slice(-10);
+
+ const index: ImageData = { '280': keys };
+
+ await this.bucket.put('imgs.json', JSON.stringify(index), {
+ httpMetadata: {
+ contentType: 'application/json',
+ cacheControl: 'public, max-age=60'
+ }
+ });
+ }
+
+ async run(): Promise<string> {
+ try {
+ const updated = await this.fetchMissingImages();
+ if (updated) {
+ await this.generateJson();
+ }
+ return `Updated: ${updated}`;
+ } catch (error) {
+ console.error('Error in GeshemUpdate.run():', error);
+ throw error;
+ }
+ }
+}
+
+export const GET: APIRoute = async ({ platform, request }) => {
+ // This endpoint should only be accessible via Cloudflare Cron
+ const cron = request.headers.get('CF-Cron');
+ if (!cron) {
+ return new Response('Unauthorized', { status: 401 });
+ }
+
+ try {
+ const env = platform?.env as unknown as CloudflareEnv;
+
+ if (!env?.BASE_URL || !env?.AUTH_USER || !env?.AUTH_PASS) {
+ return new Response('Missing environment variables', { status: 500 });
+ }
+
+ // Get R2 bucket (this would be configured in your Cloudflare Workers environment)
+ const bucket = env.BUCKET_NAME ? platform?.env[env.BUCKET_NAME] as R2Bucket : null;
+
+ if (!bucket) {
+ return new Response('R2 bucket not configured', { status: 500 });
+ }
+
+ const updater = new GeshemUpdate(bucket, env);
+ const result = await updater.run();
+
+ return new Response(JSON.stringify({
+ message: `SUCCESS: ${result}`,
+ timestamp: new Date().toISOString()
+ }), {
+ status: 200,
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ });
+
+ } catch (error) {
+ console.error('Error in update handler:', error);
+ return new Response(JSON.stringify({
+ message: 'ERROR',
+ error: error instanceof Error ? error.message : 'Unknown error'
+ }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ });
+ }
+}; \ No newline at end of file
diff --git a/src/pages/history/[date].astro b/src/pages/history/[date].astro
new file mode 100644
index 0000000..0bd1e40
--- /dev/null
+++ b/src/pages/history/[date].astro
@@ -0,0 +1,23 @@
+---
+import { Geshem } from '../../components/Geshem';
+import '../../styles/global.css';
+import '../../styles/geshem.css';
+
+export const prerender = false;
+
+const { date } = Astro.params;
+---
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <link rel="icon" type="image/png" href="/favicon.png" />
+ <meta name="viewport" content="width=device-width" />
+ <meta name="generator" content={Astro.generator} />
+ <title>Geshem - Rain Radar History</title>
+ <meta name="description" content="Israel Rain Radar History" />
+ </head>
+ <body>
+ <Geshem client:load date={date} />
+ </body>
+</html> \ No newline at end of file
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 2d14107..fb90246 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,16 +1,21 @@
---
+import { Geshem } from '../components/Geshem';
+import '../styles/global.css';
+import '../styles/geshem.css';
+const { date } = Astro.params;
---
<html lang="en">
<head>
<meta charset="utf-8" />
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+ <link rel="icon" type="image/png" href="/favicon.png" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
- <title>Astro</title>
+ <title>Geshem - Rain Radar</title>
+ <meta name="description" content="Israel Rain Radar" />
</head>
<body>
- <h1>Astro</h1>
+ <Geshem client:load date={date} />
</body>
</html>
diff --git a/src/pages/privacy.astro b/src/pages/privacy.astro
new file mode 100644
index 0000000..12ac001
--- /dev/null
+++ b/src/pages/privacy.astro
@@ -0,0 +1,38 @@
+---
+
+---
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <meta
+ name="viewport"
+ content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
+ />
+ <meta name="apple-mobile-web-app-title" content="Geshem" />
+ <meta name="apple-mobile-web-app-capable" content="yes" />
+ <meta name="theme-color" content="#000000" />
+ <link rel="shortcut icon" href="/favicon.ico" />
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
+ <link rel="manifest" href="/manifest.json" />
+ <title>Privacy Policy | geshem.space</title>
+ <style>
+ body {
+ overflow: hidden;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-family: sans-serif;
+ background-color: #1a1a1a;
+ color: white;
+ margin: 0;
+ }
+ </style>
+ </head>
+ <body>
+ <h1>We do not collect any data.</h1>
+ </body>
+</html>
diff --git a/src/styles/geshem.css b/src/styles/geshem.css
new file mode 100644
index 0000000..2dba79f
--- /dev/null
+++ b/src/styles/geshem.css
@@ -0,0 +1,45 @@
+#datetime {
+ position: absolute;
+ top: 20px;
+ left: 20px;
+ color: white;
+ font-family: monospace;
+}
+
+#date {
+ font-size: 1.4em;
+}
+
+#time {
+ font-size: 2.8em;
+}
+
+#slider {
+ position: fixed;
+ bottom: 8vh;
+ width: 30vw;
+ margin-left: 35vw;
+}
+
+@media only screen and (max-device-width: 812px) {
+ #slider {
+ width: 80vw;
+ margin-left: 8vw;
+ z-index: 10;
+ }
+}
+
+body {
+ margin: 0;
+ padding: 0;
+ position: fixed;
+ overflow: hidden;
+ width: 100vw;
+ height: 100vh;
+ user-select: none;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
+ "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
+ sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+} \ No newline at end of file