mirror of
https://github.com/hpware/news-analyze.git
synced 2025-06-23 15:51:01 +08:00
refactor: remove GitHub authentication API endpoints and add new components
- Deleted GitHub callback and authentication handler files. - Added new component for displaying headlines. - Implemented hot news feed component with external API fetching. - Created dynamic news provider page with routing. - Developed news organization about page with animations and data fetching. - Introduced a code of conduct document.
This commit is contained in:
parent
b35e96625e
commit
930713042e
17
.env.example
17
.env.example
@ -1,9 +1,12 @@
|
|||||||
S3_ACCESS_KEY=""
|
|
||||||
S3_SECRET_KEY=""
|
|
||||||
S3_BUCKETNAME=""
|
|
||||||
S3_ENDPOINT=""
|
|
||||||
|
|
||||||
NUXT_GITHUB_CLIENT_ID=""
|
S3_ACCESS_KEY=
|
||||||
NUXT_GITHUB_CLIENT_SECRET=""
|
S3_SECRET_KEY=
|
||||||
|
S3_BUCKETNAME=
|
||||||
|
S3_ENDPOINT=
|
||||||
|
|
||||||
POSTGRES_URL=""
|
POSTGRES_URL=
|
||||||
|
|
||||||
|
GROQ_API_KEY=
|
||||||
|
|
||||||
|
NUXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
|
||||||
|
NUXT_CLERK_SECRET_KEY=
|
1
CODE_OF_CONDUCT.md.md
Normal file
1
CODE_OF_CONDUCT.md.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Code of conduct
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
App Design: [Freeform](https://www.icloud.com/freeform/026AxB798cViZ9jJ2DkNsXUCQ#Untitled_5)
|
||||||
|
|
||||||
## Why?
|
## Why?
|
||||||
|
|
||||||
我們使用這個新聞來舉例:
|
我們使用這個新聞來舉例:
|
||||||
|
41
bun.lock
41
bun.lock
@ -4,6 +4,7 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "BlindSpec",
|
"name": "BlindSpec",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@clerk/nuxt": "^1.6.3",
|
||||||
"@fontsource-variable/noto-sans-tc": "^5.2.5",
|
"@fontsource-variable/noto-sans-tc": "^5.2.5",
|
||||||
"@fontsource/fira-code": "^5.2.6",
|
"@fontsource/fira-code": "^5.2.6",
|
||||||
"@fontsource/fira-sans": "^5.2.5",
|
"@fontsource/fira-sans": "^5.2.5",
|
||||||
@ -101,6 +102,16 @@
|
|||||||
|
|
||||||
"@babel/types": ["@babel/types@7.27.1", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q=="],
|
"@babel/types": ["@babel/types@7.27.1", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q=="],
|
||||||
|
|
||||||
|
"@clerk/backend": ["@clerk/backend@1.32.0", "", { "dependencies": { "@clerk/shared": "^3.8.2", "@clerk/types": "^4.58.0", "cookie": "1.0.2", "snakecase-keys": "8.0.1", "tslib": "2.8.1" }, "peerDependencies": { "svix": "^1.62.0" }, "optionalPeers": ["svix"] }, "sha512-D0hC2mnU79wM4q8GU5ZFrMD3p9lHy3aM+qDi9WqD3L40d65JJ+lzD+rKSqfM5/gDtUWUdD2Ezvqa0ZObRXTcgg=="],
|
||||||
|
|
||||||
|
"@clerk/nuxt": ["@clerk/nuxt@1.6.3", "", { "dependencies": { "@clerk/backend": "^1.32.0", "@clerk/shared": "^3.8.2", "@clerk/types": "^4.58.0", "@clerk/vue": "^1.8.0", "@nuxt/kit": "^3.16.2", "@nuxt/schema": "^3.16.2", "h3": "^1.15.1" } }, "sha512-6WjAuhXJ1MR3iNMyOKsGfdzarN58MvlPyXKdTVNo8pOPfo3Q0d+weGNbjLZrVtiT4t2OzvMbK2v/U78wYqf2gg=="],
|
||||||
|
|
||||||
|
"@clerk/shared": ["@clerk/shared@3.8.2", "", { "dependencies": { "@clerk/types": "^4.58.0", "dequal": "2.0.3", "glob-to-regexp": "0.4.1", "js-cookie": "3.0.5", "std-env": "^3.9.0", "swr": "^2.3.3" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-0", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-0" }, "optionalPeers": ["react", "react-dom"] }, "sha512-y8g8/wbFo/3gCRsrk2rmGQ1uzIb8lPM4Wjggt4glC8mPqTGgMFuIAK0Sj0PAJOq5739sokFXc4CzZdMnu/P5ug=="],
|
||||||
|
|
||||||
|
"@clerk/types": ["@clerk/types@4.58.0", "", { "dependencies": { "csstype": "3.1.3" } }, "sha512-P30Vnqaw2UzoSZivNG61NvF9WiAVbKItOvkVJzUbwqDkISdmNOio8mWCeFuKq+bxjPESvS+S615Uplm7dl6jpg=="],
|
||||||
|
|
||||||
|
"@clerk/vue": ["@clerk/vue@1.8.0", "", { "dependencies": { "@clerk/shared": "^3.8.2", "@clerk/types": "^4.58.0" }, "peerDependencies": { "vue": "^3.2.0" } }, "sha512-wfxlQMnMhRzjMF+ZKjEz3QINl9WUyLDI2FaIxFoegXdEESAv3301wxMDK+0gfV9d0xAqk0Aml62Nw72GRoYv+w=="],
|
||||||
|
|
||||||
"@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.0", "", { "dependencies": { "mime": "^3.0.0" } }, "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA=="],
|
"@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.0", "", { "dependencies": { "mime": "^3.0.0" } }, "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA=="],
|
||||||
|
|
||||||
"@colors/colors": ["@colors/colors@1.6.0", "", {}, "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="],
|
"@colors/colors": ["@colors/colors@1.6.0", "", {}, "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="],
|
||||||
@ -843,7 +854,7 @@
|
|||||||
|
|
||||||
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
|
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
|
||||||
|
|
||||||
"cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
|
"cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
|
||||||
|
|
||||||
"cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="],
|
"cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="],
|
||||||
|
|
||||||
@ -937,6 +948,8 @@
|
|||||||
|
|
||||||
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
|
||||||
|
|
||||||
|
"dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
|
||||||
|
|
||||||
"destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="],
|
"destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="],
|
||||||
|
|
||||||
"destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="],
|
"destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="],
|
||||||
@ -977,6 +990,8 @@
|
|||||||
|
|
||||||
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
|
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
|
||||||
|
|
||||||
|
"dot-case": ["dot-case@3.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w=="],
|
||||||
|
|
||||||
"dot-prop": ["dot-prop@9.0.0", "", { "dependencies": { "type-fest": "^4.18.2" } }, "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ=="],
|
"dot-prop": ["dot-prop@9.0.0", "", { "dependencies": { "type-fest": "^4.18.2" } }, "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ=="],
|
||||||
|
|
||||||
"dotenv": ["dotenv@16.5.0", "", {}, "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg=="],
|
"dotenv": ["dotenv@16.5.0", "", {}, "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg=="],
|
||||||
@ -1187,6 +1202,8 @@
|
|||||||
|
|
||||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||||
|
|
||||||
|
"glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="],
|
||||||
|
|
||||||
"global-directory": ["global-directory@4.0.1", "", { "dependencies": { "ini": "4.1.1" } }, "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q=="],
|
"global-directory": ["global-directory@4.0.1", "", { "dependencies": { "ini": "4.1.1" } }, "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q=="],
|
||||||
|
|
||||||
"globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
"globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||||
@ -1335,6 +1352,8 @@
|
|||||||
|
|
||||||
"jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="],
|
"jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="],
|
||||||
|
|
||||||
|
"js-cookie": ["js-cookie@3.0.5", "", {}, "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw=="],
|
||||||
|
|
||||||
"js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="],
|
"js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="],
|
||||||
|
|
||||||
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
|
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
|
||||||
@ -1449,6 +1468,8 @@
|
|||||||
|
|
||||||
"logform": ["logform@2.7.0", "", { "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" } }, "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ=="],
|
"logform": ["logform@2.7.0", "", { "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" } }, "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ=="],
|
||||||
|
|
||||||
|
"lower-case": ["lower-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg=="],
|
||||||
|
|
||||||
"lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
"lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||||
|
|
||||||
"lucide-vue-next": ["lucide-vue-next@0.508.0", "", { "peerDependencies": { "vue": ">=3.0.1" } }, "sha512-ZPO/Kh1gz7RU2/hd8FWw3SjLVMUIm/TJAhOGV9CbM1zvNwiJ8DK6W33LFWxtlZZ1IUPOXAny0pbttY+yyOsjKg=="],
|
"lucide-vue-next": ["lucide-vue-next@0.508.0", "", { "peerDependencies": { "vue": ">=3.0.1" } }, "sha512-ZPO/Kh1gz7RU2/hd8FWw3SjLVMUIm/TJAhOGV9CbM1zvNwiJ8DK6W33LFWxtlZZ1IUPOXAny0pbttY+yyOsjKg=="],
|
||||||
@ -1463,6 +1484,8 @@
|
|||||||
|
|
||||||
"make-dir": ["make-dir@3.1.0", "", { "dependencies": { "semver": "^6.0.0" } }, "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw=="],
|
"make-dir": ["make-dir@3.1.0", "", { "dependencies": { "semver": "^6.0.0" } }, "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw=="],
|
||||||
|
|
||||||
|
"map-obj": ["map-obj@4.3.0", "", {}, "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ=="],
|
||||||
|
|
||||||
"marky": ["marky@1.3.0", "", {}, "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ=="],
|
"marky": ["marky@1.3.0", "", {}, "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ=="],
|
||||||
|
|
||||||
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
||||||
@ -1549,6 +1572,8 @@
|
|||||||
|
|
||||||
"nitropack": ["nitropack@2.11.11", "", { "dependencies": { "@cloudflare/kv-asset-handler": "^0.4.0", "@netlify/functions": "^3.1.2", "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-commonjs": "^28.0.3", "@rollup/plugin-inject": "^5.0.5", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-replace": "^6.0.2", "@rollup/plugin-terser": "^0.4.4", "@vercel/nft": "^0.29.2", "archiver": "^7.0.1", "c12": "^3.0.3", "chokidar": "^4.0.3", "citty": "^0.1.6", "compatx": "^0.2.0", "confbox": "^0.2.2", "consola": "^3.4.2", "cookie-es": "^2.0.0", "croner": "^9.0.0", "crossws": "^0.3.4", "db0": "^0.3.2", "defu": "^6.1.4", "destr": "^2.0.5", "dot-prop": "^9.0.0", "esbuild": "^0.25.3", "escape-string-regexp": "^5.0.0", "etag": "^1.8.1", "exsolve": "^1.0.5", "globby": "^14.1.0", "gzip-size": "^7.0.0", "h3": "^1.15.3", "hookable": "^5.5.3", "httpxy": "^0.1.7", "ioredis": "^5.6.1", "jiti": "^2.4.2", "klona": "^2.0.6", "knitwork": "^1.2.0", "listhen": "^1.9.0", "magic-string": "^0.30.17", "magicast": "^0.3.5", "mime": "^4.0.7", "mlly": "^1.7.4", "node-fetch-native": "^1.6.6", "node-mock-http": "^1.0.0", "ofetch": "^1.4.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^1.0.0", "pkg-types": "^2.1.0", "pretty-bytes": "^6.1.1", "radix3": "^1.1.2", "rollup": "^4.40.0", "rollup-plugin-visualizer": "^5.14.0", "scule": "^1.3.0", "semver": "^7.7.1", "serve-placeholder": "^2.0.2", "serve-static": "^2.2.0", "source-map": "^0.7.4", "std-env": "^3.9.0", "ufo": "^1.6.1", "ultrahtml": "^1.6.0", "uncrypto": "^0.1.3", "unctx": "^2.4.1", "unenv": "^2.0.0-rc.15", "unimport": "^5.0.0", "unplugin-utils": "^0.2.4", "unstorage": "^1.16.0", "untyped": "^2.0.0", "unwasm": "^0.3.9", "youch": "^4.1.0-beta.7", "youch-core": "^0.3.2" }, "peerDependencies": { "xml2js": "^0.6.2" }, "optionalPeers": ["xml2js"], "bin": { "nitro": "dist/cli/index.mjs", "nitropack": "dist/cli/index.mjs" } }, "sha512-KnWkajf2ZIsjr7PNeENvDRi87UdMrn8dRTe/D/Ak3Ud6sbC7ZCArVGeosoY7WZvsvLBN1YAwm//34Bq4dKkAaw=="],
|
"nitropack": ["nitropack@2.11.11", "", { "dependencies": { "@cloudflare/kv-asset-handler": "^0.4.0", "@netlify/functions": "^3.1.2", "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-commonjs": "^28.0.3", "@rollup/plugin-inject": "^5.0.5", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-replace": "^6.0.2", "@rollup/plugin-terser": "^0.4.4", "@vercel/nft": "^0.29.2", "archiver": "^7.0.1", "c12": "^3.0.3", "chokidar": "^4.0.3", "citty": "^0.1.6", "compatx": "^0.2.0", "confbox": "^0.2.2", "consola": "^3.4.2", "cookie-es": "^2.0.0", "croner": "^9.0.0", "crossws": "^0.3.4", "db0": "^0.3.2", "defu": "^6.1.4", "destr": "^2.0.5", "dot-prop": "^9.0.0", "esbuild": "^0.25.3", "escape-string-regexp": "^5.0.0", "etag": "^1.8.1", "exsolve": "^1.0.5", "globby": "^14.1.0", "gzip-size": "^7.0.0", "h3": "^1.15.3", "hookable": "^5.5.3", "httpxy": "^0.1.7", "ioredis": "^5.6.1", "jiti": "^2.4.2", "klona": "^2.0.6", "knitwork": "^1.2.0", "listhen": "^1.9.0", "magic-string": "^0.30.17", "magicast": "^0.3.5", "mime": "^4.0.7", "mlly": "^1.7.4", "node-fetch-native": "^1.6.6", "node-mock-http": "^1.0.0", "ofetch": "^1.4.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^1.0.0", "pkg-types": "^2.1.0", "pretty-bytes": "^6.1.1", "radix3": "^1.1.2", "rollup": "^4.40.0", "rollup-plugin-visualizer": "^5.14.0", "scule": "^1.3.0", "semver": "^7.7.1", "serve-placeholder": "^2.0.2", "serve-static": "^2.2.0", "source-map": "^0.7.4", "std-env": "^3.9.0", "ufo": "^1.6.1", "ultrahtml": "^1.6.0", "uncrypto": "^0.1.3", "unctx": "^2.4.1", "unenv": "^2.0.0-rc.15", "unimport": "^5.0.0", "unplugin-utils": "^0.2.4", "unstorage": "^1.16.0", "untyped": "^2.0.0", "unwasm": "^0.3.9", "youch": "^4.1.0-beta.7", "youch-core": "^0.3.2" }, "peerDependencies": { "xml2js": "^0.6.2" }, "optionalPeers": ["xml2js"], "bin": { "nitro": "dist/cli/index.mjs", "nitropack": "dist/cli/index.mjs" } }, "sha512-KnWkajf2ZIsjr7PNeENvDRi87UdMrn8dRTe/D/Ak3Ud6sbC7ZCArVGeosoY7WZvsvLBN1YAwm//34Bq4dKkAaw=="],
|
||||||
|
|
||||||
|
"no-case": ["no-case@3.0.4", "", { "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg=="],
|
||||||
|
|
||||||
"node-abi": ["node-abi@3.75.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg=="],
|
"node-abi": ["node-abi@3.75.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg=="],
|
||||||
|
|
||||||
"node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
|
"node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
|
||||||
@ -1829,6 +1854,8 @@
|
|||||||
|
|
||||||
"rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="],
|
"rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="],
|
||||||
|
|
||||||
|
"react": ["react@19.1.0", "", {}, "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg=="],
|
||||||
|
|
||||||
"read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="],
|
"read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="],
|
||||||
|
|
||||||
"read-package-up": ["read-package-up@11.0.0", "", { "dependencies": { "find-up-simple": "^1.0.0", "read-pkg": "^9.0.0", "type-fest": "^4.6.0" } }, "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ=="],
|
"read-package-up": ["read-package-up@11.0.0", "", { "dependencies": { "find-up-simple": "^1.0.0", "read-pkg": "^9.0.0", "type-fest": "^4.6.0" } }, "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ=="],
|
||||||
@ -1947,6 +1974,10 @@
|
|||||||
|
|
||||||
"smob": ["smob@1.5.0", "", {}, "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig=="],
|
"smob": ["smob@1.5.0", "", {}, "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig=="],
|
||||||
|
|
||||||
|
"snake-case": ["snake-case@3.0.4", "", { "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg=="],
|
||||||
|
|
||||||
|
"snakecase-keys": ["snakecase-keys@8.0.1", "", { "dependencies": { "map-obj": "^4.1.0", "snake-case": "^3.0.4", "type-fest": "^4.15.0" } }, "sha512-Sj51kE1zC7zh6TDlNNz0/Jn1n5HiHdoQErxO8jLtnyrkJW/M5PrI7x05uDgY3BO7OUQYKCvmeMurW6BPUdwEOw=="],
|
||||||
|
|
||||||
"source-map": ["source-map@0.7.4", "", {}, "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA=="],
|
"source-map": ["source-map@0.7.4", "", {}, "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA=="],
|
||||||
|
|
||||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||||
@ -2007,6 +2038,8 @@
|
|||||||
|
|
||||||
"svgo": ["svgo@3.3.2", "", { "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.0.0" }, "bin": "./bin/svgo" }, "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw=="],
|
"svgo": ["svgo@3.3.2", "", { "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.0.0" }, "bin": "./bin/svgo" }, "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw=="],
|
||||||
|
|
||||||
|
"swr": ["swr@2.3.3", "", { "dependencies": { "dequal": "^2.0.3", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-dshNvs3ExOqtZ6kJBaAsabhPdHyeY4P2cKwRCniDVifBMoG/SVI7tfLWqPXriVspf2Rg4tPzXJTnwaihIeFw2A=="],
|
||||||
|
|
||||||
"system-architecture": ["system-architecture@0.1.0", "", {}, "sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA=="],
|
"system-architecture": ["system-architecture@0.1.0", "", {}, "sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA=="],
|
||||||
|
|
||||||
"tailwind-config-viewer": ["tailwind-config-viewer@2.0.4", "", { "dependencies": { "@koa/router": "^12.0.1", "commander": "^6.0.0", "fs-extra": "^9.0.1", "koa": "^2.14.2", "koa-static": "^5.0.0", "open": "^7.0.4", "portfinder": "^1.0.26", "replace-in-file": "^6.1.0" }, "peerDependencies": { "tailwindcss": "1 || 2 || 2.0.1-compat || 3" }, "bin": { "tailwind-config-viewer": "cli/index.js", "tailwindcss-config-viewer": "cli/index.js" } }, "sha512-icvcmdMmt9dphvas8wL40qttrHwAnW3QEN4ExJ2zICjwRsPj7gowd1cOceaWG3IfTuM/cTNGQcx+bsjMtmV+cw=="],
|
"tailwind-config-viewer": ["tailwind-config-viewer@2.0.4", "", { "dependencies": { "@koa/router": "^12.0.1", "commander": "^6.0.0", "fs-extra": "^9.0.1", "koa": "^2.14.2", "koa-static": "^5.0.0", "open": "^7.0.4", "portfinder": "^1.0.26", "replace-in-file": "^6.1.0" }, "peerDependencies": { "tailwindcss": "1 || 2 || 2.0.1-compat || 3" }, "bin": { "tailwind-config-viewer": "cli/index.js", "tailwindcss-config-viewer": "cli/index.js" } }, "sha512-icvcmdMmt9dphvas8wL40qttrHwAnW3QEN4ExJ2zICjwRsPj7gowd1cOceaWG3IfTuM/cTNGQcx+bsjMtmV+cw=="],
|
||||||
@ -2137,6 +2170,8 @@
|
|||||||
|
|
||||||
"urlpattern-polyfill": ["urlpattern-polyfill@8.0.2", "", {}, "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ=="],
|
"urlpattern-polyfill": ["urlpattern-polyfill@8.0.2", "", {}, "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ=="],
|
||||||
|
|
||||||
|
"use-sync-external-store": ["use-sync-external-store@1.5.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A=="],
|
||||||
|
|
||||||
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
||||||
|
|
||||||
"utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="],
|
"utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="],
|
||||||
@ -2413,6 +2448,8 @@
|
|||||||
|
|
||||||
"execa/@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="],
|
"execa/@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="],
|
||||||
|
|
||||||
|
"express/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
|
||||||
|
|
||||||
"externality/pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="],
|
"externality/pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="],
|
||||||
|
|
||||||
"extract-zip/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="],
|
"extract-zip/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="],
|
||||||
@ -2593,8 +2630,6 @@
|
|||||||
|
|
||||||
"yauzl/buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="],
|
"yauzl/buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="],
|
||||||
|
|
||||||
"youch/cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
|
|
||||||
|
|
||||||
"@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
"@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
||||||
|
|
||||||
"@eslint/config-array/minimatch/brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
|
"@eslint/config-array/minimatch/brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
|
||||||
|
@ -6,7 +6,7 @@ const localeLink = useLocalePath();
|
|||||||
class="flex flex-col justify-center align-center text-center absolute inset-x-0"
|
class="flex flex-col justify-center align-center text-center absolute inset-x-0"
|
||||||
>
|
>
|
||||||
<span class="text-sm m-4 mb-0 text-center align-center justify-center"
|
<span class="text-sm m-4 mb-0 text-center align-center justify-center"
|
||||||
>{{ new Date().getFullYear() }} © yh</span
|
>2025 - {{ new Date().getFullYear() }} © yh</span
|
||||||
>
|
>
|
||||||
<span class="text-xs mt-0 m-2 text-center align-center justify-center">
|
<span class="text-xs mt-0 m-2 text-center align-center justify-center">
|
||||||
Inspired by Ground.News
|
Inspired by Ground.News
|
||||||
|
@ -32,44 +32,44 @@ const toggleDropdown = () => {
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row align-center justify-center text-center">
|
<div class="flex flex-row align-center justify-center text-center">
|
||||||
<button
|
<button
|
||||||
@click="toggleDropdown"
|
@click="toggleDropdown"
|
||||||
class="flex items-center space-x-1 px-4 py-2 rounded hover:bg-gray-900 transition-all duration-100 mr-5"
|
class="flex items-center space-x-1 px-4 py-2 rounded hover:bg-gray-900 transition-all duration-100 mr-5"
|
||||||
|
>
|
||||||
|
<span>{{ locale }}</span>
|
||||||
|
<svg
|
||||||
|
class="w-4 h-4"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
>
|
>
|
||||||
<span>{{ locale }}</span>
|
<path
|
||||||
<svg
|
stroke-linecap="round"
|
||||||
class="w-4 h-4"
|
stroke-linejoin="round"
|
||||||
fill="none"
|
stroke-width="2"
|
||||||
stroke="currentColor"
|
d="M19 9l-7 7-7-7"
|
||||||
viewBox="0 0 24 24"
|
/>
|
||||||
>
|
</svg>
|
||||||
<path
|
</button>
|
||||||
stroke-linecap="round"
|
<Transition
|
||||||
stroke-linejoin="round"
|
enter-active-class="animate__animated animate__fadeInDown animate_fastest"
|
||||||
stroke-width="2"
|
leave-active-class="animate__animated animate__fadeOutUp animate_fastest"
|
||||||
d="M19 9l-7 7-7-7"
|
>
|
||||||
/>
|
<div
|
||||||
</svg>
|
v-if="dropdownOpen"
|
||||||
</button>
|
class="absolute top-full right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1"
|
||||||
<Transition
|
|
||||||
enter-active-class="animate__animated animate__fadeInDown animate_fastest"
|
|
||||||
leave-active-class="animate__animated animate__fadeOutUp animate_fastest"
|
|
||||||
>
|
>
|
||||||
<div
|
<a
|
||||||
v-if="dropdownOpen"
|
v-for="loc in availableLocales"
|
||||||
class="absolute top-full right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1"
|
:key="loc.code"
|
||||||
|
:href="switchLocalePath(loc.code)"
|
||||||
|
v-on:click="dropdownOpen = false"
|
||||||
|
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 transition-all duration-100"
|
||||||
>
|
>
|
||||||
<a
|
{{ loc.name || loc.code }}
|
||||||
v-for="loc in availableLocales"
|
</a>
|
||||||
:key="loc.code"
|
</div>
|
||||||
:href="switchLocalePath(loc.code)"
|
</Transition>
|
||||||
v-on:click="dropdownOpen = false"
|
|
||||||
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 transition-all duration-100"
|
|
||||||
>
|
|
||||||
{{ loc.name || loc.code }}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</Transition>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
"newsComparePlatform": "news comparison platform"
|
"newsComparePlatform": "news comparison platform"
|
||||||
},
|
},
|
||||||
"startusing": "Let's Start!",
|
"startusing": "Let's Start!",
|
||||||
"learnmore": "Learn More",
|
"learnmore": "Learn More"
|
||||||
},
|
},
|
||||||
"dailybriefing": "Daily Briefing",
|
"dailybriefing": "Daily Briefing",
|
||||||
"Welcome": "Welcome",
|
"Welcome": "Welcome",
|
||||||
|
@ -16,7 +16,8 @@ export default defineNuxtConfig({
|
|||||||
"@nuxtjs/i18n",
|
"@nuxtjs/i18n",
|
||||||
"@nuxtjs/tailwindcss",
|
"@nuxtjs/tailwindcss",
|
||||||
"shadcn-nuxt",
|
"shadcn-nuxt",
|
||||||
"motion-v/nuxt"
|
"motion-v/nuxt",
|
||||||
|
"@clerk/nuxt",
|
||||||
],
|
],
|
||||||
i18n: {
|
i18n: {
|
||||||
defaultLocale: "en",
|
defaultLocale: "en",
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
"start": "bun run .output/server/index.mjs"
|
"start": "bun run .output/server/index.mjs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@clerk/nuxt": "^1.6.3",
|
||||||
"@fontsource-variable/noto-sans-tc": "^5.2.5",
|
"@fontsource-variable/noto-sans-tc": "^5.2.5",
|
||||||
"@fontsource/fira-code": "^5.2.6",
|
"@fontsource/fira-code": "^5.2.6",
|
||||||
"@fontsource/fira-sans": "^5.2.5",
|
"@fontsource/fira-sans": "^5.2.5",
|
||||||
|
@ -1,3 +1,73 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
layout: false,
|
||||||
|
});
|
||||||
|
import { gsap } from "gsap";
|
||||||
|
import { TextPlugin } from "gsap/TextPlugin";
|
||||||
|
gsap.registerPlugin(TextPlugin);
|
||||||
|
const { t } = useI18n();
|
||||||
|
const localePath = useLocalePath();
|
||||||
|
const router = useRouter();
|
||||||
|
const popMessage = ref(null);
|
||||||
|
const currentDate = ref(
|
||||||
|
new Date().toLocaleDateString("zh-TW", {
|
||||||
|
month: "2-digit",
|
||||||
|
day: "2-digit",
|
||||||
|
year: "numeric",
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
second: "2-digit",
|
||||||
|
hour12: false,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
setInterval(() => {
|
||||||
|
currentDate.value = new Date().toLocaleDateString("zh-TW", {
|
||||||
|
month: "2-digit",
|
||||||
|
day: "2-digit",
|
||||||
|
year: "numeric",
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
second: "2-digit",
|
||||||
|
hour12: false,
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
import { ComputerDesktopIcon } from "@heroicons/vue/24/outline";
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<h1>The "For you page"</h1>
|
<div
|
||||||
|
class="absolute inset-x-0 flex flex-row px-2 py-1 bg-white dark:bg-gray-900 justify-between align-center text-center z-index-[999999]"
|
||||||
|
>
|
||||||
|
<div class="flex flex-row g-2 text-gray-400 dark:text-gray-500">
|
||||||
|
<button @click="" class="w-8 h-8 text-gray-400 dark:text-gray-500">
|
||||||
|
<ComputerDesktopIcon class="w-8 h-8 text-gray-400 dark:text-gray-500" />
|
||||||
|
</button>
|
||||||
|
<span class="ml-1 mr-2 text-[20px]">|</span>
|
||||||
|
</div>
|
||||||
|
<div class="text-gray-400">{{ currentDate }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="w-full h-[2.5em]"></div>
|
||||||
|
<div
|
||||||
|
class="flex flex-col justify-center align-center text-center absolute w-full h-screen inset-x-0 inset-y-0"
|
||||||
|
>
|
||||||
|
<div class="z-index-[9]"></div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="absolute w-[calc(100% - 5px)] inset-x-0 bottom-0 mx-[1.5px] p-3 z-index-[999999] justify-between align-center flex flex-row"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
Lang: <span class="text-sm">{{ $i18n.locale }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="">
|
||||||
|
<SignedOut>
|
||||||
|
<SignInButton />
|
||||||
|
</SignedOut>
|
||||||
|
<SignedIn>
|
||||||
|
<UserButton />
|
||||||
|
</SignedIn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -55,33 +55,58 @@ onMounted(() => {
|
|||||||
></span>
|
></span>
|
||||||
<div class="flex flex-row justify-center align-center gap-0s">
|
<div class="flex flex-row justify-center align-center gap-0s">
|
||||||
<NuxtLink :to="localePath('/app/')">
|
<NuxtLink :to="localePath('/app/')">
|
||||||
<button
|
<button
|
||||||
class="m-4 mr-1 ml-1 bg-[#8C9393] text-white p-3 rounded-full bg-gradient-to-l from-sky-500 to-purple-600 transition-all duration-150 hover:transform hover:scale-105 hover:shadow-lg"
|
class="m-4 mr-1 ml-1 bg-[#8C9393] text-white p-3 rounded-[10px] bg-gradient-to-l from-sky-500 to-purple-600 transition-all duration-150 hover:transform hover:scale-105 hover:shadow-lg"
|
||||||
>
|
>
|
||||||
<span>{{ t("home.startusing") }}</span>
|
<span>{{ t("home.startusing") }}</span>
|
||||||
</button>
|
</button>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink to="#learnmore">
|
<NuxtLink to="#learnmore">
|
||||||
<button
|
<button
|
||||||
class="m-4 ml-1 mr-1 bg-[#8C9393] text-white p-3 rounded-[10px] bg-gray-700 transition-all duration-150 hover:transform hover:scale-105 hover:shadow-lg"
|
class="m-4 ml-1 mr-1 bg-[#8C9393] text-white p-3 rounded-[10px] bg-gray-700 transition-all duration-150 hover:transform hover:scale-105 hover:shadow-lg"
|
||||||
>
|
>
|
||||||
<span>{{ t("home.learnmore") }}</span>
|
<span>{{ t("home.learnmore") }}</span>
|
||||||
</button>
|
</button>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="h-screen"></div>
|
<div class="h-screen"></div>
|
||||||
<div id="learnmore"></div>
|
<div id="learnmore"></div>
|
||||||
<div class="flex flex-row flex-wrap justify-center gap-x-10 gap-y-3">
|
<div class="flex flex-row flex-wrap justify-center gap-x-10 gap-y-3">
|
||||||
<div class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5 w-[300px] h-[200px]">
|
<div
|
||||||
|
class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5 w-[300px] h-[200px]"
|
||||||
|
>
|
||||||
<h1 class="text-8xl mt-0">🤔</h1>
|
<h1 class="text-8xl mt-0">🤔</h1>
|
||||||
<h2 class="text-xl font-bold">Why?</h2>
|
<h2 class="text-xl font-bold">Why?</h2>
|
||||||
<span class="text-sm">台灣的新聞是要痲是來自中國控制的媒體,或是來自只想獲得點閱的記者。</span>
|
<span class="text-sm"
|
||||||
|
>台灣的新聞是要痲是來自中國控制的媒體,或是來自只想獲得點閱的記者。</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5 w-[300px] h-[200px]">
|
<div
|
||||||
|
class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5 w-[300px] h-[200px]"
|
||||||
|
>
|
||||||
<h1 class="text-8xl mt-0">🧐</h1>
|
<h1 class="text-8xl mt-0">🧐</h1>
|
||||||
<h2 class="text-xl font-bold">How?</h2>
|
<h2 class="text-xl font-bold">How?</h2>
|
||||||
<span class="text-sm">We use web scraping to search for the latest news, and store it into a postgres database.</span>
|
<span class="text-sm"
|
||||||
|
>We use web scraping to search for the latest news, and store it into
|
||||||
|
a postgres database.</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<h2 class="text-center align-center justify-center text-3xl">
|
||||||
|
Coming soon...
|
||||||
|
</h2>
|
||||||
|
<div class="flex flex-row flex-wrap justify-center gap-x-10 gap-y-3">
|
||||||
|
<div
|
||||||
|
class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5"
|
||||||
|
>
|
||||||
|
<h2 class="text-xl font-bold">Threads 文比較</h2>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5"
|
||||||
|
>
|
||||||
|
<h2 class="text-xl font-bold">新聞 Facebook 觀點</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -36,18 +36,15 @@ soup = BeautifulSoup(html, "html.parser")
|
|||||||
# Find the topiccwiz element
|
# Find the topiccwiz element
|
||||||
topiccwiz = soup.find_all("c-wiz", class_=topiccwiz_css)
|
topiccwiz = soup.find_all("c-wiz", class_=topiccwiz_css)
|
||||||
news_data = []
|
news_data = []
|
||||||
|
index = 0
|
||||||
for item in topiccwiz:
|
for item in topiccwiz:
|
||||||
|
index+= 1
|
||||||
|
array = []
|
||||||
hotarticles = item.find_all("article")
|
hotarticles = item.find_all("article")
|
||||||
first_article = ""
|
first_article = ""
|
||||||
passed_first = False
|
passed_first = False
|
||||||
for article in hotarticles:
|
for article in hotarticles:
|
||||||
try:
|
try:
|
||||||
if not passed_first:
|
|
||||||
first_title_elem = article.find('a', class_='gPFEn')
|
|
||||||
first_title = first_title_elem.text.strip() if first_title_elem else ''
|
|
||||||
first_article = first_title
|
|
||||||
passed_first = True
|
|
||||||
continue
|
|
||||||
title_elem = article.find('a', class_='gPFEn')
|
title_elem = article.find('a', class_='gPFEn')
|
||||||
title = title_elem.text.strip() if title_elem else ''
|
title = title_elem.text.strip() if title_elem else ''
|
||||||
|
|
||||||
@ -60,13 +57,17 @@ for item in topiccwiz:
|
|||||||
'title': title,
|
'title': title,
|
||||||
'source': source,
|
'source': source,
|
||||||
'link': link,
|
'link': link,
|
||||||
'category': first_article
|
|
||||||
}
|
}
|
||||||
news_data.append(article_data)
|
array.append(article_data)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error processing article: {e}")
|
print(f"Error processing article: {e}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
sendData = {
|
||||||
|
index: array
|
||||||
|
}
|
||||||
|
news_data.append(sendData)
|
||||||
|
|
||||||
with open('news.json', 'w', encoding='utf-8') as f:
|
with open('news.json', 'w', encoding='utf-8') as f:
|
||||||
json.dump(news_data, f, ensure_ascii=False, indent=2)
|
json.dump(news_data, f, ensure_ascii=False, indent=2)
|
||||||
|
|
||||||
|
1148
scraping/news.json
1148
scraping/news.json
File diff suppressed because it is too large
Load Diff
@ -1,5 +0,0 @@
|
|||||||
export default defineEventHandler(async (event) => {});
|
|
||||||
|
|
||||||
async function findUser(githubUser: any) {
|
|
||||||
console.log("Github User: " + githubUser);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
import crypto from "node:crypto";
|
|
||||||
export default defineEventHandler(async (event) => {
|
|
||||||
const baseUrl = event.node.req.headers.host;
|
|
||||||
const protocol = process.env.NODE_ENV === "production" ? "https" : "http";
|
|
||||||
const clientId = process.env.NUXT_GITHUB_CLIENT_ID;
|
|
||||||
const callbackUrl = `${protocol}://${baseUrl}/api/auth/github/callback`;
|
|
||||||
const state = crypto.randomBytes(16).toString("hex");
|
|
||||||
setCookie(event, "oauth_state", state, {
|
|
||||||
httpOnly: true,
|
|
||||||
secure: process.env.NODE_ENV === "production",
|
|
||||||
maxAge: 60 * 10,
|
|
||||||
path: "/",
|
|
||||||
});
|
|
||||||
const authorizationUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(callbackUrl)}&scope=read:user,user:email&state=${state}`;
|
|
||||||
await sendRedirect(event, authorizationUrl, 302);
|
|
||||||
});
|
|
Loading…
x
Reference in New Issue
Block a user