diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | deno.lock | 834 | ||||
| -rw-r--r-- | index.html | 15 | ||||
| -rw-r--r-- | package.json | 21 | ||||
| -rw-r--r-- | src/components/Button.module.css | 29 | ||||
| -rw-r--r-- | src/components/Button.tsx | 57 | ||||
| -rw-r--r-- | src/components/Timer.module.css | 63 | ||||
| -rw-r--r-- | src/components/Timer.tsx | 178 | ||||
| -rw-r--r-- | src/helpers/api.ts | 103 | ||||
| -rw-r--r-- | src/index.css | 6 | ||||
| -rw-r--r-- | src/index.tsx | 17 | ||||
| -rw-r--r-- | src/pages/*.tsx | 8 | ||||
| -rw-r--r-- | src/pages/index.module.css | 14 | ||||
| -rw-r--r-- | src/pages/index.tsx | 33 | ||||
| -rw-r--r-- | src/vite.env.d.ts | 2 | ||||
| -rw-r--r-- | tsconfig.json | 17 | ||||
| -rw-r--r-- | vite.config.ts | 25 |
17 files changed, 1424 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..76add87 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +dist
\ No newline at end of file diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..8d7d064 --- /dev/null +++ b/deno.lock @@ -0,0 +1,834 @@ +{ + "version": "4", + "specifiers": { + "npm:@solidjs/router@~0.15.1": "0.15.3_solid-js@1.9.5__seroval@1.2.1", + "npm:solid-js@^1.9.5": "1.9.5_seroval@1.2.1", + "npm:vite-plugin-pages@~0.32.4": "0.32.5_vite@6.3.1__picomatch@4.0.2__yaml@2.7.1_yaml@2.7.1", + "npm:vite-plugin-solid@^2.11.6": "2.11.6_solid-js@1.9.5__seroval@1.2.1_vite@6.3.1__picomatch@4.0.2__yaml@2.7.1_@babel+core@7.26.10", + "npm:vite@6": "6.3.1_picomatch@4.0.2_yaml@2.7.1" + }, + "npm": { + "@ampproject/remapping@2.3.0": { + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": [ + "@jridgewell/gen-mapping", + "@jridgewell/trace-mapping" + ] + }, + "@babel/code-frame@7.26.2": { + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dependencies": [ + "@babel/helper-validator-identifier", + "js-tokens", + "picocolors" + ] + }, + "@babel/compat-data@7.26.8": { + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==" + }, + "@babel/core@7.26.10": { + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "dependencies": [ + "@ampproject/remapping", + "@babel/code-frame", + "@babel/generator", + "@babel/helper-compilation-targets", + "@babel/helper-module-transforms", + "@babel/helpers", + "@babel/parser", + "@babel/template", + "@babel/traverse", + "@babel/types", + "convert-source-map", + "debug", + "gensync", + "json5", + "semver" + ] + }, + "@babel/generator@7.27.0": { + "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", + "dependencies": [ + "@babel/parser", + "@babel/types", + "@jridgewell/gen-mapping", + "@jridgewell/trace-mapping", + "jsesc" + ] + }, + "@babel/helper-compilation-targets@7.27.0": { + "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", + "dependencies": [ + "@babel/compat-data", + "@babel/helper-validator-option", + "browserslist", + "lru-cache", + "semver" + ] + }, + "@babel/helper-module-imports@7.18.6": { + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dependencies": [ + "@babel/types" + ] + }, + "@babel/helper-module-imports@7.25.9": { + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dependencies": [ + "@babel/traverse", + "@babel/types" + ] + }, + "@babel/helper-module-transforms@7.26.0_@babel+core@7.26.10": { + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dependencies": [ + "@babel/core", + "@babel/helper-module-imports@7.25.9", + "@babel/helper-validator-identifier", + "@babel/traverse" + ] + }, + "@babel/helper-plugin-utils@7.26.5": { + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==" + }, + "@babel/helper-string-parser@7.25.9": { + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==" + }, + "@babel/helper-validator-identifier@7.25.9": { + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==" + }, + "@babel/helper-validator-option@7.25.9": { + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==" + }, + "@babel/helpers@7.27.0": { + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", + "dependencies": [ + "@babel/template", + "@babel/types" + ] + }, + "@babel/parser@7.27.0": { + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", + "dependencies": [ + "@babel/types" + ] + }, + "@babel/plugin-syntax-jsx@7.25.9_@babel+core@7.26.10": { + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", + "dependencies": [ + "@babel/core", + "@babel/helper-plugin-utils" + ] + }, + "@babel/template@7.27.0": { + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", + "dependencies": [ + "@babel/code-frame", + "@babel/parser", + "@babel/types" + ] + }, + "@babel/traverse@7.27.0": { + "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", + "dependencies": [ + "@babel/code-frame", + "@babel/generator", + "@babel/parser", + "@babel/template", + "@babel/types", + "debug", + "globals" + ] + }, + "@babel/types@7.27.0": { + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", + "dependencies": [ + "@babel/helper-string-parser", + "@babel/helper-validator-identifier" + ] + }, + "@esbuild/aix-ppc64@0.25.2": { + "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==" + }, + "@esbuild/android-arm64@0.25.2": { + "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==" + }, + "@esbuild/android-arm@0.25.2": { + "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==" + }, + "@esbuild/android-x64@0.25.2": { + "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==" + }, + "@esbuild/darwin-arm64@0.25.2": { + "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==" + }, + "@esbuild/darwin-x64@0.25.2": { + "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==" + }, + "@esbuild/freebsd-arm64@0.25.2": { + "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==" + }, + "@esbuild/freebsd-x64@0.25.2": { + "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==" + }, + "@esbuild/linux-arm64@0.25.2": { + "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==" + }, + "@esbuild/linux-arm@0.25.2": { + "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==" + }, + "@esbuild/linux-ia32@0.25.2": { + "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==" + }, + "@esbuild/linux-loong64@0.25.2": { + "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==" + }, + "@esbuild/linux-mips64el@0.25.2": { + "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==" + }, + "@esbuild/linux-ppc64@0.25.2": { + "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==" + }, + "@esbuild/linux-riscv64@0.25.2": { + "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==" + }, + "@esbuild/linux-s390x@0.25.2": { + "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==" + }, + "@esbuild/linux-x64@0.25.2": { + "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==" + }, + "@esbuild/netbsd-arm64@0.25.2": { + "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==" + }, + "@esbuild/netbsd-x64@0.25.2": { + "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==" + }, + "@esbuild/openbsd-arm64@0.25.2": { + "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==" + }, + "@esbuild/openbsd-x64@0.25.2": { + "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==" + }, + "@esbuild/sunos-x64@0.25.2": { + "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==" + }, + "@esbuild/win32-arm64@0.25.2": { + "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==" + }, + "@esbuild/win32-ia32@0.25.2": { + "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==" + }, + "@esbuild/win32-x64@0.25.2": { + "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==" + }, + "@jridgewell/gen-mapping@0.3.8": { + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dependencies": [ + "@jridgewell/set-array", + "@jridgewell/sourcemap-codec", + "@jridgewell/trace-mapping" + ] + }, + "@jridgewell/resolve-uri@3.1.2": { + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" + }, + "@jridgewell/set-array@1.2.1": { + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" + }, + "@jridgewell/sourcemap-codec@1.5.0": { + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "@jridgewell/trace-mapping@0.3.25": { + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": [ + "@jridgewell/resolve-uri", + "@jridgewell/sourcemap-codec" + ] + }, + "@nodelib/fs.scandir@2.1.5": { + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": [ + "@nodelib/fs.stat", + "run-parallel" + ] + }, + "@nodelib/fs.stat@2.0.5": { + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk@1.2.8": { + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": [ + "@nodelib/fs.scandir", + "fastq" + ] + }, + "@rollup/rollup-android-arm-eabi@4.40.0": { + "integrity": "sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==" + }, + "@rollup/rollup-android-arm64@4.40.0": { + "integrity": "sha512-PPA6aEEsTPRz+/4xxAmaoWDqh67N7wFbgFUJGMnanCFs0TV99M0M8QhhaSCks+n6EbQoFvLQgYOGXxlMGQe/6w==" + }, + "@rollup/rollup-darwin-arm64@4.40.0": { + "integrity": "sha512-GwYOcOakYHdfnjjKwqpTGgn5a6cUX7+Ra2HeNj/GdXvO2VJOOXCiYYlRFU4CubFM67EhbmzLOmACKEfvp3J1kQ==" + }, + "@rollup/rollup-darwin-x64@4.40.0": { + "integrity": "sha512-CoLEGJ+2eheqD9KBSxmma6ld01czS52Iw0e2qMZNpPDlf7Z9mj8xmMemxEucinev4LgHalDPczMyxzbq+Q+EtA==" + }, + "@rollup/rollup-freebsd-arm64@4.40.0": { + "integrity": "sha512-r7yGiS4HN/kibvESzmrOB/PxKMhPTlz+FcGvoUIKYoTyGd5toHp48g1uZy1o1xQvybwwpqpe010JrcGG2s5nkg==" + }, + "@rollup/rollup-freebsd-x64@4.40.0": { + "integrity": "sha512-mVDxzlf0oLzV3oZOr0SMJ0lSDd3xC4CmnWJ8Val8isp9jRGl5Dq//LLDSPFrasS7pSm6m5xAcKaw3sHXhBjoRw==" + }, + "@rollup/rollup-linux-arm-gnueabihf@4.40.0": { + "integrity": "sha512-y/qUMOpJxBMy8xCXD++jeu8t7kzjlOCkoxxajL58G62PJGBZVl/Gwpm7JK9+YvlB701rcQTzjUZ1JgUoPTnoQA==" + }, + "@rollup/rollup-linux-arm-musleabihf@4.40.0": { + "integrity": "sha512-GoCsPibtVdJFPv/BOIvBKO/XmwZLwaNWdyD8TKlXuqp0veo2sHE+A/vpMQ5iSArRUz/uaoj4h5S6Pn0+PdhRjg==" + }, + "@rollup/rollup-linux-arm64-gnu@4.40.0": { + "integrity": "sha512-L5ZLphTjjAD9leJzSLI7rr8fNqJMlGDKlazW2tX4IUF9P7R5TMQPElpH82Q7eNIDQnQlAyiNVfRPfP2vM5Avvg==" + }, + "@rollup/rollup-linux-arm64-musl@4.40.0": { + "integrity": "sha512-ATZvCRGCDtv1Y4gpDIXsS+wfFeFuLwVxyUBSLawjgXK2tRE6fnsQEkE4csQQYWlBlsFztRzCnBvWVfcae/1qxQ==" + }, + "@rollup/rollup-linux-loongarch64-gnu@4.40.0": { + "integrity": "sha512-wG9e2XtIhd++QugU5MD9i7OnpaVb08ji3P1y/hNbxrQ3sYEelKJOq1UJ5dXczeo6Hj2rfDEL5GdtkMSVLa/AOg==" + }, + "@rollup/rollup-linux-powerpc64le-gnu@4.40.0": { + "integrity": "sha512-vgXfWmj0f3jAUvC7TZSU/m/cOE558ILWDzS7jBhiCAFpY2WEBn5jqgbqvmzlMjtp8KlLcBlXVD2mkTSEQE6Ixw==" + }, + "@rollup/rollup-linux-riscv64-gnu@4.40.0": { + "integrity": "sha512-uJkYTugqtPZBS3Z136arevt/FsKTF/J9dEMTX/cwR7lsAW4bShzI2R0pJVw+hcBTWF4dxVckYh72Hk3/hWNKvA==" + }, + "@rollup/rollup-linux-riscv64-musl@4.40.0": { + "integrity": "sha512-rKmSj6EXQRnhSkE22+WvrqOqRtk733x3p5sWpZilhmjnkHkpeCgWsFFo0dGnUGeA+OZjRl3+VYq+HyCOEuwcxQ==" + }, + "@rollup/rollup-linux-s390x-gnu@4.40.0": { + "integrity": "sha512-SpnYlAfKPOoVsQqmTFJ0usx0z84bzGOS9anAC0AZ3rdSo3snecihbhFTlJZ8XMwzqAcodjFU4+/SM311dqE5Sw==" + }, + "@rollup/rollup-linux-x64-gnu@4.40.0": { + "integrity": "sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ==" + }, + "@rollup/rollup-linux-x64-musl@4.40.0": { + "integrity": "sha512-HZvjpiUmSNx5zFgwtQAV1GaGazT2RWvqeDi0hV+AtC8unqqDSsaFjPxfsO6qPtKRRg25SisACWnJ37Yio8ttaw==" + }, + "@rollup/rollup-win32-arm64-msvc@4.40.0": { + "integrity": "sha512-UtZQQI5k/b8d7d3i9AZmA/t+Q4tk3hOC0tMOMSq2GlMYOfxbesxG4mJSeDp0EHs30N9bsfwUvs3zF4v/RzOeTQ==" + }, + "@rollup/rollup-win32-ia32-msvc@4.40.0": { + "integrity": "sha512-+m03kvI2f5syIqHXCZLPVYplP8pQch9JHyXKZ3AGMKlg8dCyr2PKHjwRLiW53LTrN/Nc3EqHOKxUxzoSPdKddA==" + }, + "@rollup/rollup-win32-x64-msvc@4.40.0": { + "integrity": "sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ==" + }, + "@solidjs/router@0.15.3_solid-js@1.9.5__seroval@1.2.1": { + "integrity": "sha512-iEbW8UKok2Oio7o6Y4VTzLj+KFCmQPGEpm1fS3xixwFBdclFVBvaQVeibl1jys4cujfAK5Kn6+uG2uBm3lxOMw==", + "dependencies": [ + "solid-js" + ] + }, + "@types/babel__core@7.20.5": { + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dependencies": [ + "@babel/parser", + "@babel/types", + "@types/babel__generator", + "@types/babel__template", + "@types/babel__traverse" + ] + }, + "@types/babel__generator@7.27.0": { + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dependencies": [ + "@babel/types" + ] + }, + "@types/babel__template@7.4.4": { + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dependencies": [ + "@babel/parser", + "@babel/types" + ] + }, + "@types/babel__traverse@7.20.7": { + "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", + "dependencies": [ + "@babel/types" + ] + }, + "@types/debug@4.1.12": { + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": [ + "@types/ms" + ] + }, + "@types/estree@1.0.7": { + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==" + }, + "@types/ms@2.1.0": { + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==" + }, + "acorn@8.14.1": { + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==" + }, + "babel-plugin-jsx-dom-expressions@0.39.7_@babel+core@7.26.10": { + "integrity": "sha512-8GzVmFla7jaTNWW8W+lTMl9YGva4/06CtwJjySnkYtt8G1v9weCzc2SuF1DfrudcCNb2Doetc1FRg33swBYZCA==", + "dependencies": [ + "@babel/core", + "@babel/helper-module-imports@7.18.6", + "@babel/plugin-syntax-jsx", + "@babel/types", + "html-entities", + "parse5", + "validate-html-nesting" + ] + }, + "babel-preset-solid@1.9.5_@babel+core@7.26.10": { + "integrity": "sha512-85I3osODJ1LvZbv8wFozROV1vXq32BubqHXAGu73A//TRs3NLI1OFP83AQBUTSQHwgZQmARjHlJciym3we+V+w==", + "dependencies": [ + "@babel/core", + "babel-plugin-jsx-dom-expressions" + ] + }, + "braces@3.0.3": { + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": [ + "fill-range" + ] + }, + "browserslist@4.24.4": { + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dependencies": [ + "caniuse-lite", + "electron-to-chromium", + "node-releases", + "update-browserslist-db" + ] + }, + "caniuse-lite@1.0.30001714": { + "integrity": "sha512-mtgapdwDLSSBnCI3JokHM7oEQBLxiJKVRtg10AxM1AyeiKcM96f0Mkbqeq+1AbiCtvMcHRulAAEMu693JrSWqg==" + }, + "confbox@0.1.8": { + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==" + }, + "confbox@0.2.2": { + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==" + }, + "convert-source-map@2.0.0": { + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "csstype@3.1.3": { + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "debug@4.4.0": { + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dependencies": [ + "ms" + ] + }, + "dequal@2.0.3": { + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" + }, + "electron-to-chromium@1.5.137": { + "integrity": "sha512-/QSJaU2JyIuTbbABAo/crOs+SuAZLS+fVVS10PVrIT9hrRkmZl8Hb0xPSkKRUUWHQtYzXHpQUW3Dy5hwMzGZkA==" + }, + "entities@4.5.0": { + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + }, + "esbuild@0.25.2": { + "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", + "dependencies": [ + "@esbuild/aix-ppc64", + "@esbuild/android-arm", + "@esbuild/android-arm64", + "@esbuild/android-x64", + "@esbuild/darwin-arm64", + "@esbuild/darwin-x64", + "@esbuild/freebsd-arm64", + "@esbuild/freebsd-x64", + "@esbuild/linux-arm", + "@esbuild/linux-arm64", + "@esbuild/linux-ia32", + "@esbuild/linux-loong64", + "@esbuild/linux-mips64el", + "@esbuild/linux-ppc64", + "@esbuild/linux-riscv64", + "@esbuild/linux-s390x", + "@esbuild/linux-x64", + "@esbuild/netbsd-arm64", + "@esbuild/netbsd-x64", + "@esbuild/openbsd-arm64", + "@esbuild/openbsd-x64", + "@esbuild/sunos-x64", + "@esbuild/win32-arm64", + "@esbuild/win32-ia32", + "@esbuild/win32-x64" + ] + }, + "escalade@3.2.0": { + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" + }, + "esprima-extract-comments@1.1.0": { + "integrity": "sha512-sBQUnvJwpeE9QnPrxh7dpI/dp67erYG4WXEAreAMoelPRpMR7NWb4YtwRPn9b+H1uLQKl/qS8WYmyaljTpjIsw==", + "dependencies": [ + "esprima" + ] + }, + "esprima@4.0.1": { + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "exsolve@1.0.4": { + "integrity": "sha512-xsZH6PXaER4XoV+NiT7JHp1bJodJVT+cxeSH1G0f0tlT0lJqYuHUP3bUx2HtfTDvOagMINYp8rsqusxud3RXhw==" + }, + "extract-comments@1.1.0": { + "integrity": "sha512-dzbZV2AdSSVW/4E7Ti5hZdHWbA+Z80RJsJhr5uiL10oyjl/gy7/o+HI1HwK4/WSZhlq4SNKU3oUzXlM13Qx02Q==", + "dependencies": [ + "esprima-extract-comments", + "parse-code-context" + ] + }, + "fast-glob@3.3.3": { + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dependencies": [ + "@nodelib/fs.stat", + "@nodelib/fs.walk", + "glob-parent", + "merge2", + "micromatch" + ] + }, + "fastq@1.19.1": { + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dependencies": [ + "reusify" + ] + }, + "fdir@6.4.3_picomatch@4.0.2": { + "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "dependencies": [ + "picomatch@4.0.2" + ] + }, + "fill-range@7.1.1": { + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": [ + "to-regex-range" + ] + }, + "fsevents@2.3.3": { + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==" + }, + "gensync@1.0.0-beta.2": { + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "glob-parent@5.1.2": { + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": [ + "is-glob" + ] + }, + "globals@11.12.0": { + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "html-entities@2.3.3": { + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" + }, + "is-extglob@2.1.1": { + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-glob@4.0.3": { + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": [ + "is-extglob" + ] + }, + "is-number@7.0.0": { + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-what@4.1.16": { + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==" + }, + "js-tokens@4.0.0": { + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "jsesc@3.1.0": { + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==" + }, + "json5@2.2.3": { + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + }, + "local-pkg@1.1.1": { + "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", + "dependencies": [ + "mlly", + "pkg-types@2.1.0", + "quansync" + ] + }, + "lru-cache@5.1.1": { + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": [ + "yallist" + ] + }, + "merge-anything@5.1.7": { + "integrity": "sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==", + "dependencies": [ + "is-what" + ] + }, + "merge2@1.4.1": { + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch@4.0.8": { + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dependencies": [ + "braces", + "picomatch@2.3.1" + ] + }, + "mlly@1.7.4": { + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "dependencies": [ + "acorn", + "pathe", + "pkg-types@1.3.1", + "ufo" + ] + }, + "ms@2.1.3": { + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "nanoid@3.3.11": { + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==" + }, + "node-releases@2.0.19": { + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==" + }, + "parse-code-context@1.0.0": { + "integrity": "sha512-OZQaqKaQnR21iqhlnPfVisFjBWjhnMl5J9MgbP8xC+EwoVqbXrq78lp+9Zb3ahmLzrIX5Us/qbvBnaS3hkH6OA==" + }, + "parse5@7.2.1": { + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "dependencies": [ + "entities" + ] + }, + "pathe@2.0.3": { + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==" + }, + "picocolors@1.1.1": { + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "picomatch@2.3.1": { + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "picomatch@4.0.2": { + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==" + }, + "pkg-types@1.3.1": { + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dependencies": [ + "confbox@0.1.8", + "mlly", + "pathe" + ] + }, + "pkg-types@2.1.0": { + "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", + "dependencies": [ + "confbox@0.2.2", + "exsolve", + "pathe" + ] + }, + "postcss@8.5.3": { + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dependencies": [ + "nanoid", + "picocolors", + "source-map-js" + ] + }, + "quansync@0.2.10": { + "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==" + }, + "queue-microtask@1.2.3": { + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "reusify@1.1.0": { + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==" + }, + "rollup@4.40.0": { + "integrity": "sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==", + "dependencies": [ + "@rollup/rollup-android-arm-eabi", + "@rollup/rollup-android-arm64", + "@rollup/rollup-darwin-arm64", + "@rollup/rollup-darwin-x64", + "@rollup/rollup-freebsd-arm64", + "@rollup/rollup-freebsd-x64", + "@rollup/rollup-linux-arm-gnueabihf", + "@rollup/rollup-linux-arm-musleabihf", + "@rollup/rollup-linux-arm64-gnu", + "@rollup/rollup-linux-arm64-musl", + "@rollup/rollup-linux-loongarch64-gnu", + "@rollup/rollup-linux-powerpc64le-gnu", + "@rollup/rollup-linux-riscv64-gnu", + "@rollup/rollup-linux-riscv64-musl", + "@rollup/rollup-linux-s390x-gnu", + "@rollup/rollup-linux-x64-gnu", + "@rollup/rollup-linux-x64-musl", + "@rollup/rollup-win32-arm64-msvc", + "@rollup/rollup-win32-ia32-msvc", + "@rollup/rollup-win32-x64-msvc", + "@types/estree", + "fsevents" + ] + }, + "run-parallel@1.2.0": { + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dependencies": [ + "queue-microtask" + ] + }, + "semver@6.3.1": { + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "seroval-plugins@1.2.1_seroval@1.2.1": { + "integrity": "sha512-H5vs53+39+x4Udwp4J5rNZfgFuA+Lt+uU+09w1gYBVWomtAl98B+E9w7yC05Xc81/HgLvJdlyqJbU0fJCKCmdw==", + "dependencies": [ + "seroval" + ] + }, + "seroval@1.2.1": { + "integrity": "sha512-yBxFFs3zmkvKNmR0pFSU//rIsYjuX418TnlDmc2weaq5XFDqDIV/NOMPBoLrbxjLH42p4UzRuXHryXh9dYcKcw==" + }, + "solid-js@1.9.5_seroval@1.2.1": { + "integrity": "sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw==", + "dependencies": [ + "csstype", + "seroval", + "seroval-plugins" + ] + }, + "solid-refresh@0.6.3_solid-js@1.9.5__seroval@1.2.1": { + "integrity": "sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==", + "dependencies": [ + "@babel/generator", + "@babel/helper-module-imports@7.25.9", + "@babel/types", + "solid-js" + ] + }, + "source-map-js@1.2.1": { + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" + }, + "tinyglobby@0.2.12_picomatch@4.0.2": { + "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", + "dependencies": [ + "fdir", + "picomatch@4.0.2" + ] + }, + "to-regex-range@5.0.1": { + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": [ + "is-number" + ] + }, + "ufo@1.6.1": { + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==" + }, + "update-browserslist-db@1.1.3_browserslist@4.24.4": { + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dependencies": [ + "browserslist", + "escalade", + "picocolors" + ] + }, + "validate-html-nesting@1.2.2": { + "integrity": "sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==" + }, + "vite-plugin-pages@0.32.5_vite@6.3.1__picomatch@4.0.2__yaml@2.7.1_yaml@2.7.1": { + "integrity": "sha512-GY2JAt+4vZ4BqTtw+4CSUxPgYiqamrMRIzYk2AtJvQHeBoMlctsQW+tgCpKriUKINiKfi6NegbP07r1XrdxTWA==", + "dependencies": [ + "@types/debug", + "debug", + "dequal", + "extract-comments", + "fast-glob", + "json5", + "local-pkg", + "picocolors", + "vite@6.3.1_yaml@2.7.1_picomatch@4.0.2", + "yaml" + ] + }, + "vite-plugin-solid@2.11.6_solid-js@1.9.5__seroval@1.2.1_vite@6.3.1__picomatch@4.0.2__yaml@2.7.1_@babel+core@7.26.10": { + "integrity": "sha512-Sl5CTqJTGyEeOsmdH6BOgalIZlwH3t4/y0RQuFLMGnvWMBvxb4+lq7x3BSiAw6etf0QexfNJW7HSOO/Qf7pigg==", + "dependencies": [ + "@babel/core", + "@types/babel__core", + "babel-preset-solid", + "merge-anything", + "solid-js", + "solid-refresh", + "vite@6.3.1_yaml@2.7.1_picomatch@4.0.2", + "vitefu" + ] + }, + "vite@6.3.1_picomatch@4.0.2_yaml@2.7.1": { + "integrity": "sha512-kkzzkqtMESYklo96HKKPE5KKLkC1amlsqt+RjFMlX2AvbRB/0wghap19NdBxxwGZ+h/C6DLCrcEphPIItlGrRQ==", + "dependencies": [ + "esbuild", + "fdir", + "fsevents", + "picomatch@4.0.2", + "postcss", + "rollup", + "tinyglobby", + "yaml" + ] + }, + "vite@6.3.1_yaml@2.7.1_picomatch@4.0.2": { + "integrity": "sha512-kkzzkqtMESYklo96HKKPE5KKLkC1amlsqt+RjFMlX2AvbRB/0wghap19NdBxxwGZ+h/C6DLCrcEphPIItlGrRQ==", + "dependencies": [ + "esbuild", + "fdir", + "fsevents", + "picomatch@4.0.2", + "postcss", + "rollup", + "tinyglobby", + "yaml" + ] + }, + "vitefu@1.0.6_vite@6.3.1__yaml@2.7.1__picomatch@4.0.2": { + "integrity": "sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==", + "dependencies": [ + "vite@6.3.1_yaml@2.7.1_picomatch@4.0.2" + ] + }, + "yallist@3.1.1": { + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "yaml@2.7.1": { + "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==" + } + }, + "workspace": { + "packageJson": { + "dependencies": [ + "npm:@solidjs/router@~0.15.1", + "npm:solid-js@^1.9.5", + "npm:vite-plugin-pages@~0.32.4", + "npm:vite-plugin-solid@^2.11.6", + "npm:vite@6" + ] + } + } +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..1905a04 --- /dev/null +++ b/index.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#000000" /> + <title>Solid App</title> + </head> + <body> + <noscript>You need to enable JavaScript to run this app.</noscript> + <div id="root"></div> + + <script src="/src/index.tsx" type="module"></script> + </body> +</html> diff --git a/package.json b/package.json new file mode 100644 index 0000000..fbb1949 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "rustberry-frontend", + "version": "0.0.0", + "description": "", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "license": "AGPL-3.0-or-later", + "devDependencies": { + "vite": "^6.0.0", + "vite-plugin-pages": "^0.32.4", + "vite-plugin-solid": "^2.11.6" + }, + "dependencies": { + "@solidjs/router": "^0.15.1", + "solid-js": "^1.9.5" + } +} diff --git a/src/components/Button.module.css b/src/components/Button.module.css new file mode 100644 index 0000000..7041eaf --- /dev/null +++ b/src/components/Button.module.css @@ -0,0 +1,29 @@ +.btn:last-child { + margin-bottom: 0; +} +.generic-button { + display: grid; + place-items: center; + border: 3px solid #222; + color: white; + border-radius: 15px; + font-size: 1.6em; + width: 100%; + transition: transform 0.05s; + user-select: none; +} +.generic-button:enabled:active { + transform: scale(0.8); + box-shadow: inset 0px 0px 5px 0px black; +} +.generic-button:disabled { + filter: grayscale(0.8); +} +.btn { + composes: generic-button; + --page-size-without-margins: ( + 100svh - (var(--rows-count) + 1) * var(--btn-gap) + ); + --btn-height: calc(var(--page-size-without-margins) / var(--rows-count)); + height: var(--btn-height); +} diff --git a/src/components/Button.tsx b/src/components/Button.tsx new file mode 100644 index 0000000..031fc73 --- /dev/null +++ b/src/components/Button.tsx @@ -0,0 +1,57 @@ +import styles from "./Button.module.css"; +import { createEffect, createSignal } from "solid-js"; + +enum BtnType { + click = 0, + switch = 1, +} +export type Button = + | { + type: BtnType.click; + name: string; + color?: string; + } + | { + type: BtnType.switch; + name: string; + }; + +export default function Button(props: Button) { + const [value, setValue] = createSignal(false); + const [bgColor, setBgColor] = createSignal<string>(); + + createEffect(() => { + if (props.type === BtnType.click) { + setBgColor(value() ? "pink" : "blue"); + } else { + setBgColor(value() ? "green" : "red"); + } + }); + + function onClick() { + if (props.type === BtnType.click) { + if (value() === true) { + return; + } + setValue(true); + setTimeout(() => { + setValue(false); + }, 3000); + } else { + setValue((old) => !old); + } + } + + return ( + <button + on:click={onClick} + class={styles.btn} + style={{ "background-color": bgColor() }} + > + { + //btnText() + } + {props.name} + </button> + ); +} diff --git a/src/components/Timer.module.css b/src/components/Timer.module.css new file mode 100644 index 0000000..b748c9e --- /dev/null +++ b/src/components/Timer.module.css @@ -0,0 +1,63 @@ +.cont { + h2 { + margin-top: 0.4em; + margin-bottom: 1rem; + } + input { + width: 2em; + font-size: 1.5em; + padding: 0.3em; + } +} +.custom-option { + display: grid; + align-items: center; + grid-template-columns: 1fr 2fr 1fr; + margin-bottom: 1em; +} +.units { + display: inline-flex; + gap: 1.5em; + span { + font-size: 2em; + } +} +.not-selected-unit { + font-weight: lighter; +} +.selected-unit { + font-weight: bold; + text-decoration: underline; +} +.darkgray { + color: darkgray; +} +.custom-option-btn { + composes: generic-button from "./Button.module.css"; + background-color: green; + height: 2em; +} +.extra-stop-btn { + composes: generic-button from "./Button.module.css"; + background-color: red; + padding: 0.5em; + margin-top: 0.5em; +} + +.time-left { + margin-bottom: 1em; + h2 { + display: inline; + color: lightblue; + } +} + +.options { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1rem; +} +.option { + composes: generic-button from "./Button.module.css"; + height: calc((100vw - 2rem) / 3 / 1.5); +} diff --git a/src/components/Timer.tsx b/src/components/Timer.tsx new file mode 100644 index 0000000..61a98f5 --- /dev/null +++ b/src/components/Timer.tsx @@ -0,0 +1,178 @@ +import { createSignal, For, Match, Show, Switch } from "solid-js"; +import styles from "./Timer.module.css"; + +export const TIME_UNITS = ["s", "m", "h", "d"] as const; +export type Timer = { + title: string; + options: { + time: number; + unit: (typeof TIME_UNITS)[number]; + }[]; + backgroundColor: string; + onTill: number | null; + secondsLeftText: string; + extraStopActions: { title: string }[]; +}; + +export default function Timer(props: Timer) { + const [onTill, setOnTill] = createSignal(props.onTill); + const [unit, setUnit] = createSignal<(typeof TIME_UNITS)[number]>( + TIME_UNITS[1], + ); + const [formattedTime, setFormattedTime] = createSignal(""); + const [disabled, setDisabled] = createSignal(onTill() !== null); + const [customValue, setCustomValue] = createSignal<number | "">(""); + + let _intervalId = null; + function toggleAutoUpdate() { + if (_intervalId === null) { + updateTime(); + _intervalId = setInterval(updateTime, 1000); + } else { + clearInterval(_intervalId); + _intervalId = null; + } + } + if (props.onTill !== null) { + toggleAutoUpdate(); + } + function updateTime() { + const s = Math.floor(onTill() - Date.now() / 1000); + const days = Math.floor(s / (24 * 3600)); + const hours = Math.floor((s % (24 * 3600)) / 3600); + const minutes = Math.floor((s % 3600) / 60); + const seconds = s % 60; + + let text = ""; + if (days > 0) { + text += days + "d : "; + } + if (hours > 0 || text.length > 0) { + text += hours + "h : "; + } + if (minutes > 0 || text.length > 0) { + text += minutes + "m : "; + } + if (seconds > 0 || text.length > 0) { + text += seconds + "s"; + } + setFormattedTime(text); + } + function startStopClick() { + const val = customValue(); + if (disabled() === false && val !== "") { + optionClick({ time: val, unit: unit() }); + } else if (disabled() === true) { + setDisabled(false); + setOnTill(null); + toggleAutoUpdate(); + } + } + + function optionClick(option: Timer["options"][number]) { + setDisabled(true); + let newOnTill = Math.floor(Date.now() / 1000); + if (option.unit === "s") { + newOnTill += option.time; + } else if (option.unit === "m") { + newOnTill += option.time * 60; + } else if (option.unit === "h") { + newOnTill += option.time * 3600; + } else { + newOnTill += option.time * 3600 * 24; + } + setOnTill(newOnTill); + toggleAutoUpdate(); + } + + function extraStopClick(act: Timer["extraStopActions"][number]) { + // Some api call for the extra + startStopClick(); + } + return ( + <div class={styles.cont}> + <h2>{props.title}</h2> + + <div class={styles.customOption}> + <input + type="number" + value={customValue()} + on:input={(e) => + setCustomValue(e.target.value ? parseFloat(e.target.value) : "") + } + disabled={disabled()} + min="1" + /> + <div class={styles.units}> + <For each={TIME_UNITS}> + {(u) => ( + <span + on:click={() => (disabled() ? null : setUnit(u))} + classList={{ + [styles.selectedUnit]: unit() === u, + [styles.notSelectedUnit]: unit() !== u, + [styles.darkgray]: disabled() === true, + }} + > + {u} + </span> + )} + </For> + </div> + <button + class={styles.customOptionBtn} + on:click={startStopClick} + disabled={ + disabled() + ? false + : customValue() === "" || (customValue() as number) <= 0 + } + style={{ "background-color": disabled() ? "red" : "green" }} + > + {disabled() ? "Wyłącz" : "Włącz"} + </button> + {/*<Show when={disabled() === true}>*/} + <For each={props.extraStopActions}> + {(act) => ( + <button + disabled={disabled() === false} + on:click={[extraStopClick, act]} + class={styles.extraStopBtn} + > + {act.title} + </button> + )} + </For> + {/*</Show>*/} + </div> + + <div class={styles.timeLeft}> + <Switch> + <Match when={onTill() === null}> + <span>Wyłączone</span> + <h2> </h2> + </Match> + <Match when={onTill() > 0}> + <span>{props.secondsLeftText} </span> + <h2>{formattedTime()}</h2> + </Match> + </Switch> + </div> + + <div class={styles.options}> + <For each={props.options}> + {(option) => ( + <button + class={styles.option} + on:click={[optionClick, option]} + style={{ "background-color": props.backgroundColor }} + disabled={disabled()} + > + {option.time} {option.unit} + </button> + )} + </For> + </div> + </div> + ); +} diff --git a/src/helpers/api.ts b/src/helpers/api.ts new file mode 100644 index 0000000..112ba2f --- /dev/null +++ b/src/helpers/api.ts @@ -0,0 +1,103 @@ +import { type Button } from "@/components/Button"; +import { Timer } from "@/components/Timer"; + +export async function getButtons(): Promise<Button[]> { + return [ + { + type: 0, + name: "Brama Wjazdowa", + }, + { + type: 0, + name: "Brama Toyota", + }, + { + type: 0, + name: "Brama Passat", + }, + { + type: 1, + name: "Furtka", + }, + { + type: 0, + name: "Plafon Maks", + }, + { + type: 1, + name: "Ciepła woda 52,8°C", + }, + { + type: 1, + name: "Wentylator łazienka", + }, + { + type: 1, + name: "Wentylator Kuchnia Dolna", + }, + { + type: 1, + name: "Pompa źródło", + }, + { + type: 1, + name: "Nawodnienie", + }, + { + type: 1, + name: "Choinka+Astro", + }, + { + type: 1, + name: "Komputer", + }, + { + type: 1, + name: "Oświetlenie Zewnętrzne", + }, + { + type: 1, + name: "Blok. czujki ośw. zewn.", + }, + { + type: 1, + name: "Ogrzewanie 27,5°C", + }, + { + type: 1, + name: "Termometr - restart", + }, + ]; +} + +export async function getTimers(): Promise<Timer[]> { + return [ + { + title: "Otwórz bramę wjazową na:", + options: [ + { time: 15, unit: "m" }, + { time: 45, unit: "m" }, + { time: 1, unit: "h" }, + { time: 3, unit: "h" }, + { time: 24, unit: "h" }, + { time: 48, unit: "h" }, + ], + backgroundColor: "#ab03ab", + onTill: Math.floor(Date.now() / 1000) + 3 * 287721, + secondsLeftText: "Otwarte jeszcze przez:", + extraStopActions: [{ title: "Zamknij i wyłącz" }], + }, + { + title: "Włącz ogrzewanie na:", + secondsLeftText: "Włączone jeszcze na:", + options: [ + { time: 1, unit: "h" }, + { time: 1.5, unit: "h" }, + { time: 2, unit: "h" }, + { time: 3, unit: "h" }, + ], + backgroundColor: "#ab03ab", + onTill: null, + }, + ]; +} diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..f064787 --- /dev/null +++ b/src/index.css @@ -0,0 +1,6 @@ +body { + margin: 0; + background-color: black; + color: white; + padding: 0.3rem; +} diff --git a/src/index.tsx b/src/index.tsx new file mode 100644 index 0000000..de08c81 --- /dev/null +++ b/src/index.tsx @@ -0,0 +1,17 @@ +/* @refresh reload */ +import "./index.css"; + +import { Suspense } from "solid-js"; +import { render } from "solid-js/web"; + +import { Router } from "@solidjs/router"; +import routes from "~solid-pages"; + +render( + () => ( + <Router root={(props) => <Suspense>{props.children}</Suspense>}> + {routes} + </Router> + ), + document.getElementById("root"), +); diff --git a/src/pages/*.tsx b/src/pages/*.tsx new file mode 100644 index 0000000..a7021c6 --- /dev/null +++ b/src/pages/*.tsx @@ -0,0 +1,8 @@ +export default function NotFound() { + return ( + <section> + <h1>404: Not Found</h1> + <p>It's gone 😞</p> + </section> + ); +} diff --git a/src/pages/index.module.css b/src/pages/index.module.css new file mode 100644 index 0000000..9d6167d --- /dev/null +++ b/src/pages/index.module.css @@ -0,0 +1,14 @@ +.btns-cont { + --btn-gap: 0.3rem; + /* padding: var(--btn-gap); */ + display: grid; + justify-items: center; + align-items: center; + gap: var(--btn-gap); + grid-template-columns: repeat(2, 1fr); +} +.timers-cont { + hr { + margin-top: 2em; + } +} diff --git a/src/pages/index.tsx b/src/pages/index.tsx new file mode 100644 index 0000000..d64f9e1 --- /dev/null +++ b/src/pages/index.tsx @@ -0,0 +1,33 @@ +import { For } from "solid-js"; +import { createAsync } from "@solidjs/router"; + +import Button from "@/components/Button"; +import Timer from "@/components/Timer"; +import { getButtons, getTimers } from "@/helpers/api"; +import styles from "./index.module.css"; + +export default function Home() { + const btns = createAsync(getButtons); + const timers = createAsync(getTimers); + + return ( + <> + <div + class={styles.btnsCont} + style={{ "--rows-count": Math.floor(btns()?.length / 2) }} + > + <For each={btns()}>{(btn) => <Button {...btn} />}</For> + </div> + <div class={styles.timersCont}> + <For each={timers()}> + {(timer) => ( + <> + <hr /> + <Timer {...timer} /> + </> + )} + </For> + </div> + </> + ); +} diff --git a/src/vite.env.d.ts b/src/vite.env.d.ts new file mode 100644 index 0000000..50d6f23 --- /dev/null +++ b/src/vite.env.d.ts @@ -0,0 +1,2 @@ +/// <reference types="vite/client" /> +/// <reference types="vite-plugin-pages/client-solid" /> diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..92d678d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + "types": ["vite/client"], + "noEmit": true, + "isolatedModules": true, + "paths": { + "@/*": ["src/*"] + } + } +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..692c9bf --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,25 @@ +import { defineConfig } from "vite"; +import solidPlugin from "vite-plugin-solid"; +import Pages from "vite-plugin-pages"; + +export default defineConfig({ + plugins: [ + Pages({ + dirs: ["src/pages"], + }), + solidPlugin(), + ], + css: { + modules: { + localsConvention: "dashesOnly", + }, + }, + resolve: { + alias: { + "@": new URL("./src", import.meta.url).pathname, + }, + }, + build: { + target: "esnext", + }, +}); |
