From d502d2dbc5752c31d5c2432e8154c58a54240920 Mon Sep 17 00:00:00 2001 From: Tejas Panchal Date: Thu, 24 Jul 2025 19:41:17 +0530 Subject: [PATCH] Landing page --- .env.example | 17 +- .gitignore | 158 +- LICENSE | 60 +- README.md | 155 +- components.json | 20 + eslint.config.js | 38 + eslint.config.mjs | 14 - index.html | 93 + jsconfig.json | 10 +- lib/utils.js | 6 + next.config.js | 86 - next.config.mjs | 17 - package-lock.json | 5180 +++++++++-------- package.json | 65 +- postcss.config.js | 6 + postcss.config.mjs | 5 - public/images/placeholder.png | Bin 40 -> 0 bytes public/robots.txt | 4 + public/sitemap.xml | 2430 ++++++++ public/{LandingPage.jpg => splash.jpg} | Bin src/App.css | 27 + src/App.jsx | 73 + src/app/anime/[id]/page.js | 100 - src/app/anime/layout.js | 5 - src/app/contacts/page.jsx | 169 - src/app/dmca/page.jsx | 62 - src/app/favicon.ico | Bin 25931 -> 0 bytes src/app/globals.css | 173 - src/app/home/layout.js | 5 - src/app/home/page.js | 202 - src/app/latest-completed/layout.js | 5 - src/app/latest-completed/page.js | 305 - src/app/layout.js | 34 - src/app/most-popular/layout.js | 5 - src/app/most-popular/page.js | 305 - src/app/page.jsx | 321 - src/app/recent/layout.js | 5 - src/app/recent/page.js | 305 - src/app/search/[query]/page.js | 311 - src/app/search/layout.js | 5 - src/app/search/page.js | 433 -- src/app/terms-and-services/page.jsx | 191 - src/app/top-airing/layout.js | 5 - src/app/top-airing/page.js | 276 - src/app/watch/[episodeId]/page.js | 664 --- src/app/watch/layout.js | 5 - src/components/AnimeCalendar.js | 210 - src/components/AnimeCard.js | 158 - src/components/AnimeDetails.js | 585 -- src/components/AnimeFilters.js | 597 -- src/components/AnimeRow.js | 131 - src/components/AnimeTabs.js | 86 - src/components/EpisodeList.js | 239 - src/components/GenreBar.js | 230 - src/components/GenreList.js | 93 - src/components/Loader/AnimeInfo.loader.jsx | 58 + src/components/Loader/AtoZ.loader.jsx | 26 + src/components/Loader/Cart.loader.jsx | 27 + src/components/Loader/Category.loader.jsx | 23 + src/components/Loader/CategoryCard.loader.jsx | 35 + src/components/Loader/Home.loader.jsx | 32 + src/components/Loader/Loader.jsx | 24 + src/components/Loader/Producer.loader.jsx | 15 + src/components/Loader/Sidecard.loader.jsx | 26 + src/components/Loader/Spotlight.loader.jsx | 34 + src/components/Loader/Trending.loader.jsx | 34 + .../Loader/VoiceActorlist.loader.jsx | 21 + src/components/Navbar.js | 628 -- src/components/SeasonCard.js | 56 - src/components/SeasonRow.js | 162 - src/components/SharedLayout.js | 86 - src/components/SpotlightCarousel.js | 371 -- src/components/TopLists.js | 159 - src/components/TrendingList.js | 55 - src/components/VideoPlayer.js | 1542 ----- src/components/banner/Banner.css | 133 + src/components/banner/Banner.jsx | 136 + src/components/cart/Cart.css | 10 + src/components/cart/Cart.jsx | 132 + src/components/categorycard/CategoryCard.css | 27 + src/components/categorycard/CategoryCard.jsx | 340 ++ src/components/continue/ContinueWatching.jsx | 132 + src/components/episodelist/Episodelist.css | 15 + src/components/episodelist/Episodelist.jsx | 303 + src/components/error/Error.jsx | 21 + src/components/footer/Footer.jsx | 62 + src/components/genres/Genre.jsx | 54 + src/components/navbar/Navbar.jsx | 147 + src/components/pageslider/PageSlider.jsx | 76 + src/components/player/IframePlayer.jsx | 148 + src/components/player/Player.css | 59 + src/components/player/Player.jsx | 494 ++ src/components/player/PlayerIcons.jsx | 103 + .../player/artPlayerPluginVttThumbnail.js | 72 + src/components/player/artPlayerPluinChaper.js | 211 + .../player/artplayerPluginUploadSubtitle.js | 49 + src/components/player/autoSkip.js | 74 + src/components/player/getChapterStyle.js | 82 + src/components/player/getVttArray.js | 101 + src/components/player/pluginChapterStyle.js | 55 + src/components/producer/Producer.jsx | 102 + src/components/qtip/Qtip.jsx | 159 + src/components/schedule/Schedule.jsx | 241 + src/components/schedule/schedule.css | 11 + src/components/searchbar/MobileSearch.jsx | 73 + src/components/searchbar/WebSearch.jsx | 77 + src/components/servers/Servers.css | 9 + src/components/servers/Servers.jsx | 187 + src/components/sidebar/Sidebar.jsx | 141 + src/components/sidecard/Sidecard.jsx | 142 + src/components/splashscreen/SplashScreen.css | 227 + src/components/splashscreen/SplashScreen.jsx | 107 + src/components/spotlight/Spotlight.css | 68 + src/components/spotlight/Spotlight.jsx | 54 + src/components/suggestion/Suggestion.jsx | 115 + src/components/topten/Topten.jsx | 176 + src/components/trending/Trending.jsx | 77 + src/components/ui/Skeleton/Skeleton.css | 23 + src/components/ui/Skeleton/Skeleton.jsx | 16 + .../ui/bouncingloader/Bouncingloader.css | 45 + .../ui/bouncingloader/Bouncingloader.jsx | 12 + src/components/voiceactor/Voiceactor.jsx | 100 + .../voiceactorlist/VoiceactorList.jsx | 175 + .../watchcontrols/Watchcontrols.jsx | 97 + src/config/logoTitle.js | 3 + src/config/website.js | 3 + src/context/HomeInfoContext.jsx | 31 + src/context/LanguageContext.jsx | 27 + src/context/SearchContext.jsx | 13 + src/helper/toggleScrollbar.js | 32 + src/hooks/useSearch.js | 64 + src/hooks/useToolTipPosition.js | 49 + src/hooks/useWatch.js | 269 + src/hooks/useWatchControl.js | 34 + src/index.css | 126 + src/lib/api.js | 858 --- src/main.jsx | 13 + src/pages/Home/Home.jsx | 82 + src/pages/a2z/AtoZ.jsx | 118 + src/pages/animeInfo/AnimeInfo.jsx | 416 ++ src/pages/category/Category.jsx | 111 + src/pages/search/Search.jsx | 74 + src/pages/watch/Watch.jsx | 541 ++ src/utils/category.utils.js | 89 + src/utils/getAnimeInfo.utils.js | 18 + src/utils/getCategoryInfo.utils.js | 14 + src/utils/getEpisodes.utils.js | 12 + src/utils/getHomeInfo.utils.js | 58 + src/utils/getNextEpisodeSchedule.utils.js | 14 + src/utils/getProducer.utils.js | 14 + src/utils/getQtip.utils.js | 18 + src/utils/getScheduleInfo.utils.js | 12 + src/utils/getSearch.utils.js | 17 + src/utils/getSearchSuggestion.utils.js | 16 + src/utils/getServers.utils.js | 14 + src/utils/getStreamInfo.utils.js | 12 + src/utils/getTopSearch.utils.js | 32 + src/utils/getVoiceActor.utils.js | 14 + tailwind.config.js | 62 + vercel.json | 3 + vite.config.js | 12 + 161 files changed, 14116 insertions(+), 12747 deletions(-) create mode 100644 components.json create mode 100644 eslint.config.js delete mode 100644 eslint.config.mjs create mode 100644 index.html create mode 100644 lib/utils.js delete mode 100644 next.config.js delete mode 100644 next.config.mjs create mode 100644 postcss.config.js delete mode 100644 postcss.config.mjs delete mode 100644 public/images/placeholder.png create mode 100644 public/robots.txt create mode 100644 public/sitemap.xml rename public/{LandingPage.jpg => splash.jpg} (100%) create mode 100644 src/App.css create mode 100644 src/App.jsx delete mode 100644 src/app/anime/[id]/page.js delete mode 100644 src/app/anime/layout.js delete mode 100644 src/app/contacts/page.jsx delete mode 100644 src/app/dmca/page.jsx delete mode 100644 src/app/favicon.ico delete mode 100644 src/app/globals.css delete mode 100644 src/app/home/layout.js delete mode 100644 src/app/home/page.js delete mode 100644 src/app/latest-completed/layout.js delete mode 100644 src/app/latest-completed/page.js delete mode 100644 src/app/layout.js delete mode 100644 src/app/most-popular/layout.js delete mode 100644 src/app/most-popular/page.js delete mode 100644 src/app/page.jsx delete mode 100644 src/app/recent/layout.js delete mode 100644 src/app/recent/page.js delete mode 100644 src/app/search/[query]/page.js delete mode 100644 src/app/search/layout.js delete mode 100644 src/app/search/page.js delete mode 100644 src/app/terms-and-services/page.jsx delete mode 100644 src/app/top-airing/layout.js delete mode 100644 src/app/top-airing/page.js delete mode 100644 src/app/watch/[episodeId]/page.js delete mode 100644 src/app/watch/layout.js delete mode 100644 src/components/AnimeCalendar.js delete mode 100644 src/components/AnimeCard.js delete mode 100644 src/components/AnimeDetails.js delete mode 100644 src/components/AnimeFilters.js delete mode 100644 src/components/AnimeRow.js delete mode 100644 src/components/AnimeTabs.js delete mode 100644 src/components/EpisodeList.js delete mode 100644 src/components/GenreBar.js delete mode 100644 src/components/GenreList.js create mode 100644 src/components/Loader/AnimeInfo.loader.jsx create mode 100644 src/components/Loader/AtoZ.loader.jsx create mode 100644 src/components/Loader/Cart.loader.jsx create mode 100644 src/components/Loader/Category.loader.jsx create mode 100644 src/components/Loader/CategoryCard.loader.jsx create mode 100644 src/components/Loader/Home.loader.jsx create mode 100644 src/components/Loader/Loader.jsx create mode 100644 src/components/Loader/Producer.loader.jsx create mode 100644 src/components/Loader/Sidecard.loader.jsx create mode 100644 src/components/Loader/Spotlight.loader.jsx create mode 100644 src/components/Loader/Trending.loader.jsx create mode 100644 src/components/Loader/VoiceActorlist.loader.jsx delete mode 100644 src/components/Navbar.js delete mode 100644 src/components/SeasonCard.js delete mode 100644 src/components/SeasonRow.js delete mode 100644 src/components/SharedLayout.js delete mode 100644 src/components/SpotlightCarousel.js delete mode 100644 src/components/TopLists.js delete mode 100644 src/components/TrendingList.js delete mode 100644 src/components/VideoPlayer.js create mode 100644 src/components/banner/Banner.css create mode 100644 src/components/banner/Banner.jsx create mode 100644 src/components/cart/Cart.css create mode 100644 src/components/cart/Cart.jsx create mode 100644 src/components/categorycard/CategoryCard.css create mode 100644 src/components/categorycard/CategoryCard.jsx create mode 100644 src/components/continue/ContinueWatching.jsx create mode 100644 src/components/episodelist/Episodelist.css create mode 100644 src/components/episodelist/Episodelist.jsx create mode 100644 src/components/error/Error.jsx create mode 100644 src/components/footer/Footer.jsx create mode 100644 src/components/genres/Genre.jsx create mode 100644 src/components/navbar/Navbar.jsx create mode 100644 src/components/pageslider/PageSlider.jsx create mode 100644 src/components/player/IframePlayer.jsx create mode 100644 src/components/player/Player.css create mode 100644 src/components/player/Player.jsx create mode 100644 src/components/player/PlayerIcons.jsx create mode 100644 src/components/player/artPlayerPluginVttThumbnail.js create mode 100644 src/components/player/artPlayerPluinChaper.js create mode 100644 src/components/player/artplayerPluginUploadSubtitle.js create mode 100644 src/components/player/autoSkip.js create mode 100644 src/components/player/getChapterStyle.js create mode 100644 src/components/player/getVttArray.js create mode 100644 src/components/player/pluginChapterStyle.js create mode 100644 src/components/producer/Producer.jsx create mode 100644 src/components/qtip/Qtip.jsx create mode 100644 src/components/schedule/Schedule.jsx create mode 100644 src/components/schedule/schedule.css create mode 100644 src/components/searchbar/MobileSearch.jsx create mode 100644 src/components/searchbar/WebSearch.jsx create mode 100644 src/components/servers/Servers.css create mode 100644 src/components/servers/Servers.jsx create mode 100644 src/components/sidebar/Sidebar.jsx create mode 100644 src/components/sidecard/Sidecard.jsx create mode 100644 src/components/splashscreen/SplashScreen.css create mode 100644 src/components/splashscreen/SplashScreen.jsx create mode 100644 src/components/spotlight/Spotlight.css create mode 100644 src/components/spotlight/Spotlight.jsx create mode 100644 src/components/suggestion/Suggestion.jsx create mode 100644 src/components/topten/Topten.jsx create mode 100644 src/components/trending/Trending.jsx create mode 100644 src/components/ui/Skeleton/Skeleton.css create mode 100644 src/components/ui/Skeleton/Skeleton.jsx create mode 100644 src/components/ui/bouncingloader/Bouncingloader.css create mode 100644 src/components/ui/bouncingloader/Bouncingloader.jsx create mode 100644 src/components/voiceactor/Voiceactor.jsx create mode 100644 src/components/voiceactorlist/VoiceactorList.jsx create mode 100644 src/components/watchcontrols/Watchcontrols.jsx create mode 100644 src/config/logoTitle.js create mode 100644 src/config/website.js create mode 100644 src/context/HomeInfoContext.jsx create mode 100644 src/context/LanguageContext.jsx create mode 100644 src/context/SearchContext.jsx create mode 100644 src/helper/toggleScrollbar.js create mode 100644 src/hooks/useSearch.js create mode 100644 src/hooks/useToolTipPosition.js create mode 100644 src/hooks/useWatch.js create mode 100644 src/hooks/useWatchControl.js create mode 100644 src/index.css delete mode 100644 src/lib/api.js create mode 100644 src/main.jsx create mode 100644 src/pages/Home/Home.jsx create mode 100644 src/pages/a2z/AtoZ.jsx create mode 100644 src/pages/animeInfo/AnimeInfo.jsx create mode 100644 src/pages/category/Category.jsx create mode 100644 src/pages/search/Search.jsx create mode 100644 src/pages/watch/Watch.jsx create mode 100644 src/utils/category.utils.js create mode 100644 src/utils/getAnimeInfo.utils.js create mode 100644 src/utils/getCategoryInfo.utils.js create mode 100644 src/utils/getEpisodes.utils.js create mode 100644 src/utils/getHomeInfo.utils.js create mode 100644 src/utils/getNextEpisodeSchedule.utils.js create mode 100644 src/utils/getProducer.utils.js create mode 100644 src/utils/getQtip.utils.js create mode 100644 src/utils/getScheduleInfo.utils.js create mode 100644 src/utils/getSearch.utils.js create mode 100644 src/utils/getSearchSuggestion.utils.js create mode 100644 src/utils/getServers.utils.js create mode 100644 src/utils/getStreamInfo.utils.js create mode 100644 src/utils/getTopSearch.utils.js create mode 100644 src/utils/getVoiceActor.utils.js create mode 100644 tailwind.config.js create mode 100644 vercel.json create mode 100644 vite.config.js diff --git a/.env.example b/.env.example index 706ee2c..995c7d7 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,15 @@ -# Your Self Hosted AniWatch API URL - replace with your own API endpoint -ANIWATCH_API=https://your-api-url.com/api/v2/hianime \ No newline at end of file +#Refer https://github.com/itzzzme/anime-api to host your backend API +VITE_API_URL=/api + +#Refer this gist to setup proxy server https://gist.github.com/itzzzme/180813be2c7b45eedc8ce8344c8dea3b +VITE_PROXY_URL=/?url= + +#Refer https://github.com/itzzzme/m3u8proxy to host you m3u8 proxy server though it's optional but if you don't set it up you may get CORS error for some servers if you set up from the given repo then only the url structure will look like this +VITE_M3U8_PROXY_URL=/m3u8-proxy?url= + +#totaly optional / if you don't want to setup worker just change the code of getQtip.utils.js following the pattern of any other utils file +VITE_WORKER_URL=https://worker1.workers.dev,https://worker2.workers.dev,https://worker3.workers.dev,... + +VITE_BASE_IFRAME_URL=https://megaplay.buzz/stream/s-2 + +VITE_BASE_IFRAME_URL_2=https://vidwish.live/stream/s-2 diff --git a/.gitignore b/.gitignore index e72b4d6..4855fb9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,41 +1,133 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/versions - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug +# Logs +logs +*.log npm-debug.log* yarn-debug.log* yarn-error.log* +lerna-debug.log* .pnpm-debug.log* -# env files (can opt-in for committing if needed) -.env +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json -# vercel -.vercel +# Runtime data +pids +*.pid +*.seed +*.pid.lock -# typescript +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# lock json files +package-lock.json + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache *.tsbuildinfo -next-env.d.ts + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* \ No newline at end of file diff --git a/LICENSE b/LICENSE index 38b7740..85f6de2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,47 +1,21 @@ -Business Source License 1.1 +MIT License -Terms +Copyright (c) 2024 Sayan -The Licensor hereby grants you the right to copy, modify, create derivative -works, redistribute, and make non-production use of the Licensed Work. The -Licensor may make an Additional Use Grant, above, permitting limited -production use. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -Effective on the Change Date, or the fourth anniversary of the first publicly -available distribution of a specific version of the Licensed Work under this -License, whichever comes first, the Licensor hereby grants you rights under -the terms of the Change License, and the rights granted in the paragraph -above terminate. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -If your use of the Licensed Work does not comply with the requirements -currently in effect as described in this License, you must purchase a -commercial license from the Licensor, its affiliated entities, or authorized -resellers, or you must refrain from using the Licensed Work. - -All copies of the original and modified Licensed Work, and derivative works -of the Licensed Work, are subject to this License. This License applies -separately for each version of the Licensed Work and the Change Date may vary -for each version of the Licensed Work released by Licensor. - -You must conspicuously display this License on each original or modified copy -of the Licensed Work. If you receive the Licensed Work in original or -modified form from a third party, the terms and conditions set forth in this -License apply to your use of that work. - -Any use of the Licensed Work in violation of this License will automatically -terminate your rights under this License for the current and all other -versions of the Licensed Work. - -This License does not grant you any right in any trademark or logo of -Licensor or its affiliates (provided that you may use a trademark or logo of -Licensor as expressly required by this License). - -TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON -AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, -EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND -TITLE. - -Change Date: 2027-04-01 - -On the date above, in accordance with the Business Source License, use of this software will be governed by the open source license GPL-3.0. \ No newline at end of file +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 554fe61..1d2b28f 100644 --- a/README.md +++ b/README.md @@ -1,74 +1,119 @@

- - JustAnime - +

+ + AnimeHi + +
+

Zenime - Ad free anime streaming platform

+

+ + Github Stars + + Github Issues + + Github Forks + +

-

JustAnime

- -

A sleek anime streaming platform with a modern UI

-

- About • - Features • - Quick Start • - Development -

+ Zenime is an open-source anime streaming service that uses custom API, built using ReactJS with javascript and Tailwind CSS. It lets you easily find any anime with intuitive search & suggestion feature and stream without any ads. +

-

- - Stars - - - Forks - - - Issues - -

+
+View more Features -## What is JustAnime? +### General -Welcome to **JustAnime**, your premier destination for all things anime! Explore a comprehensive collection of high-definition anime with a seamless and user-friendly interface powered by **[aniwatch-api](https://github.com/ghoshRitesh12/aniwatch-api)**. +- Sub Anime support +- Dub Anime support +- User-friendly interface +- Mobile responsive +- Fast page load +- Character & Voice Actors -Built using **Next.js** and **React**, JustAnime offers a cutting-edge, minimalist design that ensures both fast loading times and smooth navigation. Whether you're looking for the latest anime series or classic favorites, JustAnime has you covered with an ad-free streaming experience that supports both English subtitles and dubbed versions. Additionally, you can easily keep track of your watched episodes without the hassle of creating an account, making your viewing experience as convenient as possible. +### Watch Page -## Features +- Related Animes +- Recommended Animes +- Available seasons +- Estimated schedule of upcoming episodes +- **Player** + - Autoplay + - Autoskip intro/outro + - Autonext -### General: +
-* Sub/Dub Support - Switch between subbed and dubbed versions -* Responsive Design - Optimized for all devices from mobile to desktop -* Continue Watching - Resume from where you left off -* Advanced Search - With real-time suggestions as you type +## Previews -### Player Experience: +
+ Home Page +
+ View more screenshots +
+ AnimeInfo Page + AnimeInfo Page +
+ Searchbar + Searchbar +
+ Character & Voice Actors + Character & Voice Actors +
+ Watch Page + Watch Page +
+
+
-* Autoplay - Seamlessly continue to the next episode -* Quality Selection - Choose your preferred streaming quality -* Multiple Servers - Switch between different streaming servers -* Subtitles - Toggle subtitles on/off -* Playback Speed - Adjust video playback speed -* Audio Controls - Volume adjustment and audio boost option +## Installation and Local Development -## Quick Start +### 1. Make sure you have node installed on your device + +### 2. Run the following code to clone the repository and install all required dependencies ```bash -# Clone the repository & Navigate to projetc directory -git clone https://github.com/tejaspanchall/JustAnime.git -cd JustAnime - -# Install dependencies -npm install - -# Set up environment variables -cp .env.example .env - -# Start development server -npm run dev +git clone https://github.com/itzzzme/zenime.git +cd zenime +npm install # or yarn ``` -Visit [http://localhost:3000](http://localhost:3000) to see the application in action. +### 3. Refer the .env.example to set your .env file up -## Development +## Start the server -Pull requests and stars are always welcome. If you encounter any bug or want to add a new feature to this api, consider creating a new [issue](https://github.com/tejaspanchall/JustAnime/issues). +```bash +npm start # or npm run dev (to run develepment server) +``` +## Live Deployment + +### Vercel + +Host your own instance of Zenime on vercel + +[![Deploy to Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/itzzzme/zenime) + +### Render + +Host your own instance of Zenime on Render. + +[![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/itzzzme/zenime) + +### Pull Requests + +- Pull requests are welcomed that address bug fixes, improvements, or new features. +- Fork the repository and create a new branch for your changes. +- Ensure your code follows our coding standards. +- Include tests if applicable. +- Describe your changes clearly in the pull request, explaining the problem and solution. + + ### Reporting Issues + +If you discover any issues or have suggestions for improvement, please open an issue. Provide a clear and concise description of the problem, steps to reproduce it, and any relevant information about your environment. + +### Support + + If you like the project feel free to drop a star ✨. Your appreciation means a lot. + +

Made by itzzzme +🫰

diff --git a/components.json b/components.json new file mode 100644 index 0000000..d16853e --- /dev/null +++ b/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": false, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/index.css", + "baseColor": "zinc", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + } +} \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..238d2e4 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,38 @@ +import js from '@eslint/js' +import globals from 'globals' +import react from 'eslint-plugin-react' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' + +export default [ + { ignores: ['dist'] }, + { + files: ['**/*.{js,jsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + parserOptions: { + ecmaVersion: 'latest', + ecmaFeatures: { jsx: true }, + sourceType: 'module', + }, + }, + settings: { react: { version: '18.3' } }, + plugins: { + react, + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...js.configs.recommended.rules, + ...react.configs.recommended.rules, + ...react.configs['jsx-runtime'].rules, + ...reactHooks.configs.recommended.rules, + 'react/jsx-no-target-blank': 'off', + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +] diff --git a/eslint.config.mjs b/eslint.config.mjs deleted file mode 100644 index 348c45a..0000000 --- a/eslint.config.mjs +++ /dev/null @@ -1,14 +0,0 @@ -import { dirname } from "path"; -import { fileURLToPath } from "url"; -import { FlatCompat } from "@eslint/eslintrc"; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); - -const compat = new FlatCompat({ - baseDirectory: __dirname, -}); - -const eslintConfig = [...compat.extends("next/core-web-vitals")]; - -export default eslintConfig; diff --git a/index.html b/index.html new file mode 100644 index 0000000..ea57811 --- /dev/null +++ b/index.html @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + JustAnime | Free Anime Streaming Platform + + + + + + + +
+ + + diff --git a/jsconfig.json b/jsconfig.json index b8d6842..0d81cf7 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,7 +1,9 @@ { - "compilerOptions": { - "paths": { - "@/*": ["./src/*"] + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["./*"] + } } } -} + \ No newline at end of file diff --git a/lib/utils.js b/lib/utils.js new file mode 100644 index 0000000..b20bf01 --- /dev/null +++ b/lib/utils.js @@ -0,0 +1,6 @@ +import { clsx } from "clsx"; +import { twMerge } from "tailwind-merge" + +export function cn(...inputs) { + return twMerge(clsx(inputs)); +} diff --git a/next.config.js b/next.config.js deleted file mode 100644 index 7e98866..0000000 --- a/next.config.js +++ /dev/null @@ -1,86 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - reactStrictMode: true, - env: { - // Environment variables here - }, - images: { - domains: [ - 'via.placeholder.com', - 'gogocdn.net', - 'cdnjs.cloudflare.com', - 'img.zorores.com', - 'poster.zoros.to', - 'cdn.myanimelist.net', - 's4.anilist.co', - 'artworks.thetvdb.com', - 'image.tmdb.org', - 'justanimeapi.vercel.app', - 'consumet.org', - 'api.consumet.org', - 'img.flixhq.to', - 'img.bflix.to', - ], - remotePatterns: [ - { - protocol: 'https', - hostname: '**', - }, - ], - unoptimized: true, - }, - experimental: { - scrollRestoration: true, - }, - serverExternalPackages: ['puppeteer-core'], - async rewrites() { - // Get the API URL from environment variable or use default - const apiUrl = process.env.ANIWATCH_API; - // Extract the base URL without the /api/v2/hianime path - const baseUrl = apiUrl.replace('/api/v2/hianime', ''); - - return [ - { - source: '/api/v2/hianime/:path*', - destination: `${apiUrl}/:path*` - }, - { - source: '/api/anime/:path*', - destination: `${apiUrl}/anime/:path*` - } - ] - }, - async headers() { - return [ - { - source: '/api/:path*', - headers: [ - { key: 'Access-Control-Allow-Credentials', value: 'true' }, - { key: 'Access-Control-Allow-Origin', value: '*' }, - { key: 'Access-Control-Allow-Methods', value: 'GET,OPTIONS,PATCH,DELETE,POST,PUT' }, - { key: 'Access-Control-Allow-Headers', value: 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, Authorization' }, - { key: 'Referrer-Policy', value: 'no-referrer-when-downgrade' }, - { key: 'Cross-Origin-Resource-Policy', value: 'cross-origin' }, - { key: 'Cross-Origin-Opener-Policy', value: 'same-origin' }, - ], - }, - { - source: '/:path*', - headers: [ - { key: 'Referrer-Policy', value: 'no-referrer-when-downgrade' }, - { key: 'Cross-Origin-Resource-Policy', value: 'cross-origin' }, - { key: 'Cross-Origin-Opener-Policy', value: 'same-origin' }, - ] - } - ]; - }, - webpack(config) { - config.module.rules.push({ - test: /\.svg$/, - use: [{ loader: '@svgr/webpack', options: { icon: true } }], - }); - return config; - }, -}; - -module.exports = nextConfig; \ No newline at end of file diff --git a/next.config.mjs b/next.config.mjs deleted file mode 100644 index 1f50146..0000000 --- a/next.config.mjs +++ /dev/null @@ -1,17 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - env: { - // Environment variables here - }, - images: { - unoptimized: true, - remotePatterns: [ - { - protocol: 'https', - hostname: '**', - }, - ], - } -}; - -export default nextConfig; diff --git a/package-lock.json b/package-lock.json index f7a61b5..83e3160 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,38 +1,58 @@ { "name": "justanime", - "version": "0.1.0", + "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "justanime", - "version": "0.1.0", + "version": "0.0.0", "dependencies": { - "@heroicons/react": "^2.2.0", - "@vercel/analytics": "^1.5.0", - "@vercel/speed-insights": "^1.2.0", - "hls.js": "^1.5.7", - "next": "latest", - "proxy-from-env": "^1.1.0", - "react": "latest", - "react-dom": "latest", - "swiper": "^11.2.6" + "@fortawesome/fontawesome-svg-core": "^6.6.0", + "@fortawesome/free-brands-svg-icons": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.6.0", + "@fortawesome/react-fontawesome": "^0.2.2", + "@radix-ui/react-icons": "^1.3.0", + "artplayer": "^5.2.3", + "artplayer-plugin-chapter": "^1.0.0", + "artplayer-plugin-hls-control": "^1.0.1", + "axios": "^1.7.7", + "cheerio": "^1.0.0", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "hls.js": "^1.5.17", + "lucide-react": "^0.447.0", + "react": "^18.3.1", + "react-content-loader": "^7.0.2", + "react-dom": "^18.3.1", + "react-icons": "^5.3.0", + "react-lazy-load": "^4.0.1", + "react-router-dom": "^6.26.2", + "styled-components": "^6.1.13", + "swiper": "^11.2.5", + "tailwind-merge": "^2.5.3", + "tailwindcss-animate": "^1.0.7" }, "devDependencies": { - "@eslint/eslintrc": "^3", - "@tailwindcss/postcss": "^4", - "autoprefixer": "latest", - "eslint": "^9", - "eslint-config-next": "15.2.5", - "postcss": "latest", - "tailwindcss": "^4" + "@eslint/js": "^9.9.0", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "autoprefixer": "^10.4.20", + "eslint": "^9.9.0", + "eslint-plugin-react": "^7.35.0", + "eslint-plugin-react-hooks": "^5.1.0-rc.0", + "eslint-plugin-react-refresh": "^0.4.9", + "globals": "^15.9.0", + "postcss": "^8.4.47", + "tailwindcss": "^3.4.13", + "vite": "^5.4.1" } }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -41,43 +61,718 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@emnapi/core": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.0.tgz", - "integrity": "sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg==", + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", + "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", + "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.0", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.6", + "@babel/parser": "^7.28.0", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", + "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.0", + "@babel/types": "^7.28.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.2.tgz", + "integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", + "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.0", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.0.1", - "tslib": "^2.4.0" + "os": [ + "aix" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@emnapi/runtime": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.0.tgz", - "integrity": "sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.1.tgz", - "integrity": "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==", + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", "optional": true, - "dependencies": { - "tslib": "^2.4.0" + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz", - "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", "dev": true, "license": "MIT", "dependencies": { @@ -117,9 +812,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", - "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -132,9 +827,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", - "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz", + "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -142,9 +837,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", - "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", + "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -178,14 +873,30 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@eslint/js": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.24.0.tgz", - "integrity": "sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==", + "version": "9.31.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz", + "integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==", "dev": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { @@ -199,39 +910,75 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz", + "integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.13.0", + "@eslint/core": "^0.15.1", "levn": "^0.4.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz", + "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==", + "license": "MIT", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=6" } }, - "node_modules/@heroicons/react": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz", - "integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==", + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz", + "integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==", "license": "MIT", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-brands-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.7.2.tgz", + "integrity": "sha512-zu0evbcRTgjKfrr77/2XX+bU+kuGfjm0LbajJHVIgBWNIDzrhpRxiCPNT8DW5AdmSsq7Mcf9D1bH0aSeSUSM+Q==", + "license": "(CC-BY-4.0 AND MIT)", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz", + "integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==", + "license": "(CC-BY-4.0 AND MIT)", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.3.tgz", + "integrity": "sha512-HlJco8RDY8NrzFVjy23b/7mNS4g9NegcrBG3n7jinwpc2x/AmSVk53IhWniLYM4szYLxRAFTAGwGn0EIlclDeQ==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.8.1" + }, "peerDependencies": { - "react": ">= 16 || ^19.0.0-rc" + "@fortawesome/fontawesome-svg-core": "~1 || ~6 || ~7", + "react": "^16.3 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/@humanfs/core": { @@ -287,9 +1034,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -300,529 +1047,62 @@ "url": "https://github.com/sponsors/nzakas" } }, - "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/@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/@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/@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/@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/@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/@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/@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/@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/@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/@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/@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/@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/@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/@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/@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/@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, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", "dependencies": { - "@emnapi/runtime": "^1.2.0" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" + "node": ">=12" } }, - "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/@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/@napi-rs/wasm-runtime": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.8.tgz", - "integrity": "sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==", - "dev": true, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", "license": "MIT", - "optional": true, "dependencies": { - "@emnapi/core": "^1.4.0", - "@emnapi/runtime": "^1.4.0", - "@tybys/wasm-util": "^0.9.0" + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@next/env": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@next/env/-/env-15.2.5.tgz", - "integrity": "sha512-uWkCf9C8wKTyQjqrNk+BA7eL3LOQdhL+xlmJUf2O85RM4lbzwBwot3Sqv2QGe/RGnc3zysIf1oJdtq9S00pkmQ==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", "license": "MIT" }, - "node_modules/@next/eslint-plugin-next": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.2.5.tgz", - "integrity": "sha512-Q1ncASVFKSy+AbabimYxr/2HH/h+qlKlwu1fYV48xUefGzVimS3i3nKwYsM2w+rLdpMFdJyoVowrYyjKu47rBw==", - "dev": true, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", "license": "MIT", "dependencies": { - "fast-glob": "3.3.1" - } - }, - "node_modules/@next/swc-darwin-arm64": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.2.5.tgz", - "integrity": "sha512-4OimvVlFTbgzPdA0kh8A1ih6FN9pQkL4nPXGqemEYgk+e7eQhsst/p35siNNqA49eQA6bvKZ1ASsDtu9gtXuog==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.2.5.tgz", - "integrity": "sha512-ohzRaE9YbGt1ctE0um+UGYIDkkOxHV44kEcHzLqQigoRLaiMtZzGrA11AJh2Lu0lv51XeiY1ZkUvkThjkVNBMA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.2.5.tgz", - "integrity": "sha512-FMSdxSUt5bVXqqOoZCc/Seg4LQep9w/fXTazr/EkpXW2Eu4IFI9FD7zBDlID8TJIybmvKk7mhd9s+2XWxz4flA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.2.5.tgz", - "integrity": "sha512-4ZNKmuEiW5hRKkGp2HWwZ+JrvK4DQLgf8YDaqtZyn7NYdl0cHfatvlnLFSWUayx9yFAUagIgRGRk8pFxS8Qniw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.2.5.tgz", - "integrity": "sha512-bE6lHQ9GXIf3gCDE53u2pTl99RPZW5V1GLHSRMJ5l/oB/MT+cohu9uwnCK7QUph2xIOu2a6+27kL0REa/kqwZw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.2.5.tgz", - "integrity": "sha512-y7EeQuSkQbTAkCEQnJXm1asRUuGSWAchGJ3c+Qtxh8LVjXleZast8Mn/rL7tZOm7o35QeIpIcid6ufG7EVTTcA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.2.5.tgz", - "integrity": "sha512-gQMz0yA8/dskZM2Xyiq2FRShxSrsJNha40Ob/M2n2+JGRrZ0JwTVjLdvtN6vCxuq4ByhOd4a9qEf60hApNR2gQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.2.5.tgz", - "integrity": "sha512-tBDNVUcI7U03+3oMvJ11zrtVin5p0NctiuKmTGyaTIEAVj9Q77xukLXGXRnWxKRIIdFG4OTA2rUVGZDYOwgmAA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -836,7 +1116,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -846,7 +1125,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -856,85 +1134,59 @@ "node": ">= 8" } }, - "node_modules/@nolyfill/is-core-module": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", - "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", - "dev": true, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "license": "MIT", + "optional": true, "engines": { - "node": ">=12.4.0" + "node": ">=14" } }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "node_modules/@radix-ui/react-icons": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.2.tgz", + "integrity": "sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==", + "license": "MIT", + "peerDependencies": { + "react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/@remix-run/router": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz", + "integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", "dev": true, "license": "MIT" }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.11.0.tgz", - "integrity": "sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "license": "Apache-2.0" - }, - "node_modules/@swc/helpers": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", - "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.8.0" - } - }, - "node_modules/@tailwindcss/node": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.3.tgz", - "integrity": "sha512-H/6r6IPFJkCfBJZ2dKZiPJ7Ueb2wbL592+9bQEl2r73qbX6yGnmQVIfiUvDRB2YI0a3PWDrzUwkvQx1XW1bNkA==", + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.45.1.tgz", + "integrity": "sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "enhanced-resolve": "^5.18.1", - "jiti": "^2.4.2", - "lightningcss": "1.29.2", - "tailwindcss": "4.1.3" - } + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@tailwindcss/oxide": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.3.tgz", - "integrity": "sha512-t16lpHCU7LBxDe/8dCj9ntyNpXaSTAgxWm1u2XQP5NiIu4KGSyrDJJRlK9hJ4U9yJxx0UKCVI67MJWFNll5mOQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.3", - "@tailwindcss/oxide-darwin-arm64": "4.1.3", - "@tailwindcss/oxide-darwin-x64": "4.1.3", - "@tailwindcss/oxide-freebsd-x64": "4.1.3", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.3", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.3", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.3", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.3", - "@tailwindcss/oxide-linux-x64-musl": "4.1.3", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.3", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.3" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.3.tgz", - "integrity": "sha512-cxklKjtNLwFl3mDYw4XpEfBY+G8ssSg9ADL4Wm6//5woi3XGqlxFsnV5Zb6v07dxw1NvEX2uoqsxO/zWQsgR+g==", + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.45.1.tgz", + "integrity": "sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ==", "cpu": [ "arm64" ], @@ -943,15 +1195,12 @@ "optional": true, "os": [ "android" - ], - "engines": { - "node": ">= 10" - } + ] }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.3.tgz", - "integrity": "sha512-mqkf2tLR5VCrjBvuRDwzKNShRu99gCAVMkVsaEOFvv6cCjlEKXRecPu9DEnxp6STk5z+Vlbh1M5zY3nQCXMXhw==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.45.1.tgz", + "integrity": "sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA==", "cpu": [ "arm64" ], @@ -960,15 +1209,12 @@ "optional": true, "os": [ "darwin" - ], - "engines": { - "node": ">= 10" - } + ] }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.3.tgz", - "integrity": "sha512-7sGraGaWzXvCLyxrc7d+CCpUN3fYnkkcso3rCzwUmo/LteAl2ZGCDlGvDD8Y/1D3ngxT8KgDj1DSwOnNewKhmg==", + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.45.1.tgz", + "integrity": "sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og==", "cpu": [ "x64" ], @@ -977,461 +1223,26 @@ "optional": true, "os": [ "darwin" - ], - "engines": { - "node": ">= 10" - } + ] }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.3.tgz", - "integrity": "sha512-E2+PbcbzIReaAYZe997wb9rId246yDkCwAakllAWSGqe6VTg9hHle67hfH6ExjpV2LSK/siRzBUs5wVff3RW9w==", + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.45.1.tgz", + "integrity": "sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.3.tgz", - "integrity": "sha512-GvfbJ8wjSSjbLFFE3UYz4Eh8i4L6GiEYqCtA8j2Zd2oXriPuom/Ah/64pg/szWycQpzRnbDiJozoxFU2oJZyfg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.3.tgz", - "integrity": "sha512-35UkuCWQTeG9BHcBQXndDOrpsnt3Pj9NVIB4CgNiKmpG8GnCNXeMczkUpOoqcOhO6Cc/mM2W7kaQ/MTEENDDXg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.3.tgz", - "integrity": "sha512-dm18aQiML5QCj9DQo7wMbt1Z2tl3Giht54uVR87a84X8qRtuXxUqnKQkRDK5B4bCOmcZ580lF9YcoMkbDYTXHQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.3.tgz", - "integrity": "sha512-LMdTmGe/NPtGOaOfV2HuO7w07jI3cflPrVq5CXl+2O93DCewADK0uW1ORNAcfu2YxDUS035eY2W38TxrsqngxA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.3.tgz", - "integrity": "sha512-aalNWwIi54bbFEizwl1/XpmdDrOaCjRFQRgtbv9slWjmNPuJJTIKPHf5/XXDARc9CneW9FkSTqTbyvNecYAEGw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.3.tgz", - "integrity": "sha512-PEj7XR4OGTGoboTIAdXicKuWl4EQIjKHKuR+bFy9oYN7CFZo0eu74+70O4XuERX4yjqVZGAkCdglBODlgqcCXg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.3.tgz", - "integrity": "sha512-T8gfxECWDBENotpw3HR9SmNiHC9AOJdxs+woasRZ8Q/J4VHN0OMs7F+4yVNZ9EVN26Wv6mZbK0jv7eHYuLJLwA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/postcss": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.3.tgz", - "integrity": "sha512-6s5nJODm98F++QT49qn8xJKHQRamhYHfMi3X7/ltxiSQ9dyRsaFSfFkfaMsanWzf+TMYQtbk8mt5f6cCVXJwfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.1.3", - "@tailwindcss/oxide": "4.1.3", - "postcss": "^8.4.41", - "tailwindcss": "4.1.3" - } - }, - "node_modules/@tybys/wasm-util": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", - "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.1.tgz", - "integrity": "sha512-ba0rr4Wfvg23vERs3eB+P3lfj2E+2g3lhWcCVukUuhtcdUx5lSIFZlGFEBHKr+3zizDa/TvZTptdNHVZWAkSBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.29.1", - "@typescript-eslint/type-utils": "8.29.1", - "@typescript-eslint/utils": "8.29.1", - "@typescript-eslint/visitor-keys": "8.29.1", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.0.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.1.tgz", - "integrity": "sha512-zczrHVEqEaTwh12gWBIJWj8nx+ayDcCJs06yoNMY0kwjMWDM6+kppljY+BxWI06d2Ja+h4+WdufDcwMnnMEWmg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.29.1", - "@typescript-eslint/types": "8.29.1", - "@typescript-eslint/typescript-estree": "8.29.1", - "@typescript-eslint/visitor-keys": "8.29.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.1.tgz", - "integrity": "sha512-2nggXGX5F3YrsGN08pw4XpMLO1Rgtnn4AzTegC2MDesv6q3QaTU5yU7IbS1tf1IwCR0Hv/1EFygLn9ms6LIpDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.29.1", - "@typescript-eslint/visitor-keys": "8.29.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.29.1.tgz", - "integrity": "sha512-DkDUSDwZVCYN71xA4wzySqqcZsHKic53A4BLqmrWFFpOpNSoxX233lwGu/2135ymTCR04PoKiEEEvN1gFYg4Tw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "8.29.1", - "@typescript-eslint/utils": "8.29.1", - "debug": "^4.3.4", - "ts-api-utils": "^2.0.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.1.tgz", - "integrity": "sha512-VT7T1PuJF1hpYC3AGm2rCgJBjHL3nc+A/bhOp9sGMKfi5v0WufsX/sHCFBfNTx2F+zA6qBc/PD0/kLRLjdt8mQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.1.tgz", - "integrity": "sha512-l1enRoSaUkQxOQnbi0KPUtqeZkSiFlqrx9/3ns2rEDhGKfTa+88RmXqedC1zmVTOWrLc2e6DEJrTA51C9iLH5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.29.1", - "@typescript-eslint/visitor-keys": "8.29.1", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.0.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.29.1.tgz", - "integrity": "sha512-QAkFEbytSaB8wnmB+DflhUPz6CLbFWE2SnSCrRMEa+KnXIzDYbpsn++1HGvnfAsUY44doDXmvRkO5shlM/3UfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.29.1", - "@typescript-eslint/types": "8.29.1", - "@typescript-eslint/typescript-estree": "8.29.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.29.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.1.tgz", - "integrity": "sha512-RGLh5CRaUEf02viP5c1Vh1cMGffQscyHe7HPAzGpfmfflFg1wUz2rYxd+OZqwpeypYvZ8UxSxuIpF++fmOzEcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.29.1", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.4.1.tgz", - "integrity": "sha512-8Tv+Bsd0BjGwfEedIyor4inw8atppRxM5BdUnIt+3mAm/QXUm7Dw74CHnXpfZKXkp07EXJGiA8hStqCINAWhdw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" ] }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.4.1.tgz", - "integrity": "sha512-X8c3PhWziEMKAzZz+YAYWfwawi5AEgzy/hmfizAB4C70gMHLKmInJcp1270yYAOs7z07YVFI220pp50z24Jk3A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.4.1.tgz", - "integrity": "sha512-UUr/nREy1UdtxXQnmLaaTXFGOcGxPwNIzeJdb3KXai3TKtC1UgNOB9s8KOA4TaxOUBR/qVgL5BvBwmUjD5yuVA==", + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.45.1.tgz", + "integrity": "sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A==", "cpu": [ "x64" ], @@ -1442,10 +1253,10 @@ "freebsd" ] }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.4.1.tgz", - "integrity": "sha512-e3pII53dEeS8inkX6A1ad2UXE0nuoWCqik4kOxaDnls0uJUq0ntdj5d9IYd+bv5TDwf9DSge/xPOvCmRYH+Tsw==", + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.45.1.tgz", + "integrity": "sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q==", "cpu": [ "arm" ], @@ -1456,10 +1267,10 @@ "linux" ] }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.4.1.tgz", - "integrity": "sha512-e/AKKd9gR+HNmVyDEPI/PIz2t0DrA3cyonHNhHVjrkxe8pMCiYiqhtn1+h+yIpHUtUlM6Y1FNIdivFa+r7wrEQ==", + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.45.1.tgz", + "integrity": "sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q==", "cpu": [ "arm" ], @@ -1470,10 +1281,10 @@ "linux" ] }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.4.1.tgz", - "integrity": "sha512-vtIu34luF1jRktlHtiwm2mjuE8oJCsFiFr8hT5+tFQdqFKjPhbJXn83LswKsOhy0GxAEevpXDI4xxEwkjuXIPA==", + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.45.1.tgz", + "integrity": "sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw==", "cpu": [ "arm64" ], @@ -1484,10 +1295,10 @@ "linux" ] }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.4.1.tgz", - "integrity": "sha512-H3PaOuGyhFXiyJd+09uPhGl4gocmhyi1BRzvsP8Lv5AQO3p3/ZY7WjV4t2NkBksm9tMjf3YbOVHyPWi2eWsNYw==", + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.45.1.tgz", + "integrity": "sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog==", "cpu": [ "arm64" ], @@ -1498,10 +1309,24 @@ "linux" ] }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.4.1.tgz", - "integrity": "sha512-4+GmJcaaFntCi1S01YByqp8wLMjV/FyQyHVGm0vedIhL1Vfx7uHkz/sZmKsidRwokBGuxi92GFmSzqT2O8KcNA==", + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.45.1.tgz", + "integrity": "sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.45.1.tgz", + "integrity": "sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg==", "cpu": [ "ppc64" ], @@ -1512,10 +1337,38 @@ "linux" ] }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.4.1.tgz", - "integrity": "sha512-6RDQVCmtFYTlhy89D5ixTqo9bTQqFhvNN0Ey1wJs5r+01Dq15gPHRXv2jF2bQATtMrOfYwv+R2ZR9ew1N1N3YQ==", + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.45.1.tgz", + "integrity": "sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.45.1.tgz", + "integrity": "sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.45.1.tgz", + "integrity": "sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw==", "cpu": [ "s390x" ], @@ -1526,10 +1379,10 @@ "linux" ] }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.4.1.tgz", - "integrity": "sha512-XpU9uzIkD86+19NjCXxlVPISMUrVXsXo5htxtuG+uJ59p5JauSRZsIxQxzzfKzkxEjdvANPM/lS1HFoX6A6QeA==", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.45.1.tgz", + "integrity": "sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw==", "cpu": [ "x64" ], @@ -1540,10 +1393,10 @@ "linux" ] }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.4.1.tgz", - "integrity": "sha512-3CDjG/spbTKCSHl66QP2ekHSD+H34i7utuDIM5gzoNBcZ1gTO0Op09Wx5cikXnhORRf9+HyDWzm37vU1PLSM1A==", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.45.1.tgz", + "integrity": "sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw==", "cpu": [ "x64" ], @@ -1554,27 +1407,10 @@ "linux" ] }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.4.1.tgz", - "integrity": "sha512-50tYhvbCTnuzMn7vmP8IV2UKF7ITo1oihygEYq9wW2DUb/Y+QMqBHJUSCABRngATjZ4shOK6f2+s0gQX6ElENQ==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.8" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.4.1.tgz", - "integrity": "sha512-KyJiIne/AqV4IW0wyQO34wSMuJwy3VxVQOfIXIPyQ/Up6y/zi2P/WwXb78gHsLiGRUqCA9LOoCX+6dQZde0g1g==", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.45.1.tgz", + "integrity": "sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg==", "cpu": [ "arm64" ], @@ -1585,10 +1421,10 @@ "win32" ] }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.4.1.tgz", - "integrity": "sha512-y2NUD7pygrBolN2NoXUrwVqBpKPhF8DiSNE5oB5/iFO49r2DpoYqdj5HPb3F42fPBH5qNqj6Zg63+xCEzAD2hw==", + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.45.1.tgz", + "integrity": "sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw==", "cpu": [ "ia32" ], @@ -1599,10 +1435,10 @@ "win32" ] }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.4.1.tgz", - "integrity": "sha512-hVXaObGI2lGFmrtT77KSbPQ3I+zk9IU500wobjk0+oX59vg/0VqAzABNtt3YSQYgXTC2a/LYxekLfND/wlt0yQ==", + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.45.1.tgz", + "integrity": "sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA==", "cpu": [ "x64" ], @@ -1613,83 +1449,124 @@ "win32" ] }, - "node_modules/@vercel/analytics": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.5.0.tgz", - "integrity": "sha512-MYsBzfPki4gthY5HnYN7jgInhAZ7Ac1cYDoRWFomwGHWEX7odTEzbtg9kf/QSo7XEsEAqlQugA6gJ2WS2DEa3g==", - "license": "MPL-2.0", - "peerDependencies": { - "@remix-run/react": "^2", - "@sveltejs/kit": "^1 || ^2", - "next": ">= 13", - "react": "^18 || ^19 || ^19.0.0-rc", - "svelte": ">= 4", - "vue": "^3", - "vue-router": "^4" - }, - "peerDependenciesMeta": { - "@remix-run/react": { - "optional": true - }, - "@sveltejs/kit": { - "optional": true - }, - "next": { - "optional": true - }, - "react": { - "optional": true - }, - "svelte": { - "optional": true - }, - "vue": { - "optional": true - }, - "vue-router": { - "optional": true - } + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "node_modules/@vercel/speed-insights": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vercel/speed-insights/-/speed-insights-1.2.0.tgz", - "integrity": "sha512-y9GVzrUJ2xmgtQlzFP2KhVRoCglwfRQgjyfY607aU0hh0Un6d0OUyrJkjuAlsV18qR4zfoFPs/BiIj9YDS6Wzw==", - "hasInstallScript": true, - "license": "Apache-2.0", + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", + "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.23", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz", + "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", "peerDependencies": { - "@sveltejs/kit": "^1 || ^2", - "next": ">= 13", - "react": "^18 || ^19 || ^19.0.0-rc", - "svelte": ">= 4", - "vue": "^3", - "vue-router": "^4" + "@types/react": "^18.0.0" + } + }, + "node_modules/@types/stylis": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", + "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==", + "license": "MIT" + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" }, - "peerDependenciesMeta": { - "@sveltejs/kit": { - "optional": true - }, - "next": { - "optional": true - }, - "react": { - "optional": true - }, - "svelte": { - "optional": true - }, - "vue": { - "optional": true - }, - "vue-router": { - "optional": true - } + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -1726,11 +1603,22 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -1742,6 +1630,31 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1749,16 +1662,6 @@ "dev": true, "license": "Python-2.0" }, - "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/array-buffer-byte-length": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", @@ -1777,18 +1680,20 @@ } }, "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -1818,28 +1723,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", - "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-shim-unscopables": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array.prototype.flat": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", @@ -1917,11 +1800,25 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ast-types-flow": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", - "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", - "dev": true, + "node_modules/artplayer": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/artplayer/-/artplayer-5.2.3.tgz", + "integrity": "sha512-WaOZQrpZn/L+GgI2f0TEsoAL3Wb+v16Mu0JmWh7qKFYuvr11WNt3dWhWeIaCfoHy3NtkCWM9jTP+xwwsxdElZQ==", + "license": "MIT", + "dependencies": { + "option-validator": "^2.0.6" + } + }, + "node_modules/artplayer-plugin-chapter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/artplayer-plugin-chapter/-/artplayer-plugin-chapter-1.0.1.tgz", + "integrity": "sha512-opXKGN/AdUkzhJeOJu7Pp7ExjDI9HhFbzEXmjvhLfDwZY0zSd3PpcBA5ZWPxKMqA9qxdbInCkLtWbPEhi3ZSxA==", + "license": "MIT" + }, + "node_modules/artplayer-plugin-hls-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/artplayer-plugin-hls-control/-/artplayer-plugin-hls-control-1.0.1.tgz", + "integrity": "sha512-rbOeH/mzqgZuosOtxJ9NERil6siOLd9K7nsCRWARrSyT+zH3xdDo0WunYgDQiATniNySicxZ//ex/pPLxYECUg==", "license": "MIT" }, "node_modules/async-function": { @@ -1934,6 +1831,12 @@ "node": ">= 0.4" } }, + "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/autoprefixer": { "version": "10.4.21", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", @@ -1988,37 +1891,45 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/axe-core": { - "version": "4.10.3", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", - "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", - "dev": true, - "license": "MPL-2.0", - "engines": { - "node": ">=4" - } - }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" + "node_modules/axios": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" } }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -2030,7 +1941,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -2040,9 +1950,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", "dev": true, "funding": [ { @@ -2060,10 +1970,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" + "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" @@ -2072,17 +1982,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -2106,7 +2005,6 @@ "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==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -2143,10 +2041,29 @@ "node": ">=6" } }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-lite": { - "version": "1.0.30001712", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001712.tgz", - "integrity": "sha512-MBqPpGYYdQ7/hfKiet9SCI+nmN5/hp4ZzveOJubl5DTAMa5oggjAuoi0Z4onBpKPFI2ePGnQuQIzF3VxDjDJig==", + "version": "1.0.30001727", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "dev": true, "funding": [ { "type": "opencollective", @@ -2180,31 +2097,109 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/client-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", - "license": "MIT" - }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "node_modules/cheerio": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.2.tgz", + "integrity": "sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==", "license": "MIT", - "optional": true, "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.0.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.12.0", + "whatwg-mimetype": "^4.0.0" }, "engines": { - "node": ">=12.5.0" + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" } }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "devOptional": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -2217,18 +2212,27 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true, "license": "MIT" }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "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", - "optional": true, "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" } }, "node_modules/concat-map": { @@ -2238,11 +2242,17 @@ "dev": true, "license": "MIT" }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -2253,12 +2263,71 @@ "node": ">= 8" } }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true, - "license": "BSD-2-Clause" + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" }, "node_modules/data-view-buffer": { "version": "1.0.2", @@ -2315,9 +2384,9 @@ } }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2375,16 +2444,27 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "devOptional": true, - "license": "Apache-2.0", + "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": ">=8" + "node": ">=0.4.0" } }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -2398,11 +2478,65 @@ "node": ">=0.10.0" } }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "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==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -2413,10 +2547,16 @@ "node": ">= 0.4" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, "node_modules/electron-to-chromium": { - "version": "1.5.139", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.139.tgz", - "integrity": "sha512-GGnRYOTdN5LYpwbIr0rwP/ZHOQSvAF6TG0LSzp28uCBb9JiXHJGmaaKw29qjNJc5bGnnp6kXJqRnGMQoELwi5w==", + "version": "1.5.190", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.190.tgz", + "integrity": "sha512-k4McmnB2091YIsdCgkS0fMVMPOJgxl93ltFzaryXqwip1AaxeDqKCGLxkXODDA5Ab/D+tV5EL5+aTx76RvLRxw==", "dev": true, "license": "ISC" }, @@ -2424,27 +2564,37 @@ "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, "license": "MIT" }, - "node_modules/enhanced-resolve": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", - "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", - "dev": true, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", "engines": { - "node": ">=10.13.0" + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/es-abstract": { - "version": "1.23.9", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", - "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", "dev": true, "license": "MIT", "dependencies": { @@ -2452,18 +2602,18 @@ "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", - "call-bound": "^1.0.3", + "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", + "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.0", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", @@ -2475,21 +2625,24 @@ "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", + "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.0", + "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.3", + "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.3", + "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", @@ -2498,7 +2651,7 @@ "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.18" + "which-typed-array": "^1.1.19" }, "engines": { "node": ">= 0.4" @@ -2511,7 +2664,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -2521,7 +2673,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -2559,7 +2710,6 @@ "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==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -2572,7 +2722,6 @@ "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==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -2615,6 +2764,45 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -2639,20 +2827,20 @@ } }, "node_modules/eslint": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.24.0.tgz", - "integrity": "sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==", + "version": "9.31.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.31.0.tgz", + "integrity": "sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.0", - "@eslint/config-helpers": "^0.2.0", - "@eslint/core": "^0.12.0", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.0", + "@eslint/core": "^0.15.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.24.0", - "@eslint/plugin-kit": "^0.2.7", + "@eslint/js": "9.31.0", + "@eslint/plugin-kit": "^0.3.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -2663,9 +2851,9 @@ "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.3.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -2699,203 +2887,6 @@ } } }, - "node_modules/eslint-config-next": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.2.5.tgz", - "integrity": "sha512-/aUpN5FVI3FD+OB4gY0GyD2TwIOjLk8mG0B9NxVsSn8/svNmzFaIAaS80ZO1zWaIcWxrzTy2FcPVdsCK7eiceA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@next/eslint-plugin-next": "15.2.5", - "@rushstack/eslint-patch": "^1.10.3", - "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", - "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-import-resolver-typescript": "^3.5.2", - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-jsx-a11y": "^6.10.0", - "eslint-plugin-react": "^7.37.0", - "eslint-plugin-react-hooks": "^5.0.0" - }, - "peerDependencies": { - "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", - "typescript": ">=3.3.1" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.0.tgz", - "integrity": "sha512-aV3/dVsT0/H9BtpNwbaqvl+0xGMRGzncLyhm793NFGvbwGGvzyAykqWZ8oZlZuGwuHkwJjhWJkG1cM3ynvd2pQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@nolyfill/is-core-module": "1.0.39", - "debug": "^4.4.0", - "get-tsconfig": "^4.10.0", - "is-bun-module": "^2.0.0", - "stable-hash": "^0.0.5", - "tinyglobby": "^0.2.12", - "unrs-resolver": "^1.3.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-import-resolver-typescript" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*", - "eslint-plugin-import-x": "*" - }, - "peerDependenciesMeta": { - "eslint-plugin-import": { - "optional": true - }, - "eslint-plugin-import-x": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", - "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", - "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.0", - "hasown": "^2.0.2", - "is-core-module": "^2.15.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "object.groupby": "^1.0.3", - "object.values": "^1.2.0", - "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.8", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", - "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "aria-query": "^5.3.2", - "array-includes": "^3.1.8", - "array.prototype.flatmap": "^1.3.2", - "ast-types-flow": "^0.0.8", - "axe-core": "^4.10.0", - "axobject-query": "^4.1.0", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "hasown": "^2.0.2", - "jsx-ast-utils": "^3.3.5", - "language-tags": "^1.0.9", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "safe-regex-test": "^1.0.3", - "string.prototype.includes": "^2.0.1" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" - } - }, "node_modules/eslint-plugin-react": { "version": "7.37.5", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", @@ -2942,38 +2933,20 @@ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.20", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.20.tgz", + "integrity": "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA==", "dev": true, "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/eslint-plugin-react/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "peerDependencies": { + "eslint": ">=8.40" } }, "node_modules/eslint-scope": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", - "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -2988,9 +2961,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3001,15 +2974,15 @@ } }, "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.14.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3072,17 +3045,16 @@ "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dev": true, + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -3092,7 +3064,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -3119,27 +3090,11 @@ "version": "1.19.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, - "node_modules/fdir": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", - "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -3157,7 +3112,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -3204,6 +3158,26 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -3220,6 +3194,38 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -3234,11 +3240,24 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3275,11 +3294,20 @@ "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", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "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==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -3304,7 +3332,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -3332,24 +3359,30 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-tsconfig": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", - "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==", - "dev": true, - "license": "MIT", + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", "dependencies": { - "resolve-pkg-maps": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -3358,10 +3391,34 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", "dev": true, "license": "MIT", "engines": { @@ -3392,7 +3449,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3401,20 +3457,6 @@ "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==", - "dev": true, - "license": "ISC" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -3471,7 +3513,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -3484,7 +3525,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -3500,7 +3540,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -3510,11 +3549,54 @@ } }, "node_modules/hls.js": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.1.tgz", - "integrity": "sha512-7GOkcqn0Y9EqU2OJZlzkwxj9Uynuln7URvr7dRjgqNJNZ5UbbjL/v1BjAvQogy57Psdd/ek1u2s6IDEFYlabrA==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.7.tgz", + "integrity": "sha512-QW2fnwDGKGc9DwQUGLbmMOz8G48UZK7PVNJPcOUql1b8jubKx4/eMHNP5mGqr6tYlJNDG1g10Lx2U/qPzL6zwQ==", "license": "Apache-2.0" }, + "node_modules/htmlparser2": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", + "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.1", + "entities": "^6.0.0" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -3585,13 +3667,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "license": "MIT", - "optional": true - }, "node_modules/is-async-function": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", @@ -3628,6 +3703,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", @@ -3645,16 +3732,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-bun-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", - "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.7.1" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -3672,7 +3749,6 @@ "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -3723,7 +3799,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3745,6 +3820,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-generator-function": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", @@ -3768,7 +3852,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -3790,11 +3873,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -3973,7 +4068,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, "license": "ISC" }, "node_modules/iterator.prototype": { @@ -3994,21 +4088,34 @@ "node": ">= 0.4" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "dev": true, + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "license": "MIT", "bin": { - "jiti": "lib/jiti-cli.mjs" + "jiti": "bin/jiti.js" } }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, "license": "MIT" }, "node_modules/js-yaml": { @@ -4024,6 +4131,19 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -4046,16 +4166,16 @@ "license": "MIT" }, "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, "bin": { "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, "node_modules/jsx-ast-utils": { @@ -4084,24 +4204,13 @@ "json-buffer": "3.0.1" } }, - "node_modules/language-subtag-registry": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", - "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/language-tags": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", - "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", - "dev": true, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "license": "MIT", - "dependencies": { - "language-subtag-registry": "^0.3.20" - }, "engines": { - "node": ">=0.10" + "node": ">=0.10.0" } }, "node_modules/levn": { @@ -4118,244 +4227,23 @@ "node": ">= 0.8.0" } }, - "node_modules/lightningcss": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.2.tgz", - "integrity": "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", "engines": { - "node": ">= 12.0.0" + "node": ">=14" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.29.2", - "lightningcss-darwin-x64": "1.29.2", - "lightningcss-freebsd-x64": "1.29.2", - "lightningcss-linux-arm-gnueabihf": "1.29.2", - "lightningcss-linux-arm64-gnu": "1.29.2", - "lightningcss-linux-arm64-musl": "1.29.2", - "lightningcss-linux-x64-gnu": "1.29.2", - "lightningcss-linux-x64-musl": "1.29.2", - "lightningcss-win32-arm64-msvc": "1.29.2", - "lightningcss-win32-x64-msvc": "1.29.2" + "url": "https://github.com/sponsors/antonk52" } }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz", - "integrity": "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz", - "integrity": "sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz", - "integrity": "sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz", - "integrity": "sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz", - "integrity": "sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz", - "integrity": "sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz", - "integrity": "sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz", - "integrity": "sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz", - "integrity": "sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.2.tgz", - "integrity": "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" }, "node_modules/locate-path": { "version": "6.0.0", @@ -4384,7 +4272,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -4393,11 +4280,29 @@ "loose-envify": "cli.js" } }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lucide-react": { + "version": "0.447.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.447.0.tgz", + "integrity": "sha512-SZ//hQmvi+kDKrNepArVkYK7/jfeZ5uFNEnYmd45RKZcbGD78KLnrcNXmgeg6m+xNHFvTG+CblszXCy4n6DN4w==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" + } + }, "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==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4407,7 +4312,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -4417,7 +4321,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -4427,6 +4330,27 @@ "node": ">=8.6" } }, + "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/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4440,14 +4364,13 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" } }, "node_modules/ms": { @@ -4457,6 +4380,17 @@ "dev": true, "license": "MIT" }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -4482,88 +4416,6 @@ "dev": true, "license": "MIT" }, - "node_modules/next": { - "version": "15.2.5", - "resolved": "https://registry.npmjs.org/next/-/next-15.2.5.tgz", - "integrity": "sha512-LlqS8ljc7RWR3riUwxB5+14v7ULAa5EuLUyarD/sFgXPd6Hmmscg8DXcu9hDdh5atybrIDVBrFhjDpRIQo/4pQ==", - "license": "MIT", - "dependencies": { - "@next/env": "15.2.5", - "@swc/counter": "0.1.3", - "@swc/helpers": "0.5.15", - "busboy": "1.6.0", - "caniuse-lite": "^1.0.30001579", - "postcss": "8.4.31", - "styled-jsx": "5.1.6" - }, - "bin": { - "next": "dist/bin/next" - }, - "engines": { - "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" - }, - "optionalDependencies": { - "@next/swc-darwin-arm64": "15.2.5", - "@next/swc-darwin-x64": "15.2.5", - "@next/swc-linux-arm64-gnu": "15.2.5", - "@next/swc-linux-arm64-musl": "15.2.5", - "@next/swc-linux-x64-gnu": "15.2.5", - "@next/swc-linux-x64-musl": "15.2.5", - "@next/swc-win32-arm64-msvc": "15.2.5", - "@next/swc-win32-x64-msvc": "15.2.5", - "sharp": "^0.33.5" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.1.0", - "@playwright/test": "^1.41.2", - "babel-plugin-react-compiler": "*", - "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", - "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", - "sass": "^1.3.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - }, - "@playwright/test": { - "optional": true - }, - "babel-plugin-react-compiler": { - "optional": true - }, - "sass": { - "optional": true - } - } - }, - "node_modules/next/node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", @@ -4571,6 +4423,15 @@ "dev": true, "license": "MIT" }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", @@ -4581,16 +4442,36 @@ "node": ">=0.10.0" } }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -4670,21 +4551,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/object.values": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", @@ -4704,6 +4570,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/option-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/option-validator/-/option-validator-2.0.6.tgz", + "integrity": "sha512-tmZDan2LRIRQyhUGvkff68/O0R8UmF+Btmiiz0SmSw2ng3CfPZB9wJlIjHpe/MKUZqyIZkVIXCrwr1tIN+0Dzg==", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.3" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -4772,6 +4647,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -4785,6 +4666,55 @@ "node": ">=6" } }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4799,7 +4729,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4809,9 +4738,30 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, "license": "MIT" }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -4822,7 +4772,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -4831,6 +4780,24 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -4842,10 +4809,9 @@ } }, "node_modules/postcss": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", - "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", - "dev": true, + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "funding": [ { "type": "opencollective", @@ -4862,7 +4828,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.8", + "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -4870,11 +4836,139 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-import/node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, "license": "MIT" }, "node_modules/prelude-ls": { @@ -4891,7 +4985,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -4919,7 +5012,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -4937,33 +5029,130 @@ "license": "MIT" }, "node_modules/react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, "engines": { "node": ">=0.10.0" } }, - "node_modules/react-dom": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "node_modules/react-content-loader": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/react-content-loader/-/react-content-loader-7.1.1.tgz", + "integrity": "sha512-yNkqtd+15wXRLfDKZb5nTqDV2fPTG2kpUgeGRb+WBz43bU0j4DSGXETF0bnFr44fAoTPpm0Dya0WGdhpHSvtYA==", "license": "MIT", - "dependencies": { - "scheduler": "^0.26.0" + "engines": { + "node": ">=10" }, "peerDependencies": { - "react": "^19.1.0" + "react": ">=16.0.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" } }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, "license": "MIT" }, + "node_modules/react-lazy-load": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/react-lazy-load/-/react-lazy-load-4.0.1.tgz", + "integrity": "sha512-TnXRr79X9rlC9UcmO6iyS28rOPHrgkHIP4+b8yZPfs1tw6k/Rp2DmFY8R20BqWR45ZWkpT+4dqV1f+yci+1ozg==", + "license": "MIT", + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz", + "integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz", + "integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.0", + "react-router": "6.30.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -5009,22 +5198,19 @@ } }, "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.16.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, - "engines": { - "node": ">= 0.4" - }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5039,32 +5225,60 @@ "node": ">=4" } }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, + "node_modules/rollup": { + "version": "4.45.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.45.1.tgz", + "integrity": "sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.45.1", + "@rollup/rollup-android-arm64": "4.45.1", + "@rollup/rollup-darwin-arm64": "4.45.1", + "@rollup/rollup-darwin-x64": "4.45.1", + "@rollup/rollup-freebsd-arm64": "4.45.1", + "@rollup/rollup-freebsd-x64": "4.45.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.45.1", + "@rollup/rollup-linux-arm-musleabihf": "4.45.1", + "@rollup/rollup-linux-arm64-gnu": "4.45.1", + "@rollup/rollup-linux-arm64-musl": "4.45.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.45.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.45.1", + "@rollup/rollup-linux-riscv64-gnu": "4.45.1", + "@rollup/rollup-linux-riscv64-musl": "4.45.1", + "@rollup/rollup-linux-s390x-gnu": "4.45.1", + "@rollup/rollup-linux-x64-gnu": "4.45.1", + "@rollup/rollup-linux-x64-musl": "4.45.1", + "@rollup/rollup-win32-arm64-msvc": "4.45.1", + "@rollup/rollup-win32-ia32-msvc": "4.45.1", + "@rollup/rollup-win32-x64-msvc": "4.45.1", + "fsevents": "~2.3.2" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -5139,23 +5353,29 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, "node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "devOptional": true, + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" } }, "node_modules/set-function-length": { @@ -5207,51 +5427,16 @@ "node": ">= 0.4" } }, - "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", - "optional": true, - "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/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -5264,7 +5449,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5346,14 +5530,16 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "license": "MIT", - "optional": true, - "dependencies": { - "is-arrayish": "^0.3.1" + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/source-map-js": { @@ -5365,36 +5551,79 @@ "node": ">=0.10.0" } }, - "node_modules/stable-hash": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", - "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", - "dev": true, - "license": "MIT" - }, - "node_modules/streamsearch": { + "node_modules/stop-iteration-iterator": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/string.prototype.includes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", - "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.3" + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" }, "engines": { "node": ">= 0.4" } }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string.prototype.matchall": { "version": "4.0.12", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", @@ -5493,14 +5722,41 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-json-comments": { @@ -5516,27 +5772,88 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/styled-jsx": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", - "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "node_modules/styled-components": { + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.19.tgz", + "integrity": "sha512-1v/e3Dl1BknC37cXMhwGomhO8AkYmN41CqyX9xhUDxry1ns3BFQy2lLDRQXJRdVVWB9OHemv/53xaStimvWyuA==", "license": "MIT", "dependencies": { - "client-only": "0.0.1" + "@emotion/is-prop-valid": "1.2.2", + "@emotion/unitless": "0.8.1", + "@types/stylis": "4.2.5", + "css-to-react-native": "3.2.0", + "csstype": "3.1.3", + "postcss": "8.4.49", + "shallowequal": "1.1.0", + "stylis": "4.3.2", + "tslib": "2.6.2" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" }, "peerDependencies": { - "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" }, - "babel-plugin-macros": { - "optional": true + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "license": "MIT" + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" } }, "node_modules/supports-color": { @@ -5556,7 +5873,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -5566,9 +5882,9 @@ } }, "node_modules/swiper": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.6.tgz", - "integrity": "sha512-8aXpYKtjy3DjcbzZfz+/OX/GhcU5h+looA6PbAzHMZT6ESSycSp9nAjPCenczgJyslV+rUGse64LMGpWE3PX9Q==", + "version": "11.2.10", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.10.tgz", + "integrity": "sha512-RMeVUUjTQH+6N3ckimK93oxz6Sn5la4aDlgPzB+rBrG/smPdCTicXyhxa+woIpopz+jewEloiEE3lKo1h9w2YQ==", "funding": [ { "type": "patreon", @@ -5584,58 +5900,107 @@ "node": ">= 4.7.0" } }, - "node_modules/tailwindcss": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.3.tgz", - "integrity": "sha512-2Q+rw9vy1WFXu5cIxlvsabCwhU2qUwodGq03ODhLJ0jW4ek5BUtoCsnLB0qG+m8AHgEsSJcJGDSDe06FXlP74g==", - "dev": true, - "license": "MIT" - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, + "node_modules/tailwind-merge": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", + "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==", "license": "MIT", - "engines": { - "node": ">=6" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" } }, - "node_modules/tinyglobby": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz", - "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", - "dev": true, + "node_modules/tailwindcss": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", "license": "MIT", "dependencies": { - "fdir": "^6.4.3", - "picomatch": "^4.0.2" + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" }, "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" + "node": ">=14.0.0" } }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, + "node_modules/tailwindcss-animate": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", + "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", "license": "MIT", + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, + "node_modules/tailwindcss/node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" } }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -5644,36 +6009,16 @@ "node": ">=8.0" } }, - "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "license": "Apache-2.0" }, "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "license": "0BSD" }, "node_modules/type-check": { @@ -5786,31 +6131,13 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/unrs-resolver": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.4.1.tgz", - "integrity": "sha512-MhPB3wBI5BR8TGieTb08XuYlE8oFVEXdSAgat3psdlRyejl8ojQ8iqPcjh094qCZ1r+TnkxzP6BeCd/umfHckQ==", - "dev": true, + "node_modules/undici": { + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.12.0.tgz", + "integrity": "sha512-GrKEsc3ughskmGA9jevVlIOPMiiAHJ4OFUtaAH+NhfTUSiZ1wMPIQqQvAJUrJspFXJt3EBWgpAeoHEDVT1IBug==", "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/JounQin" - }, - "optionalDependencies": { - "@unrs/resolver-binding-darwin-arm64": "1.4.1", - "@unrs/resolver-binding-darwin-x64": "1.4.1", - "@unrs/resolver-binding-freebsd-x64": "1.4.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.4.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.4.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.4.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.4.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.4.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.4.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.4.1", - "@unrs/resolver-binding-linux-x64-musl": "1.4.1", - "@unrs/resolver-binding-wasm32-wasi": "1.4.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.4.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.4.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.4.1" + "engines": { + "node": ">=20.18.1" } }, "node_modules/update-browserslist-db": { @@ -5854,11 +6181,97 @@ "punycode": "^2.1.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/vite": { + "version": "5.4.19", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", + "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -5969,6 +6382,113 @@ "node": ">=0.10.0" } }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 48b5f2e..0abc694 100644 --- a/package.json +++ b/package.json @@ -1,31 +1,54 @@ { "name": "justanime", - "version": "0.1.0", "private": true, + "version": "0.0.0", + "type": "module", "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "lint": "next lint" + "dev": "vite", + "build": "vite build", + "lint": "eslint .", + "preview": "vite preview", + "host": "vite --host" }, "dependencies": { - "@heroicons/react": "^2.2.0", - "@vercel/analytics": "^1.5.0", - "@vercel/speed-insights": "^1.2.0", - "hls.js": "^1.5.7", - "next": "latest", - "proxy-from-env": "^1.1.0", - "react": "latest", - "react-dom": "latest", - "swiper": "^11.2.6" + "@fortawesome/fontawesome-svg-core": "^6.6.0", + "@fortawesome/free-brands-svg-icons": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.6.0", + "@fortawesome/react-fontawesome": "^0.2.2", + "@radix-ui/react-icons": "^1.3.0", + "artplayer": "^5.2.3", + "artplayer-plugin-chapter": "^1.0.0", + "artplayer-plugin-hls-control": "^1.0.1", + "axios": "^1.7.7", + "cheerio": "^1.0.0", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "hls.js": "^1.5.17", + "lucide-react": "^0.447.0", + "react": "^18.3.1", + "react-content-loader": "^7.0.2", + "react-dom": "^18.3.1", + "react-icons": "^5.3.0", + "react-lazy-load": "^4.0.1", + "react-router-dom": "^6.26.2", + "styled-components": "^6.1.13", + "swiper": "^11.2.5", + "tailwind-merge": "^2.5.3", + "tailwindcss-animate": "^1.0.7" }, "devDependencies": { - "@eslint/eslintrc": "^3", - "@tailwindcss/postcss": "^4", - "autoprefixer": "latest", - "eslint": "^9", - "eslint-config-next": "15.2.5", - "postcss": "latest", - "tailwindcss": "^4" + "@eslint/js": "^9.9.0", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "autoprefixer": "^10.4.20", + "eslint": "^9.9.0", + "eslint-plugin-react": "^7.35.0", + "eslint-plugin-react-hooks": "^5.1.0-rc.0", + "eslint-plugin-react-refresh": "^0.4.9", + "globals": "^15.9.0", + "postcss": "^8.4.47", + "tailwindcss": "^3.4.13", + "vite": "^5.4.1" } } diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..2e7af2b --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/postcss.config.mjs b/postcss.config.mjs deleted file mode 100644 index c7bcb4b..0000000 --- a/postcss.config.mjs +++ /dev/null @@ -1,5 +0,0 @@ -const config = { - plugins: ["@tailwindcss/postcss"], -}; - -export default config; diff --git a/public/images/placeholder.png b/public/images/placeholder.png deleted file mode 100644 index 490b3f60003e09656c96c9e16365bcfcbed955fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40 rcmezWPoF`HL4l!wA%`K6A( + + + https://zenime.site/ + 2024-11-08T15:50:46+00:00 + 1.00 + + + https://zenime.site/top-upcoming + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/movie + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/tv + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/most-popular + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/top-airing + 2024-11-08T15:50:46+00:00 + 0.80 + + + + https://zenime.site/search?keyword=Dandadan + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/search?keyword=Blue%20Box + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/search?keyword=Haikyu!!%20Movie%3A%20Battle%20of%20the%20Garbage%20Dump + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/search?keyword=One%20Piece + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/search?keyword=Dragon%20Ball%20Daima + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/search?keyword=Solo%20Leveling + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/search?keyword=Re%3AZERO%20-Starting%20Life%20in%20Another%20World-%20Season%203 + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/search?keyword=Attack%20on%20Titan + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/search?keyword=Bleach%3A%20Thousand-Year%20Blood%20War%20-%20The%20Conflict + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/search?keyword=My%20Hero%20Academia%20Season%207 + 2024-11-08T15:50:46+00:00 + 0.80 + + + https://zenime.site/basilisk-1307 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/subbed-anime + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/dubbed-anime + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/ova + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/ona + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/special + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/app-download + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/action + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/adventure + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/cars + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/comedy + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/dementia + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/demons + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/drama + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/ecchi + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/fantasy + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/game + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/harem + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/historical + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/horror + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/isekai + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/josei + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/kids + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/magic + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/marial-arts + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/mecha + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/military + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/music + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/mystery + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/parody + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/police + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/psychological + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/romance + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/samurai + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/school + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/sci-fi + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/seinen + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/shoujo + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/shoujo-ai + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/shounen + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/shounen-ai + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/slice-of-life + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/space + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/sports + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/super-power + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/supernatural + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/thriller + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genre/vampire + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/filter + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/ranma-1-2-19335 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/ranma-1-2-19335 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/the-elusive-samurai-19233 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/the-elusive-samurai-19233 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/no-longer-allowed-in-another-world-19247 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/no-longer-allowed-in-another-world-19247 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/why-does-nobody-remember-me-in-this-world-19240 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/why-does-nobody-remember-me-in-this-world-19240 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/one-piece-100 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/one-piece-100 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/the-strongest-magician-in-the-demon-lords-army-was-a-human-19238 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/the-strongest-magician-in-the-demon-lords-army-was-a-human-19238 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/pseudo-harem-19246 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/pseudo-harem-19246 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/demon-slayer-kimetsu-no-yaiba-hashira-training-arc-19107 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/demon-slayer-kimetsu-no-yaiba-hashira-training-arc-19107 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/wind-breaker-19136 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/wind-breaker-19136 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/bleach-806 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/bleach-806 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/dandadan-19319 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-lock-season-2-19318 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-box-19326 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/bleach-thousand-year-blood-war-the-conflict-19322 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/rurouni-kenshin-kyoto-disturbance-19340 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/rezero-starting-life-in-another-world-season-3-19301 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/my-star-season-2-19256 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/good-bye-dragon-life-19347 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/case-closed-323 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/naruto-shippuden-355 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/jujutsu-kaisen-2nd-season-18413 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/black-clover-2404 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/chainsaw-man-17406 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/jujutsu-kaisen-tv-534 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/demon-slayer-kimetsu-no-yaiba-swordsmith-village-arc-18056 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/most-favorite + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/look-back-19083 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/i-parry-everything-19229 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/high-card-the-flowers-bloom-19410 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/jellyfish-cant-swim-in-the-night-19124 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/level-1-demon-lord-and-one-room-hero-18465 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/completed + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/recently-updated + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/hamidashi-creative-19368?w=latest + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/hamidashi-creative-19368 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/25-dimensional-seduction-19245?w=latest + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/25-dimensional-seduction-19245 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/another-journey-to-the-west-19402?w=latest + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/another-journey-to-the-west-19402 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/rurouni-kenshin-kyoto-disturbance-19340?w=latest + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/trillion-game-19362?w=latest + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/trillion-game-19362 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/good-bye-dragon-life-19347?w=latest + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/365-days-to-the-wedding-19332?w=latest + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/365-days-to-the-wedding-19332 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/mechanical-arms-19354?w=latest + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/mechanical-arms-19354 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/look-back-19083?w=latest + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/dandadan-19319?w=latest + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/loner-life-in-another-world-19337?w=latest + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/loner-life-in-another-world-19337 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/kinoko-inu-19373?w=latest + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/kinoko-inu-19373 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/recently-added + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/look-back-19083 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/i-parry-everything-19229 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/high-card-the-flowers-bloom-19410 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/jellyfish-cant-swim-in-the-night-19124 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/level-1-demon-lord-and-one-room-hero-18465 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/future-folktales-8383 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/future-folktales-8383 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/mission-yozakura-family-19133 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/mission-yozakura-family-19133 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/da-shen-xian-17405 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/da-shen-xian-17405 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/da-shen-xian-17526 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/da-shen-xian-17526 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/crayon-shin-chan-movie-31-chounouryoku-daikessen-tobe-tobe-temakizushi-18427 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/crayon-shin-chan-movie-31-chounouryoku-daikessen-tobe-tobe-temakizushi-18427 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/crayon-shin-chan-movie-30-mononoke-ninja-chinpuuden-19408 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/crayon-shin-chan-movie-30-mononoke-ninja-chinpuuden-19408 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/cardfight-vanguard-divinez-season-2-19206 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/cardfight-vanguard-divinez-season-2-19206 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/rakshasa-street-4th-season-19411 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/murder-mystery-of-the-dead-19405 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/kagaku-x-bouken-survival-19376 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/genjitsu-no-yohane-sunshine-in-the-mirror-movie-19394 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/give-it-all-19393 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/solo-leveling-reawakening-19392 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/attack-on-titan-the-last-attack-19391 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/gintama-on-theater-2d-kintama-hen-19389 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/beastars-final-season-19385 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/pinkfong-gwa-hogi-sae-chingu-ninimo-19384 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/pochaazu-19383 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/kumarba-season-2-19382 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/is-it-wrong-to-try-to-pick-up-girls-in-a-dungeon-v-19323 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/haikyu-movie-battle-of-the-garbage-dump-18922 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/my-hero-academia-season-7-19146 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/dragon-ball-daima-19328 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/other + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/0-9 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/A + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/B + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/C + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/D + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/E + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/F + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/G + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/H + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/I + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/J + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/K + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/L + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/M + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/N + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/O + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/P + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/Q + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/R + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/S + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/T + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/U + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/V + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/W + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/X + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/Y + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/az-list/Z + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/spy-x-family-code-white-19291 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/be-forever-yamato-rebel-3199-19192 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/idolish7-movie-live-4bit-beyond-the-period-19176 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-lock-episode-nagi-19085 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/my-oni-girl-19076 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/kuramerukagari-19075 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/rascal-does-not-dream-of-a-sister-venturing-out-18934 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/dead-dead-demons-dededede-destruction-18925 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/oomuro-ke-dear-sisters-18916 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/ya-boy-kongming-road-to-summer-sonia-18913 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/mobile-suit-gundam-seed-freedom-18910 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/psycho-pass-movie-providence-18715 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/white-snake-2-the-tribulation-of-the-green-snake-18682 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/detective-conan-movie-26-black-iron-submarine-18655 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/my-hero-academia-ua-heroes-battle-18629 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/digimon-adventure-02-movie-18562 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/the-imaginary-18561 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/i-am-what-i-am-18555 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/the-summer-18553 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/boonie-bears-back-to-earth-18549 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/boonie-bears-the-wild-life-18548 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/free-movie-5-the-final-stroke-kouhen-18504 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/maboroshi-18434 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/sound-euphonium-ensemble-contest-arc-18433 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/kaina-of-the-great-snow-sea-star-sage-18432 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/resident-evil-death-island-18429 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/detective-conan-movie-the-story-of-haibara-ai-black-iron-mystery-train-18412 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/tsurune-movie-hajimari-no-issha-18411 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/backflip-the-movie-18405 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/mobile-suit-gundam-cucuruz-doans-island-18400 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/movie?page=2 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/movie?page=3 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/movie?page=32 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/one-piece-log-fish-man-island-saga-19404 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/tower-of-god-season-2-workshop-battle-19400 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/punirunes-2-19381 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/okaimono-panda-19379 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/asatir-2-mirai-no-mukashi-banashi-19378 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/neko-ni-tensei-shita-ojisan-19375 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/hyakushou-kizoku-2nd-season-19374 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/puniru-is-a-kawaii-slime-19372 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/tonbo-season-2-19370 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/the-idolm-at-ster-shiny-colors-2nd-season-19369 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/a-herbivorous-dragon-of-5000-years-gets-unfairly-villainized-2nd-season-19367 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/a-story-of-a-girl-that-was-unable-to-become-a-mage-19366 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/the-prince-of-tennis-u-17-world-cup-semifinal-19365 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/kamierabi-godapp-season-2-19364 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/negative-positive-angler-19363 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/haigakura-19361 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/acro-trip-19360 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/a-terrified-teacher-at-ghoul-school-19359 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/touhai-ura-rate-mahjong-touhai-roku-19358 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/magilumiere-co-ltd-19357 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/let-this-grieving-soul-retire-19356 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/how-i-attended-an-all-guys-mixer-19355 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/the-most-notorious-talker-runs-the-worlds-greatest-clan-19353 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/love-live-superstar-3rd-season-19352 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/about-the-movement-of-the-earth-19351 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-wolves-of-mibu-19350 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/demon-lord-retry-r-19349 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/nina-the-starry-bride-19348 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/after-school-hanako-kun-part-2-19346 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/tv?page=2 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/tv?page=3 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/tv?page=113 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/boruto-naruto-next-generations-8143 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/naruto-677 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/spy-x-family-17977 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/solo-leveling-18718 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/hunter-x-hunter-2 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-lock-17889 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/demon-slayer-entertainment-district-arc-17483 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/demon-slayer-kimetsu-no-yaiba-47 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/attack-on-titan-112 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/my-hero-academia-season-6-18154 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/hells-paradise-18332 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/dragon-ball-z-325 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/the-eminence-in-shadow-17473 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/dragon-ball-super-1692 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/attack-on-titan-final-season-part-2-17753 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/death-note-60 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/mashle-magic-and-muscles-18339 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/attack-on-titan-season-3-85 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/i-got-a-cheat-skill-in-another-world-and-became-unrivaled-in-the-real-world-too-18343 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/dragon-ball-509 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/attack-on-titan-final-season-part-1-15548 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/classroom-of-the-elite-2nd-season-18076 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/fairy-tail-930 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/my-hero-academia-5th-season-15666 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/bleach-thousandyear-blood-war-the-separation-18420 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/my-star-18330 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/vinland-saga-2nd-season-18239 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/that-time-i-got-reincarnated-as-a-slime-season-3-19109 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/jujutsu-kaisen-0-movie-17763 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/most-popular?page=2 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/most-popular?page=3 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/most-popular?page=50 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/fairy-tail-100-years-quest-19253 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/super-dragon-ball-heroes-9688 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/pokemon-horizons-the-series-18397 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/seirei-gensouki-spirit-chronicles-season-2-19320 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/the-healer-who-was-banished-from-his-party-is-in-fact-the-strongest-19345 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/shangri-la-frontier-season-2-19324 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/as-a-reincarnated-aristocrat-ill-use-my-appraisal-skill-to-rise-in-the-world-season-2-19329 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/arifureta-from-commonplace-to-worlds-strongest-season-3-19321 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/super-dragon-ball-heroes-big-bang-mission-17970 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/yakuza-fiance-19336 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/battle-through-the-heavens-5th-season-18119 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/ill-become-a-villainess-who-goes-down-in-history-19334 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/demon-lord-2099-19339 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/you-are-ms-servant-19331 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/shin-chan-1058 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/the-do-over-damsel-conquers-the-dragon-emperor-19341 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/tying-the-knot-with-an-amagami-sister-19338 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/beyblade-x-18632 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/soul-land-2-peerless-tang-sect-18416 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/swallowed-star-2nd-season-18018 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/top-airing?page=2 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/top-airing?page=3 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/top-airing?page=10 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/dandadan-19319 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/dandadan-19319 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-giant-18260 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-giant-18260 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-gender-3372 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-gender-3372 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-reflection-17485 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-reflection-17485 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-box-19326 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-box-19326 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-period-17427 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-period-17427 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-lock-17889 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-lock-17889 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-dragon-6179 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-dragon-6179 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-seed-3431 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-seed-3431 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/grand-blue-dreaming-139 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/grand-blue-dreaming-139 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/perfect-blue-127 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/perfect-blue-127 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-literature-893 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-literature-893 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-wolves-of-mibu-19350 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-wolves-of-mibu-19350 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-seed-beyond-6048 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-seed-beyond-6048 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/the-blue-orchestra-18359 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/the-blue-orchestra-18359 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/bb-fish-10438 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/bb-fish-10438 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/sweet-blue-flowers-2862 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/sweet-blue-flowers-2862 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/armed-blue-gunvolt-8786 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/armed-blue-gunvolt-8786 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-seed-omake-4193 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-seed-omake-4193 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-exorcist-1198 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-exorcist-1198 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-drop-4694 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-drop-4694 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-blink-4540 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-blink-4540 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/sky-blue-3412 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/sky-blue-3412 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/ginga-no-uo-ursa-minor-blue-7064 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/ginga-no-uo-ursa-minor-blue-7064 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-dragon-the-seven-dragons-of-the-heavens-5453 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-dragon-the-seven-dragons-of-the-heavens-5453 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-lock-season-2-19318 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-lock-season-2-19318 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/aoki-honoo-10273 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/aoki-honoo-10273 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/801-tts-airbats-5741 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/801-tts-airbats-5741 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/ao-no-exorcist-kyoto-fujouou-hen-ova-2896 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/ao-no-exorcist-kyoto-fujouou-hen-ova-2896 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-archive-the-animation-19125 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-archive-the-animation-19125 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-lock-episode-nagi-19085 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-lock-episode-nagi-19085 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/world-war-blue-8602 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/world-war-blue-8602 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/her-blue-sky-1418 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/her-blue-sky-1418 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-legend-shoot-1822 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-legend-shoot-1822 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-legend-shoot-4518 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-legend-shoot-4518 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/combat-mecha-xabungle-2768 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/combat-mecha-xabungle-2768 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blue-exorcist-kyoto-saga-1628 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blue-exorcist-kyoto-saga-1628 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/search?keyword=Blue%20Box&page=2 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/search?keyword=Blue%20Box&page=3 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/haikyu-movie-battle-of-the-garbage-dump-18922 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/haikyu-movie-battle-of-the-garbage-dump-18922 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/knights-of-the-zodiac-saint-seiya-battle-for-sanctuary-18135 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/knights-of-the-zodiac-saint-seiya-battle-for-sanctuary-18135 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/persona-3-the-movie-1-spring-of-birth-1244 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/persona-3-the-movie-1-spring-of-birth-1244 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/persona-3-the-movie-4-winter-of-rebirth-500 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/persona-3-the-movie-4-winter-of-rebirth-500 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/haikyu-76 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/haikyu-76 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/ex-driver-the-movie-5019 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/ex-driver-the-movie-5019 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/dirty-pair-project-eden-3340 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/dirty-pair-project-eden-3340 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/the-last-naruto-the-movie-882 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/the-last-naruto-the-movie-882 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/boruto-naruto-the-movie-1391 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/boruto-naruto-the-movie-1391 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/love-live-the-school-idol-movie-572 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/love-live-the-school-idol-movie-572 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/banner-of-the-stars-945 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/banner-of-the-stars-945 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/recycle-of-the-penguindrum-17796 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/recycle-of-the-penguindrum-17796 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/haikyu-2nd-season-29 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/haikyu-2nd-season-29 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/haikyu-3rd-season-18 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/haikyu-3rd-season-18 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/my-hero-academia-the-movie-3-world-heroes-mission-17334 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/my-hero-academia-the-movie-3-world-heroes-mission-17334 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/naruto-shippuuden-movie-6-road-to-ninja-1066 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/naruto-shippuuden-movie-6-road-to-ninja-1066 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/persona-3-the-movie-3-falling-down-1230 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/persona-3-the-movie-3-falling-down-1230 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/love-live-sunshine-the-school-idol-movie-over-the-rainbow-1211 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/love-live-sunshine-the-school-idol-movie-over-the-rainbow-1211 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/banner-of-the-stars-ii-753 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/banner-of-the-stars-ii-753 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/black-butler-book-of-the-atlantic-224 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/black-butler-book-of-the-atlantic-224 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/magi-the-labyrinth-of-magic-425 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/magi-the-labyrinth-of-magic-425 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/magi-the-kingdom-of-magic-208 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/magi-the-kingdom-of-magic-208 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/patlabor-the-movie-1464 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/patlabor-the-movie-1464 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/persona-3-the-movie-2-midsummer-knights-dream-1088 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/persona-3-the-movie-2-midsummer-knights-dream-1088 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/my-hero-academia-the-movie-2-heroes-rising-383 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/my-hero-academia-the-movie-2-heroes-rising-383 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/battle-of-clay-10620 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/battle-of-clay-10620 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/tales-of-luminaria-the-fateful-crossroad-17962 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/tales-of-luminaria-the-fateful-crossroad-17962 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/growlanser-iv-wayfarer-of-time-8906 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/growlanser-iv-wayfarer-of-time-8906 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/blackfox-4434 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/blackfox-4434 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/mobile-police-patlabor-2-the-movie-696 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/mobile-police-patlabor-2-the-movie-696 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/garouden-the-way-of-the-lone-wolf-19165 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/garouden-the-way-of-the-lone-wolf-19165 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/saint-seiya-the-movie-evil-goddess-eris-4181 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/saint-seiya-the-movie-evil-goddess-eris-4181 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/kabaneri-of-the-iron-fortress-the-battle-of-unato-933 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/kabaneri-of-the-iron-fortress-the-battle-of-unato-933 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/saint-seiya-knights-of-the-zodiac-battle-for-sanctuary-part-2-19090 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/saint-seiya-knights-of-the-zodiac-battle-for-sanctuary-part-2-19090 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/soul-hunter-3019 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/soul-hunter-3019 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/highschool-of-the-dead-drifters-of-the-dead-5101 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/highschool-of-the-dead-drifters-of-the-dead-5101 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/search?keyword=Haikyu!!%20Movie:%20Battle%20of%20the%20Garbage%20Dump&page=2 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/search?keyword=Haikyu!!%20Movie:%20Battle%20of%20the%20Garbage%20Dump&page=3 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/search?keyword=Haikyu!!%20Movie:%20Battle%20of%20the%20Garbage%20Dump&page=76 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/one-piece-movie-1-3096 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/one-piece-movie-1-3096 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/one-piece-100 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/one-piece-fan-letter-19406 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/one-piece-fan-letter-19406 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/one-piece-film-red-18236 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/one-piece-film-red-18236 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/one-piece-the-movie-13-film-gold-550 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/one-piece-the-movie-13-film-gold-550 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/one-room-9215 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/one-room-9215 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/one-room-second-season-7392 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/one-room-second-season-7392 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/one-room-third-season-6959 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/one-room-third-season-6959 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/one-piece-episode-of-skypiea-3097 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/one-piece-episode-of-skypiea-3097 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/one-piece-log-fish-man-island-saga-19404 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/one-piece-log-fish-man-island-saga-19404 + 2024-11-08T15:50:46+00:00 + 0.64 + + + https://zenime.site/watch/one-piece-3d-gekisou-trap-coaster-3400 + 2024-11-08T15:50:46+00:00 + 0.64 + + + + \ No newline at end of file diff --git a/public/LandingPage.jpg b/public/splash.jpg similarity index 100% rename from public/LandingPage.jpg rename to public/splash.jpg diff --git a/src/App.css b/src/App.css new file mode 100644 index 0000000..d608b5b --- /dev/null +++ b/src/App.css @@ -0,0 +1,27 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} +html, +body, +#root { + margin: 0; + padding: 0; +} + +.app-container { + display: flex; + flex-direction: column; + min-height: 100vh; + max-width: 2048px; + margin-inline: auto; +} +.content { + width: 100%; + flex-grow: 1; +} + +footer { + margin-top: auto; +} diff --git a/src/App.jsx b/src/App.jsx new file mode 100644 index 0000000..65102a4 --- /dev/null +++ b/src/App.jsx @@ -0,0 +1,73 @@ +import { useLocation } from "react-router-dom"; +import { useEffect } from "react"; +import { Routes, Route } from "react-router-dom"; +import { HomeInfoProvider } from "./context/HomeInfoContext"; +import Home from "./pages/Home/Home"; +import AnimeInfo from "./pages/animeInfo/AnimeInfo"; +import Navbar from "./components/navbar/Navbar"; +import Footer from "./components/footer/Footer"; +import Error from "./components/error/Error"; +import Category from "./pages/category/Category"; +import AtoZ from "./pages/a2z/AtoZ"; +import { azRoute, categoryRoutes } from "./utils/category.utils"; +import "./App.css"; +import Search from "./pages/search/Search"; +import Watch from "./pages/watch/Watch"; +import Producer from "./components/producer/Producer"; +import SplashScreen from "./components/splashscreen/SplashScreen"; + +function App() { + const location = useLocation(); + + // Scroll to top on location change + useEffect(() => { + window.scrollTo(0, 0); + }, [location]); + + // Check if the current route is for the splash screen + const isSplashScreen = location.pathname === "/"; + + return ( + +
+
+ {!isSplashScreen && } + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + {/* Render category routes */} + {categoryRoutes.map((path) => ( + + } + /> + ))} + {/* Render A to Z routes */} + {azRoute.map((path) => ( + } + /> + ))} + } /> + } /> + {/* Catch-all route for 404 */} + } /> + + {!isSplashScreen &&
} +
+
+
+ ); +} + +export default App; diff --git a/src/app/anime/[id]/page.js b/src/app/anime/[id]/page.js deleted file mode 100644 index a50221a..0000000 --- a/src/app/anime/[id]/page.js +++ /dev/null @@ -1,100 +0,0 @@ -import React, { Suspense } from 'react'; -import Link from 'next/link'; -import { fetchAnimeInfo } from '@/lib/api'; -import AnimeDetails from '@/components/AnimeDetails.js'; - -// Loading state component -const LoadingState = () => ( -
-
- {/* Background Placeholder */} -
- - {/* Content Placeholder */} -
-
- {/* Poster Placeholder */} -
-
-
- - {/* Details Placeholder */} -
-
-
-
-
-
-
-
-
-
-
-); - -// Error state component -const ErrorState = ({ error }) => ( -
-
-

Error Loading Anime

-

{error}

-
- - - Go Back Home - -
-
-
-); - -// Not found state component -const NotFoundState = () => ( -
-
-

Anime Not Found

-

The anime you're looking for doesn't exist or was removed.

- - Go Back Home - -
-
-); - -// Main anime content component -const AnimeContent = async ({ id }) => { - try { - const anime = await fetchAnimeInfo(id); - - if (!anime || !anime.info) { - return ; - } - - return ( -
- -
- ); - } catch (error) { - return ; - } -}; - -// Main page component with Suspense -export default function AnimeInfoPage({ params }) { - const { id } = params; - - return ( - }> - - - ); -} \ No newline at end of file diff --git a/src/app/anime/layout.js b/src/app/anime/layout.js deleted file mode 100644 index 9fab739..0000000 --- a/src/app/anime/layout.js +++ /dev/null @@ -1,5 +0,0 @@ -import SharedLayout from '@/components/SharedLayout'; - -export default function AnimeLayout({ children }) { - return {children}; -} \ No newline at end of file diff --git a/src/app/contacts/page.jsx b/src/app/contacts/page.jsx deleted file mode 100644 index 5f5ecd9..0000000 --- a/src/app/contacts/page.jsx +++ /dev/null @@ -1,169 +0,0 @@ -'use client'; - -import { useState } from 'react'; -import SharedLayout from '@/components/SharedLayout'; - -export default function ContactsPage() { - const [formData, setFormData] = useState({ - name: '', - email: '', - subject: '', - message: '', - }); - - const [isSubmitting, setIsSubmitting] = useState(false); - const [submitStatus, setSubmitStatus] = useState(null); - - const handleChange = (e) => { - const { name, value } = e.target; - setFormData((prev) => ({ - ...prev, - [name]: value, - })); - }; - - const handleSubmit = async (e) => { - e.preventDefault(); - setIsSubmitting(true); - - // Simulate form submission - try { - // In a real application, you would send this data to your backend/API - await new Promise(resolve => setTimeout(resolve, 1000)); - setSubmitStatus({ success: true, message: 'Your message has been sent successfully!' }); - // Reset form - setFormData({ - name: '', - email: '', - subject: '', - message: '', - }); - } catch (error) { - setSubmitStatus({ success: false, message: 'There was an error sending your message. Please try again.' }); - } finally { - setIsSubmitting(false); - } - }; - - return ( - -
-

Contact Us

- -
-
-
-

- Have questions, suggestions, or need assistance? We're here to help. - Fill out the form and we'll get back to you as soon as possible. -

-
- -
-
-

Email

-

support@justanime.com

-
- -
-

Connect With Us

- -
-
-
- -
-
-
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- -
- - {submitStatus && ( -
- {submitStatus.message} -
- )} -
-
-
-
-
- ); -} \ No newline at end of file diff --git a/src/app/dmca/page.jsx b/src/app/dmca/page.jsx deleted file mode 100644 index e4c7127..0000000 --- a/src/app/dmca/page.jsx +++ /dev/null @@ -1,62 +0,0 @@ -'use client'; - -import SharedLayout from '@/components/SharedLayout'; - -export default function DmcaPage() { - return ( - -
-

DMCA Policy

- -
-
-

- We take the intellectual property rights of others seriously and require that our Users do the same. - The Digital Millennium Copyright Act (DMCA) established a process for addressing claims of copyright infringement. - If you own a copyright or have authority to act on behalf of a copyright owner and want to report a claim that a third party is - infringing that material on or through JustAnime's services, please submit a DMCA report as outlined below, and we will take appropriate action. -

- -
-

DMCA Report Requirements

-
    -
  • A description of the copyrighted work that you claim is being infringed;
  • -
  • A description of the material you claim is infringing and that you want removed or access to which you want disabled and the URL or other location of that material;
  • -
  • Your name, title (if acting as an agent), address, telephone number, and email address;
  • -
  • The following statement: "I have a good faith belief that the use of the copyrighted material I am complaining of is not authorized by the copyright owner, its agent, or the law (e.g., as a fair use)";
  • -
  • The following statement: "The information in this notice is accurate and, under penalty of perjury, I am the owner, or authorized to act on behalf of the owner, of the copyright or of an exclusive right that is allegedly infringed";
  • -
  • An electronic or physical signature of the owner of the copyright or a person authorized to act on the owner's behalf.
  • -
-
- -
-

- Your DMCA takedown request should be submitted through our Contact page. -

- -

- We will then review your DMCA request and take proper actions, including removal of the content from the website. -

-
- -
-

Submit a DMCA Request

-

- To submit a DMCA takedown request, please include all required information as listed above and - contact us through our Contact page. -

- -
-
-
-
-
- ); -} \ No newline at end of file diff --git a/src/app/favicon.ico b/src/app/favicon.ico deleted file mode 100644 index 718d6fea4835ec2d246af9800eddb7ffb276240c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25931 zcmeHv30#a{`}aL_*G&7qml|y<+KVaDM2m#dVr!KsA!#An?kSQM(q<_dDNCpjEux83 zLb9Z^XxbDl(w>%i@8hT6>)&Gu{h#Oeyszu?xtw#Zb1mO{pgX9699l+Qppw7jXaYf~-84xW z)w4x8?=youko|}Vr~(D$UXIbiXABHh`p1?nn8Po~fxRJv}|0e(BPs|G`(TT%kKVJAdg5*Z|x0leQq0 zkdUBvb#>9F()jo|T~kx@OM8$9wzs~t2l;K=woNssA3l6|sx2r3+kdfVW@e^8e*E}v zA1y5{bRi+3Z`uD3{F7LgFJDdvm;nJilkzDku>BwXH(8ItVCXk*-lSJnR?-2UN%hJ){&rlvg`CDTj z)Bzo!3v7Ou#83zEDEFcKt(f1E0~=rqeEbTnMvWR#{+9pg%7G8y>u1OVRUSoox-ovF z2Ydma(;=YuBY(eI|04{hXzZD6_f(v~H;C~y5=DhAC{MMS>2fm~1H_t2$56pc$NH8( z5bH|<)71dV-_oCHIrzrT`2s-5w_+2CM0$95I6X8p^r!gHp+j_gd;9O<1~CEQQGS8) zS9Qh3#p&JM-G8rHekNmKVewU;pJRcTAog68KYo^dRo}(M>36U4Us zfgYWSiHZL3;lpWT=zNAW>Dh#mB!_@Lg%$ms8N-;aPqMn+C2HqZgz&9~Eu z4|Kp<`$q)Uw1R?y(~S>ePdonHxpV1#eSP1B;Ogo+-Pk}6#0GsZZ5!||ev2MGdh}_m z{DeR7?0-1^zVs&`AV6Vt;r3`I`OI_wgs*w=eO%_#7Kepl{B@xiyCANc(l zzIyd4y|c6PXWq9-|KM8(zIk8LPk(>a)zyFWjhT!$HJ$qX1vo@d25W<fvZQ2zUz5WRc(UnFMKHwe1| zWmlB1qdbiA(C0jmnV<}GfbKtmcu^2*P^O?MBLZKt|As~ge8&AAO~2K@zbXelK|4T<{|y4`raF{=72kC2Kn(L4YyenWgrPiv z@^mr$t{#X5VuIMeL!7Ab6_kG$&#&5p*Z{+?5U|TZ`B!7llpVmp@skYz&n^8QfPJzL z0G6K_OJM9x+Wu2gfN45phANGt{7=C>i34CV{Xqlx(fWpeAoj^N0Biu`w+MVcCUyU* zDZuzO0>4Z6fbu^T_arWW5n!E45vX8N=bxTVeFoep_G#VmNlQzAI_KTIc{6>c+04vr zx@W}zE5JNSU>!THJ{J=cqjz+4{L4A{Ob9$ZJ*S1?Ggg3klFp!+Y1@K+pK1DqI|_gq z5ZDXVpge8-cs!o|;K73#YXZ3AShj50wBvuq3NTOZ`M&qtjj#GOFfgExjg8Gn8>Vq5 z`85n+9|!iLCZF5$HJ$Iu($dm?8~-ofu}tEc+-pyke=3!im#6pk_Wo8IA|fJwD&~~F zc16osQ)EBo58U7XDuMexaPRjU@h8tXe%S{fA0NH3vGJFhuyyO!Uyl2^&EOpX{9As0 zWj+P>{@}jxH)8|r;2HdupP!vie{sJ28b&bo!8`D^x}TE$%zXNb^X1p@0PJ86`dZyj z%ce7*{^oo+6%&~I!8hQy-vQ7E)0t0ybH4l%KltWOo~8cO`T=157JqL(oq_rC%ea&4 z2NcTJe-HgFjNg-gZ$6!Y`SMHrlj}Etf7?r!zQTPPSv}{so2e>Fjs1{gzk~LGeesX%r(Lh6rbhSo_n)@@G-FTQy93;l#E)hgP@d_SGvyCp0~o(Y;Ee8{ zdVUDbHm5`2taPUOY^MAGOw*>=s7=Gst=D+p+2yON!0%Hk` zz5mAhyT4lS*T3LS^WSxUy86q&GnoHxzQ6vm8)VS}_zuqG?+3td68_x;etQAdu@sc6 zQJ&5|4(I?~3d-QOAODHpZ=hlSg(lBZ!JZWCtHHSj`0Wh93-Uk)_S%zsJ~aD>{`A0~ z9{AG(e|q3g5B%wYKRxiL2Y$8(4w6bzchKuloQW#e&S3n+P- z8!ds-%f;TJ1>)v)##>gd{PdS2Oc3VaR`fr=`O8QIO(6(N!A?pr5C#6fc~Ge@N%Vvu zaoAX2&(a6eWy_q&UwOhU)|P3J0Qc%OdhzW=F4D|pt0E4osw;%<%Dn58hAWD^XnZD= z>9~H(3bmLtxpF?a7su6J7M*x1By7YSUbxGi)Ot0P77`}P3{)&5Un{KD?`-e?r21!4vTTnN(4Y6Lin?UkSM z`MXCTC1@4A4~mvz%Rh2&EwY))LeoT=*`tMoqcEXI>TZU9WTP#l?uFv+@Dn~b(>xh2 z;>B?;Tz2SR&KVb>vGiBSB`@U7VIWFSo=LDSb9F{GF^DbmWAfpms8Sx9OX4CnBJca3 zlj9(x!dIjN?OG1X4l*imJNvRCk}F%!?SOfiOq5y^mZW)jFL@a|r-@d#f7 z2gmU8L3IZq0ynIws=}~m^#@&C%J6QFo~Mo4V`>v7MI-_!EBMMtb%_M&kvAaN)@ZVw z+`toz&WG#HkWDjnZE!6nk{e-oFdL^$YnbOCN}JC&{$#$O27@|Tn-skXr)2ml2~O!5 zX+gYoxhoc7qoU?C^3~&!U?kRFtnSEecWuH0B0OvLodgUAi}8p1 zrO6RSXHH}DMc$&|?D004DiOVMHV8kXCP@7NKB zgaZq^^O<7PoKEp72kby@W0Z!Y*Ay{&vfg#C&gG@YVR9g?FEocMUi1gSN$+V+ayF45{a zuDZDTN}mS|;BO%gEf}pjBfN2-gIrU#G5~cucA;dokXW89%>AyXJJI z9X4UlIWA|ZYHgbI z5?oFk@A=Ik7lrEQPDH!H+b`7_Y~aDb_qa=B2^Y&Ow41cU=4WDd40dp5(QS-WMN-=Y z9g;6_-JdNU;|6cPwf$ak*aJIcwL@1n$#l~zi{c{EW?T;DaW*E8DYq?Umtz{nJ&w-M zEMyTDrC&9K$d|kZe2#ws6)L=7K+{ zQw{XnV6UC$6-rW0emqm8wJoeZK)wJIcV?dST}Z;G0Arq{dVDu0&4kd%N!3F1*;*pW zR&qUiFzK=@44#QGw7k1`3t_d8&*kBV->O##t|tonFc2YWrL7_eqg+=+k;!F-`^b8> z#KWCE8%u4k@EprxqiV$VmmtiWxDLgnGu$Vs<8rppV5EajBXL4nyyZM$SWVm!wnCj-B!Wjqj5-5dNXukI2$$|Bu3Lrw}z65Lc=1G z^-#WuQOj$hwNGG?*CM_TO8Bg-1+qc>J7k5c51U8g?ZU5n?HYor;~JIjoWH-G>AoUP ztrWWLbRNqIjW#RT*WqZgPJXU7C)VaW5}MiijYbABmzoru6EmQ*N8cVK7a3|aOB#O& zBl8JY2WKfmj;h#Q!pN%9o@VNLv{OUL?rixHwOZuvX7{IJ{(EdPpuVFoQqIOa7giLVkBOKL@^smUA!tZ1CKRK}#SSM)iQHk)*R~?M!qkCruaS!#oIL1c z?J;U~&FfH#*98^G?i}pA{ z9Jg36t4=%6mhY(quYq*vSxptes9qy|7xSlH?G=S@>u>Ebe;|LVhs~@+06N<4CViBk zUiY$thvX;>Tby6z9Y1edAMQaiH zm^r3v#$Q#2T=X>bsY#D%s!bhs^M9PMAcHbCc0FMHV{u-dwlL;a1eJ63v5U*?Q_8JO zT#50!RD619#j_Uf))0ooADz~*9&lN!bBDRUgE>Vud-i5ck%vT=r^yD*^?Mp@Q^v+V zG#-?gKlr}Eeqifb{|So?HM&g91P8|av8hQoCmQXkd?7wIJwb z_^v8bbg`SAn{I*4bH$u(RZ6*xUhuA~hc=8czK8SHEKTzSxgbwi~9(OqJB&gwb^l4+m`k*Q;_?>Y-APi1{k zAHQ)P)G)f|AyjSgcCFps)Fh6Bca*Xznq36!pV6Az&m{O8$wGFD? zY&O*3*J0;_EqM#jh6^gMQKpXV?#1?>$ml1xvh8nSN>-?H=V;nJIwB07YX$e6vLxH( zqYwQ>qxwR(i4f)DLd)-$P>T-no_c!LsN@)8`e;W@)-Hj0>nJ-}Kla4-ZdPJzI&Mce zv)V_j;(3ERN3_@I$N<^|4Lf`B;8n+bX@bHbcZTopEmDI*Jfl)-pFDvo6svPRoo@(x z);_{lY<;);XzT`dBFpRmGrr}z5u1=pC^S-{ce6iXQlLGcItwJ^mZx{m$&DA_oEZ)B{_bYPq-HA zcH8WGoBG(aBU_j)vEy+_71T34@4dmSg!|M8Vf92Zj6WH7Q7t#OHQqWgFE3ARt+%!T z?oLovLVlnf?2c7pTc)~cc^($_8nyKwsN`RA-23ed3sdj(ys%pjjM+9JrctL;dy8a( z@en&CQmnV(()bu|Y%G1-4a(6x{aLytn$T-;(&{QIJB9vMox11U-1HpD@d(QkaJdEb zG{)+6Dos_L+O3NpWo^=gR?evp|CqEG?L&Ut#D*KLaRFOgOEK(Kq1@!EGcTfo+%A&I z=dLbB+d$u{sh?u)xP{PF8L%;YPPW53+@{>5W=Jt#wQpN;0_HYdw1{ksf_XhO4#2F= zyPx6Lx2<92L-;L5PD`zn6zwIH`Jk($?Qw({erA$^bC;q33hv!d!>%wRhj# zal^hk+WGNg;rJtb-EB(?czvOM=H7dl=vblBwAv>}%1@{}mnpUznfq1cE^sgsL0*4I zJ##!*B?=vI_OEVis5o+_IwMIRrpQyT_Sq~ZU%oY7c5JMIADzpD!Upz9h@iWg_>>~j zOLS;wp^i$-E?4<_cp?RiS%Rd?i;f*mOz=~(&3lo<=@(nR!_Rqiprh@weZlL!t#NCc zO!QTcInq|%#>OVgobj{~ixEUec`E25zJ~*DofsQdzIa@5^nOXj2T;8O`l--(QyU^$t?TGY^7#&FQ+2SS3B#qK*k3`ye?8jUYSajE5iBbJls75CCc(m3dk{t?- zopcER9{Z?TC)mk~gpi^kbbu>b-+a{m#8-y2^p$ka4n60w;Sc2}HMf<8JUvhCL0B&Btk)T`ctE$*qNW8L$`7!r^9T+>=<=2qaq-;ll2{`{Rg zc5a0ZUI$oG&j-qVOuKa=*v4aY#IsoM+1|c4Z)<}lEDvy;5huB@1RJPquU2U*U-;gu z=En2m+qjBzR#DEJDO`WU)hdd{Vj%^0V*KoyZ|5lzV87&g_j~NCjwv0uQVqXOb*QrQ zy|Qn`hxx(58c70$E;L(X0uZZ72M1!6oeg)(cdKO ze0gDaTz+ohR-#d)NbAH4x{I(21yjwvBQfmpLu$)|m{XolbgF!pmsqJ#D}(ylp6uC> z{bqtcI#hT#HW=wl7>p!38sKsJ`r8}lt-q%Keqy%u(xk=yiIJiUw6|5IvkS+#?JTBl z8H5(Q?l#wzazujH!8o>1xtn8#_w+397*_cy8!pQGP%K(Ga3pAjsaTbbXJlQF_+m+-UpUUent@xM zg%jqLUExj~o^vQ3Gl*>wh=_gOr2*|U64_iXb+-111aH}$TjeajM+I20xw(((>fej-@CIz4S1pi$(#}P7`4({6QS2CaQS4NPENDp>sAqD z$bH4KGzXGffkJ7R>V>)>tC)uax{UsN*dbeNC*v}#8Y#OWYwL4t$ePR?VTyIs!wea+ z5Urmc)X|^`MG~*dS6pGSbU+gPJoq*^a=_>$n4|P^w$sMBBy@f*Z^Jg6?n5?oId6f{ z$LW4M|4m502z0t7g<#Bx%X;9<=)smFolV&(V^(7Cv2-sxbxopQ!)*#ZRhTBpx1)Fc zNm1T%bONzv6@#|dz(w02AH8OXe>kQ#1FMCzO}2J_mST)+ExmBr9cva-@?;wnmWMOk z{3_~EX_xadgJGv&H@zK_8{(x84`}+c?oSBX*Ge3VdfTt&F}yCpFP?CpW+BE^cWY0^ zb&uBN!Ja3UzYHK-CTyA5=L zEMW{l3Usky#ly=7px648W31UNV@K)&Ub&zP1c7%)`{);I4b0Q<)B}3;NMG2JH=X$U zfIW4)4n9ZM`-yRj67I)YSLDK)qfUJ_ij}a#aZN~9EXrh8eZY2&=uY%2N0UFF7<~%M zsB8=erOWZ>Ct_#^tHZ|*q`H;A)5;ycw*IcmVxi8_0Xk}aJA^ath+E;xg!x+As(M#0=)3!NJR6H&9+zd#iP(m0PIW8$ z1Y^VX`>jm`W!=WpF*{ioM?C9`yOR>@0q=u7o>BP-eSHqCgMDj!2anwH?s%i2p+Q7D zzszIf5XJpE)IG4;d_(La-xenmF(tgAxK`Y4sQ}BSJEPs6N_U2vI{8=0C_F?@7<(G; zo$~G=8p+076G;`}>{MQ>t>7cm=zGtfbdDXm6||jUU|?X?CaE?(<6bKDYKeHlz}DA8 zXT={X=yp_R;HfJ9h%?eWvQ!dRgz&Su*JfNt!Wu>|XfU&68iRikRrHRW|ZxzRR^`eIGt zIeiDgVS>IeExKVRWW8-=A=yA`}`)ZkWBrZD`hpWIxBGkh&f#ijr449~m`j6{4jiJ*C!oVA8ZC?$1RM#K(_b zL9TW)kN*Y4%^-qPpMP7d4)o?Nk#>aoYHT(*g)qmRUb?**F@pnNiy6Fv9rEiUqD(^O zzyS?nBrX63BTRYduaG(0VVG2yJRe%o&rVrLjbxTaAFTd8s;<<@Qs>u(<193R8>}2_ zuwp{7;H2a*X7_jryzriZXMg?bTuegABb^87@SsKkr2)0Gyiax8KQWstw^v#ix45EVrcEhr>!NMhprl$InQMzjSFH54x5k9qHc`@9uKQzvL4ihcq{^B zPrVR=o_ic%Y>6&rMN)hTZsI7I<3&`#(nl+3y3ys9A~&^=4?PL&nd8)`OfG#n zwAMN$1&>K++c{^|7<4P=2y(B{jJsQ0a#U;HTo4ZmWZYvI{+s;Td{Yzem%0*k#)vjpB zia;J&>}ICate44SFYY3vEelqStQWFihx%^vQ@Do(sOy7yR2@WNv7Y9I^yL=nZr3mb zXKV5t@=?-Sk|b{XMhA7ZGB@2hqsx}4xwCW!in#C zI@}scZlr3-NFJ@NFaJlhyfcw{k^vvtGl`N9xSo**rDW4S}i zM9{fMPWo%4wYDG~BZ18BD+}h|GQKc-g^{++3MY>}W_uq7jGHx{mwE9fZiPCoxN$+7 zrODGGJrOkcPQUB(FD5aoS4g~7#6NR^ma7-!>mHuJfY5kTe6PpNNKC9GGRiu^L31uG z$7v`*JknQHsYB!Tm_W{a32TM099djW%5e+j0Ve_ct}IM>XLF1Ap+YvcrLV=|CKo6S zb+9Nl3_YdKP6%Cxy@6TxZ>;4&nTneadr z_ES90ydCev)LV!dN=#(*f}|ZORFdvkYBni^aLbUk>BajeWIOcmHP#8S)*2U~QKI%S zyrLmtPqb&TphJ;>yAxri#;{uyk`JJqODDw%(Z=2`1uc}br^V%>j!gS)D*q*f_-qf8&D;W1dJgQMlaH5er zN2U<%Smb7==vE}dDI8K7cKz!vs^73o9f>2sgiTzWcwY|BMYHH5%Vn7#kiw&eItCqa zIkR2~Q}>X=Ar8W|^Ms41Fm8o6IB2_j60eOeBB1Br!boW7JnoeX6Gs)?7rW0^5psc- zjS16yb>dFn>KPOF;imD}e!enuIniFzv}n$m2#gCCv4jM#ArwlzZ$7@9&XkFxZ4n!V zj3dyiwW4Ki2QG{@i>yuZXQizw_OkZI^-3otXC{!(lUpJF33gI60ak;Uqitp74|B6I zgg{b=Iz}WkhCGj1M=hu4#Aw173YxIVbISaoc z-nLZC*6Tgivd5V`K%GxhBsp@SUU60-rfc$=wb>zdJzXS&-5(NRRodFk;Kxk!S(O(a0e7oY=E( zAyS;Ow?6Q&XA+cnkCb{28_1N8H#?J!*$MmIwLq^*T_9-z^&UE@A(z9oGYtFy6EZef LrJugUA?W`A8`#=m diff --git a/src/app/globals.css b/src/app/globals.css deleted file mode 100644 index 9413505..0000000 --- a/src/app/globals.css +++ /dev/null @@ -1,173 +0,0 @@ -@import "tailwindcss"; - -:root { - --background: #0a0a0a; - --foreground: #ffffff; - --primary: #d1d1d1; - --secondary: #404040; - --accent: #808080; - --card: #131313; - --border: #2a2a2a; - --hover: #333333; - --text-muted: #8a8a8a; -} - -@theme inline { - --color-background: var(--background); - --color-foreground: var(--foreground); - --color-primary: var(--primary); - --color-secondary: var(--secondary); - --color-accent: var(--accent); - --color-card: var(--card); - --color-border: var(--border); - --color-hover: var(--hover); - --color-text-muted: var(--text-muted); - --font-sans: var(--font-geist-sans); - --font-mono: var(--font-geist-mono); -} - -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #f5f5f5; - } -} - -body { - margin: 0; - padding: 0; - min-height: 100vh; - background-color: var(--background); - color: var(--foreground); - font-family: var(--font-sans); -} - -/* Custom scrollbar */ -::-webkit-scrollbar { - width: 8px; -} - -::-webkit-scrollbar-track { - background: var(--background); -} - -::-webkit-scrollbar-thumb { - background: var(--border); - border-radius: 4px; -} - -::-webkit-scrollbar-thumb:hover { - background: var(--secondary); -} - -/* Hide scrollbar for Chrome, Safari and Opera */ -.scrollbar-hide::-webkit-scrollbar { - display: none; -} - -/* Hide scrollbar for IE, Edge and Firefox */ -.scrollbar-hide { - -ms-overflow-style: none; /* IE and Edge */ - scrollbar-width: none; /* Firefox */ -} - -.custom-scrollbar::-webkit-scrollbar { - width: 6px; - height: 6px; -} - -.custom-scrollbar::-webkit-scrollbar-track { - background: rgba(255, 255, 255, 0.05); - border-radius: 8px; -} - -.custom-scrollbar::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.15); - border-radius: 8px; -} - -.custom-scrollbar::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.25); -} - -/* Modern card styling */ -.card-hover { - transition: transform 0.3s ease, box-shadow 0.3s ease; -} - -.card-hover:hover { - transform: translateY(-4px); - box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); -} - -/* Gradient text */ -.gradient-text { - background: linear-gradient(to right, var(--foreground), var(--text-muted)); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; -} - -/* Button styles */ -.btn-primary { - background-color: var(--foreground); - color: var(--background); - transition: all 0.2s ease; -} - -.btn-primary:hover { - background-color: var(--text-muted); -} - -.btn-secondary { - background-color: transparent; - border: 1px solid var(--border); - color: var(--foreground); - transition: all 0.2s ease; -} - -.btn-secondary:hover { - background-color: var(--hover); -} - -/* Animation utilities */ -.fade-in { - animation: fadeIn 0.5s ease-in forwards; -} - -@keyframes fadeIn { - 0% { opacity: 0; } - 100% { opacity: 1; } -} - -.slide-up { - animation: slideUp 0.5s ease forwards; -} - -@keyframes slideUp { - 0% { transform: translateY(20px); opacity: 0; } - 100% { transform: translateY(0); opacity: 1; } -} - -/* Radial gradient for hero sections */ -.bg-radial-gradient { - background: radial-gradient(circle at center, rgba(20, 20, 20, 0) 0%, rgba(0, 0, 0, 0.8) 100%); -} - -/* Grid Pattern for backgrounds */ -.bg-grid-pattern { - background-size: 25px 25px; - background-image: - linear-gradient(to right, rgba(255, 255, 255, 0.05) 1px, transparent 1px), - linear-gradient(to bottom, rgba(255, 255, 255, 0.05) 1px, transparent 1px); -} - -/* Hide scrollbar while maintaining scroll functionality */ -.hide-scrollbar { - -ms-overflow-style: none; /* IE and Edge */ - scrollbar-width: none; /* Firefox */ -} - -.hide-scrollbar::-webkit-scrollbar { - display: none; /* Chrome, Safari and Opera */ -} diff --git a/src/app/home/layout.js b/src/app/home/layout.js deleted file mode 100644 index 48bdb93..0000000 --- a/src/app/home/layout.js +++ /dev/null @@ -1,5 +0,0 @@ -import SharedLayout from '@/components/SharedLayout'; - -export default function HomeLayout({ children }) { - return {children}; -} \ No newline at end of file diff --git a/src/app/home/page.js b/src/app/home/page.js deleted file mode 100644 index d263a5b..0000000 --- a/src/app/home/page.js +++ /dev/null @@ -1,202 +0,0 @@ -import React from 'react'; -import AnimeCard from '@/components/AnimeCard'; -import TopLists from '@/components/TopLists'; -import AnimeCalendar from '@/components/AnimeCalendar'; -import GenreBar from '@/components/GenreBar'; -import SpotlightCarousel from '@/components/SpotlightCarousel'; -import AnimeTabs from '@/components/AnimeTabs'; -import TrendingList from '@/components/TrendingList'; -import Link from 'next/link'; -import { - fetchRecentEpisodes, - fetchMostFavorite, - fetchSpotlightAnime, - fetchTopToday, - fetchTopWeek, - fetchTopMonth, - fetchMostPopular, - fetchTopAiring, - fetchLatestCompleted, - fetchTrending -} from '@/lib/api'; - -// New unified section component with grid layout -const AnimeGridSection = ({ title, animeList = [], viewMoreLink, isRecent = false }) => { - if (!animeList || animeList.length === 0) { - return ( -
-
-

{title}

-
-
-
-
-
-
-
-
- ); - } - - return ( -
-
-

{title}

- {viewMoreLink && ( - - View All - - - - - )} -
- -
- {animeList.slice(0, 12).map((anime, index) => ( - - ))} -
-
- ); -}; - -async function HomePage() { - try { - console.log('[HomePage] Fetching home page data'); - - // Fetch all data in parallel - const [ - spotlightData, - recentEpisodes, - mostFavorite, - topToday, - topWeek, - topMonth, - topAiring, - popular, - latestCompleted, - trending - ] = await Promise.all([ - fetchSpotlightAnime().catch(err => { - console.error("[HomePage] Error fetching spotlight anime:", err.message); - return []; - }), - fetchRecentEpisodes().catch(err => { - console.error("[HomePage] Error fetching recent episodes:", err.message); - return { results: [] }; - }), - fetchMostFavorite().catch(err => { - console.error("[HomePage] Error fetching most favorite:", err.message); - return { results: [] }; - }), - fetchTopToday().catch(err => { - console.error("[HomePage] Error fetching top today:", err.message); - return []; - }), - fetchTopWeek().catch(err => { - console.error("[HomePage] Error fetching top week:", err.message); - return []; - }), - fetchTopMonth().catch(err => { - console.error("[HomePage] Error fetching top month:", err.message); - return []; - }), - fetchTopAiring().catch(err => { - console.error("[HomePage] Error fetching top airing anime:", err.message); - return { results: [] }; - }), - fetchMostPopular().catch(err => { - console.error("[HomePage] Error fetching popular anime:", err.message); - return { results: [] }; - }), - fetchLatestCompleted().catch(err => { - console.error("[HomePage] Error fetching latest completed anime:", err.message); - return { results: [] }; - }), - fetchTrending().catch(err => { - console.error("[HomePage] Error fetching trending anime:", err.message); - return { results: [] }; - }) - ]); - - console.log('[HomePage] Data fetched successfully'); - - return ( -
-
- {/* Spotlight Carousel */} - - - {/* Genre Bar */} -
- -
- - {/* Main Content + Sidebar Layout */} -
- {/* Main Content - 2/3 width on large screens */} -
- {/* Latest Episodes Grid */} - - - {/* Anime Tabs Section */} - -
- - {/* Sidebar - 1/4 width on large screens */} -
- {/* Trending List */} - - - {/* Calendar Widget */} - - - {/* Top Lists */} - -
-
-
-
- ); - } catch (error) { - console.error('[HomePage] Error in HomePage:', error.message); - return ( -
-
-

Unable to load content

-

There was an error loading the home page content. Please try refreshing the page.

- -
-
- ); - } -} - -export default HomePage; \ No newline at end of file diff --git a/src/app/latest-completed/layout.js b/src/app/latest-completed/layout.js deleted file mode 100644 index 37cb70c..0000000 --- a/src/app/latest-completed/layout.js +++ /dev/null @@ -1,5 +0,0 @@ -import SharedLayout from '@/components/SharedLayout'; - -export default function LatestCompletedLayout({ children }) { - return {children}; -} \ No newline at end of file diff --git a/src/app/latest-completed/page.js b/src/app/latest-completed/page.js deleted file mode 100644 index 8f97593..0000000 --- a/src/app/latest-completed/page.js +++ /dev/null @@ -1,305 +0,0 @@ -'use client'; - -import { useState, useEffect, useRef } from 'react'; -import AnimeCard from '@/components/AnimeCard'; -import AnimeFilters from '@/components/AnimeFilters'; -import { fetchLatestCompleted } from '@/lib/api'; - -export default function LatestCompletedPage() { - const [animeList, setAnimeList] = useState([]); - const [filteredList, setFilteredList] = useState([]); - const [isLoading, setIsLoading] = useState(true); - const [currentPage, setCurrentPage] = useState(1); - const [hasNextPage, setHasNextPage] = useState(false); - const [selectedGenre, setSelectedGenre] = useState(null); - const [yearFilter, setYearFilter] = useState('all'); - const [sortOrder, setSortOrder] = useState('default'); - const [searchQuery, setSearchQuery] = useState(''); - const [selectedSeasons, setSelectedSeasons] = useState([]); - const [selectedTypes, setSelectedTypes] = useState([]); - const [selectedStatus, setSelectedStatus] = useState([]); - const [selectedLanguages, setSelectedLanguages] = useState([]); - const [error, setError] = useState(null); - - // Current year for filtering - const currentYear = new Date().getFullYear(); - - // Add ref to track if this is the first render - const initialRender = useRef(true); - - useEffect(() => { - const fetchData = async () => { - setIsLoading(true); - try { - const data = await fetchLatestCompleted(currentPage); - - if (currentPage === 1) { - setAnimeList(data.results || []); - } else { - setAnimeList(prev => [...prev, ...(data.results || [])]); - } - - setHasNextPage(data.hasNextPage || false); - } catch (error) { - console.error('Error fetching latest completed anime:', error); - setError('Failed to load anime. Please try again later.'); - } finally { - setIsLoading(false); - } - }; - - fetchData(); - }, [currentPage]); - - // Apply filters and sorting whenever the anime list or filter settings change - useEffect(() => { - // Skip the initial render effect to avoid duplicate filtering - if (initialRender.current) { - initialRender.current = false; - return; - } - - if (!animeList.length) { - setFilteredList([]); - return; - } - - let result = [...animeList]; - - // Search filter - if (searchQuery && searchQuery.trim() !== '') { - const query = searchQuery.toLowerCase().trim(); - result = result.filter(anime => { - const title = (anime.title || '').toLowerCase(); - const otherNames = (anime.otherNames || '').toLowerCase(); - return title.includes(query) || otherNames.includes(query); - }); - } - - // Filter by genre if selected - if (selectedGenre) { - result = result.filter(anime => { - if (anime.genres && Array.isArray(anime.genres)) { - return anime.genres.some(g => - g.toLowerCase() === selectedGenre.toLowerCase() || - (g.name && g.name.toLowerCase() === selectedGenre.toLowerCase()) - ); - } else if (anime.genre) { - return anime.genre.toLowerCase().includes(selectedGenre.toLowerCase()); - } - return false; - }); - } - - // Filter by season - if (selectedSeasons.length > 0) { - result = result.filter(anime => { - const season = getAnimeSeason(anime); - return selectedSeasons.includes(season); - }); - } - - // Filter by year - if (yearFilter !== 'all') { - result = result.filter(anime => { - const animeYear = parseInt(anime.year) || 0; - if (yearFilter === 'older') { - return animeYear < 2000; - } else { - return animeYear.toString() === yearFilter; - } - }); - } - - // Filter by type - if (selectedTypes.length > 0) { - result = result.filter(anime => - selectedTypes.includes(anime.type) - ); - } - - // Filter by status - if (selectedStatus.length > 0) { - result = result.filter(anime => { - const status = anime.status || getDefaultStatus(anime); - return selectedStatus.includes(status); - }); - } - - // Filter by language - if (selectedLanguages.length > 0) { - result = result.filter(anime => { - const language = anime.language || getDefaultLanguage(anime); - return selectedLanguages.includes(language); - }); - } - - // Apply sorting - switch (sortOrder) { - case 'title-asc': - result.sort((a, b) => (a.title || '').localeCompare(b.title || '')); - break; - case 'title-desc': - result.sort((a, b) => (b.title || '').localeCompare(a.title || '')); - break; - case 'year-desc': - result.sort((a, b) => (parseInt(b.year) || 0) - (parseInt(a.year) || 0)); - break; - case 'year-asc': - result.sort((a, b) => (parseInt(a.year) || 0) - (parseInt(b.year) || 0)); - break; - default: - // Default order from API - break; - } - - setFilteredList(result); - }, [animeList, selectedGenre, yearFilter, sortOrder, searchQuery, selectedSeasons, selectedTypes, selectedStatus, selectedLanguages]); - - const handleLoadMore = () => { - setCurrentPage(prev => prev + 1); - }; - - const handleGenreChange = (genre) => { - setSelectedGenre(genre); - }; - - const handleYearChange = (year) => { - setYearFilter(year); - }; - - const handleSortChange = (order) => { - setSortOrder(order); - }; - - const handleSearchChange = (value) => { - setSearchQuery(value); - }; - - const handleSeasonChange = (seasons) => { - setSelectedSeasons(seasons); - }; - - const handleTypeChange = (types) => { - setSelectedTypes(types); - }; - - const handleStatusChange = (status) => { - setSelectedStatus(status); - }; - - const handleLanguageChange = (languages) => { - setSelectedLanguages(languages); - }; - - // Helper function to determine anime season based on available data - const getAnimeSeason = (anime) => { - if (anime.season) return anime.season; - - const seasons = ['Winter', 'Spring', 'Summer', 'Fall']; - // Use hash of ID to assign consistent season for demo purposes - const hash = anime.id.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0); - return seasons[hash % 4]; - }; - - // Helper function to determine anime status - const getDefaultStatus = (anime) => { - if (anime.status) return anime.status; - - // Default logic - you may need to customize this based on your actual data - const currentYear = new Date().getFullYear(); - if (anime.year > currentYear) return 'Upcoming'; - if (anime.totalEpisodes && anime.episodes && anime.episodes >= anime.totalEpisodes) return 'Completed'; - return 'Ongoing'; - }; - - // Helper function to determine anime language - const getDefaultLanguage = (anime) => { - if (anime.language) return anime.language; - - // Default to "Subbed" for all anime unless specifically marked - return anime.isDub ? 'Dubbed' : 'Subbed'; - }; - - return ( -
-

Latest Completed Anime

- - {/* Filters */} -
- -
- - {isLoading && animeList.length === 0 ? ( -
- {[...Array(14)].map((_, index) => ( -
-
-
-
-
-
-
- ))} -
- ) : (filteredList.length > 0 || animeList.length > 0) ? ( - <> -
- {(filteredList.length > 0 ? filteredList : animeList).map((anime) => ( - - ))} -
- - {hasNextPage && ( -
- -
- )} - - ) : ( -
-

No anime found

-

- We couldn't find any anime matching your criteria. Please try different filters. -

-
- )} -
- ); -} \ No newline at end of file diff --git a/src/app/layout.js b/src/app/layout.js deleted file mode 100644 index d25115b..0000000 --- a/src/app/layout.js +++ /dev/null @@ -1,34 +0,0 @@ -import { Geist, Geist_Mono } from "next/font/google"; -import { Analytics } from "@vercel/analytics/next"; -import { SpeedInsights } from "@vercel/speed-insights/next"; -import "./globals.css"; - -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); - -export const metadata = { - title: "JustAnime - Watch Anime Online", - description: "Watch the latest anime episodes for free. Stream all your favorite anime shows in HD quality.", - keywords: "anime, streaming, watch anime, free anime, anime online, just , justanime", -}; - -export default function RootLayout({ children }) { - return ( - - -
- {children} -
- - - - - ); -} diff --git a/src/app/most-popular/layout.js b/src/app/most-popular/layout.js deleted file mode 100644 index 7daa4ab..0000000 --- a/src/app/most-popular/layout.js +++ /dev/null @@ -1,5 +0,0 @@ -import SharedLayout from '@/components/SharedLayout'; - -export default function MostPopularLayout({ children }) { - return {children}; -} \ No newline at end of file diff --git a/src/app/most-popular/page.js b/src/app/most-popular/page.js deleted file mode 100644 index d546f9d..0000000 --- a/src/app/most-popular/page.js +++ /dev/null @@ -1,305 +0,0 @@ -'use client'; - -import { useState, useEffect, useRef } from 'react'; -import AnimeCard from '@/components/AnimeCard'; -import AnimeFilters from '@/components/AnimeFilters'; -import { fetchMostPopular } from '@/lib/api'; - -export default function MostPopularPage() { - const [animeList, setAnimeList] = useState([]); - const [filteredList, setFilteredList] = useState([]); - const [isLoading, setIsLoading] = useState(true); - const [currentPage, setCurrentPage] = useState(1); - const [hasNextPage, setHasNextPage] = useState(false); - const [selectedGenre, setSelectedGenre] = useState(null); - const [yearFilter, setYearFilter] = useState('all'); - const [sortOrder, setSortOrder] = useState('default'); - const [searchQuery, setSearchQuery] = useState(''); - const [selectedSeasons, setSelectedSeasons] = useState([]); - const [selectedTypes, setSelectedTypes] = useState([]); - const [selectedStatus, setSelectedStatus] = useState([]); - const [selectedLanguages, setSelectedLanguages] = useState([]); - const [error, setError] = useState(null); - - // Current year for filtering - const currentYear = new Date().getFullYear(); - - // Add ref to track if this is the first render - const initialRender = useRef(true); - - useEffect(() => { - const fetchData = async () => { - setIsLoading(true); - try { - const data = await fetchMostPopular(currentPage); - - if (currentPage === 1) { - setAnimeList(data.results || []); - } else { - setAnimeList(prev => [...prev, ...(data.results || [])]); - } - - setHasNextPage(data.hasNextPage || false); - } catch (error) { - console.error('Error fetching most popular anime:', error); - setError('Failed to load anime. Please try again later.'); - } finally { - setIsLoading(false); - } - }; - - fetchData(); - }, [currentPage]); - - // Apply filters and sorting whenever the anime list or filter settings change - useEffect(() => { - // Skip the initial render effect to avoid duplicate filtering - if (initialRender.current) { - initialRender.current = false; - return; - } - - if (!animeList.length) { - setFilteredList([]); - return; - } - - let result = [...animeList]; - - // Search filter - if (searchQuery && searchQuery.trim() !== '') { - const query = searchQuery.toLowerCase().trim(); - result = result.filter(anime => { - const title = (anime.title || '').toLowerCase(); - const otherNames = (anime.otherNames || '').toLowerCase(); - return title.includes(query) || otherNames.includes(query); - }); - } - - // Filter by genre if selected - if (selectedGenre) { - result = result.filter(anime => { - if (anime.genres && Array.isArray(anime.genres)) { - return anime.genres.some(g => - g.toLowerCase() === selectedGenre.toLowerCase() || - (g.name && g.name.toLowerCase() === selectedGenre.toLowerCase()) - ); - } else if (anime.genre) { - return anime.genre.toLowerCase().includes(selectedGenre.toLowerCase()); - } - return false; - }); - } - - // Filter by season - if (selectedSeasons.length > 0) { - result = result.filter(anime => { - const season = getAnimeSeason(anime); - return selectedSeasons.includes(season); - }); - } - - // Filter by year - if (yearFilter !== 'all') { - result = result.filter(anime => { - const animeYear = parseInt(anime.year) || 0; - if (yearFilter === 'older') { - return animeYear < 2000; - } else { - return animeYear.toString() === yearFilter; - } - }); - } - - // Filter by type - if (selectedTypes.length > 0) { - result = result.filter(anime => - selectedTypes.includes(anime.type) - ); - } - - // Filter by status - if (selectedStatus.length > 0) { - result = result.filter(anime => { - const status = anime.status || getDefaultStatus(anime); - return selectedStatus.includes(status); - }); - } - - // Filter by language - if (selectedLanguages.length > 0) { - result = result.filter(anime => { - const language = anime.language || getDefaultLanguage(anime); - return selectedLanguages.includes(language); - }); - } - - // Apply sorting - switch (sortOrder) { - case 'title-asc': - result.sort((a, b) => (a.title || '').localeCompare(b.title || '')); - break; - case 'title-desc': - result.sort((a, b) => (b.title || '').localeCompare(a.title || '')); - break; - case 'year-desc': - result.sort((a, b) => (parseInt(b.year) || 0) - (parseInt(a.year) || 0)); - break; - case 'year-asc': - result.sort((a, b) => (parseInt(a.year) || 0) - (parseInt(b.year) || 0)); - break; - default: - // Default order from API - break; - } - - setFilteredList(result); - }, [animeList, selectedGenre, yearFilter, sortOrder, searchQuery, selectedSeasons, selectedTypes, selectedStatus, selectedLanguages]); - - const handleLoadMore = () => { - setCurrentPage(prev => prev + 1); - }; - - const handleGenreChange = (genre) => { - setSelectedGenre(genre); - }; - - const handleYearChange = (year) => { - setYearFilter(year); - }; - - const handleSortChange = (order) => { - setSortOrder(order); - }; - - const handleSearchChange = (value) => { - setSearchQuery(value); - }; - - const handleSeasonChange = (seasons) => { - setSelectedSeasons(seasons); - }; - - const handleTypeChange = (types) => { - setSelectedTypes(types); - }; - - const handleStatusChange = (status) => { - setSelectedStatus(status); - }; - - const handleLanguageChange = (languages) => { - setSelectedLanguages(languages); - }; - - // Helper function to determine anime season based on available data - const getAnimeSeason = (anime) => { - if (anime.season) return anime.season; - - const seasons = ['Winter', 'Spring', 'Summer', 'Fall']; - // Use hash of ID to assign consistent season for demo purposes - const hash = anime.id.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0); - return seasons[hash % 4]; - }; - - // Helper function to determine anime status - const getDefaultStatus = (anime) => { - if (anime.status) return anime.status; - - // Default logic - you may need to customize this based on your actual data - const currentYear = new Date().getFullYear(); - if (anime.year > currentYear) return 'Upcoming'; - if (anime.totalEpisodes && anime.episodes && anime.episodes >= anime.totalEpisodes) return 'Completed'; - return 'Ongoing'; - }; - - // Helper function to determine anime language - const getDefaultLanguage = (anime) => { - if (anime.language) return anime.language; - - // Default to "Subbed" for all anime unless specifically marked - return anime.isDub ? 'Dubbed' : 'Subbed'; - }; - - return ( -
-

Most Popular Anime

- - {/* Filters */} -
- -
- - {isLoading && animeList.length === 0 ? ( -
- {[...Array(14)].map((_, index) => ( -
-
-
-
-
-
-
- ))} -
- ) : (filteredList.length > 0 || animeList.length > 0) ? ( - <> -
- {(filteredList.length > 0 ? filteredList : animeList).map((anime) => ( - - ))} -
- - {hasNextPage && ( -
- -
- )} - - ) : ( -
-

No anime found

-

- We couldn't find any anime matching your criteria. Please try different filters. -

-
- )} -
- ); -} \ No newline at end of file diff --git a/src/app/page.jsx b/src/app/page.jsx deleted file mode 100644 index bf8e703..0000000 --- a/src/app/page.jsx +++ /dev/null @@ -1,321 +0,0 @@ -'use client'; - -import Link from 'next/link'; -import { useState, useEffect, useRef } from 'react'; -import { useRouter } from 'next/navigation'; -import { fetchSearchSuggestions } from '@/lib/api'; -import Image from 'next/image'; - -export default function LandingPage() { - const [searchQuery, setSearchQuery] = useState(''); - const [searchSuggestions, setSearchSuggestions] = useState([]); - const [showSuggestions, setShowSuggestions] = useState(false); - const router = useRouter(); - const suggestionRef = useRef(null); - const searchInputRef = useRef(null); - - // For FAQ dropdowns - const [openFAQ, setOpenFAQ] = useState(null); - - const toggleFAQ = (index) => { - setOpenFAQ(openFAQ === index ? null : index); - }; - - // Fetch search suggestions when search query changes - useEffect(() => { - const fetchSuggestions = async () => { - if (searchQuery.trim().length > 2) { - try { - const suggestions = await fetchSearchSuggestions(searchQuery); - // Update to use the same format as home page search - setSearchSuggestions(suggestions || []); - setShowSuggestions(true); - } catch (error) { - console.error('Error fetching search suggestions:', error); - setSearchSuggestions([]); - } - } else { - setSearchSuggestions([]); - setShowSuggestions(false); - } - }; - - const debounceTimer = setTimeout(() => { - fetchSuggestions(); - }, 300); - - return () => clearTimeout(debounceTimer); - }, [searchQuery]); - - // Close suggestions when clicking outside - useEffect(() => { - const handleClickOutside = (event) => { - if ( - suggestionRef.current && - !suggestionRef.current.contains(event.target) && - !searchInputRef.current?.contains(event.target) - ) { - setShowSuggestions(false); - } - }; - - document.addEventListener('mousedown', handleClickOutside); - return () => { - document.removeEventListener('mousedown', handleClickOutside); - }; - }, []); - - const handleSearch = (e) => { - e.preventDefault(); - if (searchQuery.trim()) { - router.push(`/search?q=${encodeURIComponent(searchQuery)}`); - setSearchQuery(''); - setShowSuggestions(false); - } - }; - - const handleSuggestionClick = (suggestion) => { - // Updated to handle object-based suggestions - const query = suggestion.title || suggestion; - router.push(`/search?q=${encodeURIComponent(query)}`); - setSearchQuery(''); - setShowSuggestions(false); - }; - - return ( -
- {/* Background Image with Fade Effect */} -
- Dark anime character background - {/* Ultra-smooth gradient for fade from bottom */} -
-
-
- - {/* Unified Content Section */} -
- {/* Hero Content */} -
- {/* Logo */} -
- JustAnime Logo -
- - {/* Search Bar */} -
-
-
- setSearchQuery(e.target.value)} - onFocus={() => searchSuggestions.length > 0 && setShowSuggestions(true)} - /> -
- - - - -
-
-
- - {/* Search Suggestions Dropdown */} - {showSuggestions && searchSuggestions.length > 0 && ( -
- {searchSuggestions.map((suggestion, index) => ( -
handleSuggestionClick(suggestion)} - > - {suggestion.image && ( -
- {suggestion.title -
- )} -
-

{suggestion.title || suggestion}

- {suggestion.jname && ( -

{suggestion.jname}

- )} -
- {suggestion.type && ( - - {suggestion.type} - - )} -
- ))} -
- )} -
- - {/* Enter Homepage Button */} - - Enter Homepage - -
- - {/* FAQ Content */} -
-

Frequently Asked Questions

- -
- {/* FAQ Item 1 */} -
- -
-
-

Yes. We started this site to improve UX and are committed to keeping our users safe. We encourage all our users to notify us if anything looks suspicious.

-
-
-
- - {/* FAQ Item 2 */} -
- -
-
-

JustAnime offers the best user experience for anime streaming with fast loading speeds, a beautiful interface, no intrusive ads, large content library, HD quality, and weekly updates. Our clean design and extensive features set us apart from other platforms.

-
-
-
- - {/* FAQ Item 3 */} -
- -
-
-

You can request anime by visiting our Discord community or using the contact form. Our team aims to fulfill requests quickly based on availability.

-
-
-
-
-
-
-
- ); -} \ No newline at end of file diff --git a/src/app/recent/layout.js b/src/app/recent/layout.js deleted file mode 100644 index 14e5824..0000000 --- a/src/app/recent/layout.js +++ /dev/null @@ -1,5 +0,0 @@ -import SharedLayout from '@/components/SharedLayout'; - -export default function RecentEpisodesLayout({ children }) { - return {children}; -} \ No newline at end of file diff --git a/src/app/recent/page.js b/src/app/recent/page.js deleted file mode 100644 index 7e6dec4..0000000 --- a/src/app/recent/page.js +++ /dev/null @@ -1,305 +0,0 @@ -'use client'; - -import { useState, useEffect, useRef } from 'react'; -import AnimeCard from '@/components/AnimeCard'; -import AnimeFilters from '@/components/AnimeFilters'; -import { fetchRecentEpisodes } from '@/lib/api'; - -export default function RecentEpisodesPage() { - const [animeList, setAnimeList] = useState([]); - const [filteredList, setFilteredList] = useState([]); - const [isLoading, setIsLoading] = useState(true); - const [currentPage, setCurrentPage] = useState(1); - const [hasNextPage, setHasNextPage] = useState(false); - const [selectedGenre, setSelectedGenre] = useState(null); - const [yearFilter, setYearFilter] = useState('all'); - const [sortOrder, setSortOrder] = useState('default'); - const [searchQuery, setSearchQuery] = useState(''); - const [selectedSeasons, setSelectedSeasons] = useState([]); - const [selectedTypes, setSelectedTypes] = useState([]); - const [selectedStatus, setSelectedStatus] = useState([]); - const [selectedLanguages, setSelectedLanguages] = useState([]); - const [error, setError] = useState(null); - - // Current year for filtering - const currentYear = new Date().getFullYear(); - - // Add ref to track if this is the first render - const initialRender = useRef(true); - - useEffect(() => { - const fetchData = async () => { - setIsLoading(true); - try { - const data = await fetchRecentEpisodes(currentPage); - - if (currentPage === 1) { - setAnimeList(data.results || []); - } else { - setAnimeList(prev => [...prev, ...(data.results || [])]); - } - - setHasNextPage(data.hasNextPage || false); - } catch (error) { - console.error('Error fetching recent episodes:', error); - setError('Failed to load anime. Please try again later.'); - } finally { - setIsLoading(false); - } - }; - - fetchData(); - }, [currentPage]); - - // Apply filters and sorting whenever the anime list or filter settings change - useEffect(() => { - // Skip the initial render effect to avoid duplicate filtering - if (initialRender.current) { - initialRender.current = false; - return; - } - - if (!animeList.length) { - setFilteredList([]); - return; - } - - let result = [...animeList]; - - // Search filter - if (searchQuery && searchQuery.trim() !== '') { - const query = searchQuery.toLowerCase().trim(); - result = result.filter(anime => { - const title = (anime.title || '').toLowerCase(); - const otherNames = (anime.otherNames || '').toLowerCase(); - return title.includes(query) || otherNames.includes(query); - }); - } - - // Filter by genre if selected - if (selectedGenre) { - result = result.filter(anime => { - if (anime.genres && Array.isArray(anime.genres)) { - return anime.genres.some(g => - g.toLowerCase() === selectedGenre.toLowerCase() || - (g.name && g.name.toLowerCase() === selectedGenre.toLowerCase()) - ); - } else if (anime.genre) { - return anime.genre.toLowerCase().includes(selectedGenre.toLowerCase()); - } - return false; - }); - } - - // Filter by season - if (selectedSeasons.length > 0) { - result = result.filter(anime => { - const season = getAnimeSeason(anime); - return selectedSeasons.includes(season); - }); - } - - // Filter by year - if (yearFilter !== 'all') { - result = result.filter(anime => { - const animeYear = parseInt(anime.year) || 0; - if (yearFilter === 'older') { - return animeYear < 2000; - } else { - return animeYear.toString() === yearFilter; - } - }); - } - - // Filter by type - if (selectedTypes.length > 0) { - result = result.filter(anime => - selectedTypes.includes(anime.type) - ); - } - - // Filter by status - if (selectedStatus.length > 0) { - result = result.filter(anime => { - const status = anime.status || getDefaultStatus(anime); - return selectedStatus.includes(status); - }); - } - - // Filter by language - if (selectedLanguages.length > 0) { - result = result.filter(anime => { - const language = anime.language || getDefaultLanguage(anime); - return selectedLanguages.includes(language); - }); - } - - // Apply sorting - switch (sortOrder) { - case 'title-asc': - result.sort((a, b) => (a.title || '').localeCompare(b.title || '')); - break; - case 'title-desc': - result.sort((a, b) => (b.title || '').localeCompare(a.title || '')); - break; - case 'year-desc': - result.sort((a, b) => (parseInt(b.year) || 0) - (parseInt(a.year) || 0)); - break; - case 'year-asc': - result.sort((a, b) => (parseInt(a.year) || 0) - (parseInt(b.year) || 0)); - break; - default: - // Default order from API - break; - } - - setFilteredList(result); - }, [animeList, selectedGenre, yearFilter, sortOrder, searchQuery, selectedSeasons, selectedTypes, selectedStatus, selectedLanguages]); - - const handleLoadMore = () => { - setCurrentPage(prev => prev + 1); - }; - - const handleGenreChange = (genre) => { - setSelectedGenre(genre); - }; - - const handleYearChange = (year) => { - setYearFilter(year); - }; - - const handleSortChange = (order) => { - setSortOrder(order); - }; - - const handleSearchChange = (value) => { - setSearchQuery(value); - }; - - const handleSeasonChange = (seasons) => { - setSelectedSeasons(seasons); - }; - - const handleTypeChange = (types) => { - setSelectedTypes(types); - }; - - const handleStatusChange = (status) => { - setSelectedStatus(status); - }; - - const handleLanguageChange = (languages) => { - setSelectedLanguages(languages); - }; - - // Helper function to determine anime season based on available data - const getAnimeSeason = (anime) => { - if (anime.season) return anime.season; - - const seasons = ['Winter', 'Spring', 'Summer', 'Fall']; - // Use hash of ID to assign consistent season for demo purposes - const hash = anime.id.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0); - return seasons[hash % 4]; - }; - - // Helper function to determine anime status - const getDefaultStatus = (anime) => { - if (anime.status) return anime.status; - - // Default logic - you may need to customize this based on your actual data - const currentYear = new Date().getFullYear(); - if (anime.year > currentYear) return 'Upcoming'; - if (anime.totalEpisodes && anime.episodes && anime.episodes >= anime.totalEpisodes) return 'Completed'; - return 'Ongoing'; - }; - - // Helper function to determine anime language - const getDefaultLanguage = (anime) => { - if (anime.language) return anime.language; - - // Default to "Subbed" for all anime unless specifically marked - return anime.isDub ? 'Dubbed' : 'Subbed'; - }; - - return ( -
-

Recent Episodes

- - {/* Filters */} -
- -
- - {isLoading && animeList.length === 0 ? ( -
- {[...Array(14)].map((_, index) => ( -
-
-
-
-
-
-
- ))} -
- ) : (filteredList.length > 0 || animeList.length > 0) ? ( - <> -
- {(filteredList.length > 0 ? filteredList : animeList).map((anime) => ( - - ))} -
- - {hasNextPage && ( -
- -
- )} - - ) : ( -
-

No anime found

-

- We couldn't find any anime matching your criteria. Please try different filters. -

-
- )} -
- ); -} \ No newline at end of file diff --git a/src/app/search/[query]/page.js b/src/app/search/[query]/page.js deleted file mode 100644 index 7c147cc..0000000 --- a/src/app/search/[query]/page.js +++ /dev/null @@ -1,311 +0,0 @@ -'use client'; - -import { useState, useEffect, useCallback } from 'react'; -import { useParams, useRouter } from 'next/navigation'; -import AnimeCard from '@/components/AnimeCard'; -import AnimeFilters from '@/components/AnimeFilters'; -import { searchAnime, fetchMostPopular } from '@/lib/api'; - -export default function SearchPage() { - const router = useRouter(); - const { query } = useParams(); - const decodedQuery = query ? decodeURIComponent(query) : ''; - - const [searchResults, setSearchResults] = useState([]); - const [filteredResults, setFilteredResults] = useState([]); - const [isLoading, setIsLoading] = useState(true); - const [currentPage, setCurrentPage] = useState(1); - const [hasNextPage, setHasNextPage] = useState(false); - const [isEmptySearch, setIsEmptySearch] = useState(false); - - // Filter states - const [selectedGenre, setSelectedGenre] = useState(null); - const [yearFilter, setYearFilter] = useState('all'); - const [sortOrder, setSortOrder] = useState('default'); - const [selectedSeasons, setSelectedSeasons] = useState([]); - const [selectedTypes, setSelectedTypes] = useState([]); - const [selectedStatus, setSelectedStatus] = useState([]); - const [selectedLanguages, setSelectedLanguages] = useState([]); - const [error, setError] = useState(null); - - // Create filters object for API request - const getFiltersForApi = useCallback(() => { - const filters = {}; - - if (selectedGenre) filters.genre = selectedGenre; - if (yearFilter !== 'all') filters.year = yearFilter; - if (sortOrder !== 'default') filters.sort = sortOrder; - - // Only add these filters if API supports them - // Currently, these may need to be handled client-side - // if (selectedSeasons.length > 0) filters.seasons = selectedSeasons; - // if (selectedTypes.length > 0) filters.types = selectedTypes; - // if (selectedStatus.length > 0) filters.status = selectedStatus; - // if (selectedLanguages.length > 0) filters.languages = selectedLanguages; - - return filters; - }, [selectedGenre, yearFilter, sortOrder]); - - // Apply client-side filters - const applyClientSideFilters = useCallback((animeList) => { - if (!animeList.length) return []; - - let result = [...animeList]; - - // Apply season filter if selected - if (selectedSeasons.length > 0) { - result = result.filter(anime => { - if (!anime.season) return false; - - const animeSeason = typeof anime.season === 'string' - ? anime.season - : anime.season?.name || ''; - - return selectedSeasons.some(season => - animeSeason.toLowerCase().includes(season.toLowerCase()) - ); - }); - } - - // Apply type filter if selected - if (selectedTypes.length > 0) { - result = result.filter(anime => { - if (!anime.type) return false; - - return selectedTypes.some(type => - anime.type.toLowerCase() === type.toLowerCase() - ); - }); - } - - // Apply status filter if selected - if (selectedStatus.length > 0) { - result = result.filter(anime => { - if (!anime.status) return false; - - return selectedStatus.some(status => - anime.status.toLowerCase().includes(status.toLowerCase()) - ); - }); - } - - // Apply language filter if selected - if (selectedLanguages.length > 0) { - result = result.filter(anime => { - // If no language info, assume subbed (most common) - const animeLanguage = anime.language || 'Subbed'; - - return selectedLanguages.some(language => - animeLanguage.toLowerCase().includes(language.toLowerCase()) - ); - }); - } - - // Apply client-side sorting (when API sort is not supported) - if (sortOrder !== 'default') { - switch (sortOrder) { - case 'title-asc': - result.sort((a, b) => (a.title || '').localeCompare(b.title || '')); - break; - case 'title-desc': - result.sort((a, b) => (b.title || '').localeCompare(a.title || '')); - break; - case 'year-desc': - result.sort((a, b) => (parseInt(b.year) || 0) - (parseInt(a.year) || 0)); - break; - case 'year-asc': - result.sort((a, b) => (parseInt(a.year) || 0) - (parseInt(b.year) || 0)); - break; - // Default order from API is used when sortOrder is 'default' - } - } - - return result; - }, [selectedSeasons, selectedTypes, selectedStatus, selectedLanguages, sortOrder]); - - // Fetch popular anime when search is empty - const fetchPopularAnime = useCallback(async (page = 1) => { - setIsLoading(true); - setError(null); - setIsEmptySearch(true); - - try { - const data = await fetchMostPopular(page); - - if (page === 1) { - setSearchResults(data.results || []); - } else { - setSearchResults(prev => [...prev, ...(data.results || [])]); - } - - setHasNextPage(data.hasNextPage || false); - } catch (error) { - console.error('Error fetching popular anime:', error); - setError('Failed to fetch popular anime. Please try again later.'); - } finally { - setIsLoading(false); - } - }, []); - - useEffect(() => { - // If the query param is empty, redirect to search page with empty query - if (!decodedQuery.trim()) { - // Fetch popular anime instead - fetchPopularAnime(currentPage); - return; - } - - setIsEmptySearch(false); - const fetchSearchResults = async () => { - setIsLoading(true); - setError(null); - - try { - const filters = getFiltersForApi(); - const data = await searchAnime(decodedQuery, currentPage, filters); - - if (currentPage === 1) { - setSearchResults(data.results || []); - } else { - setSearchResults(prev => [...prev, ...(data.results || [])]); - } - - setHasNextPage(data.hasNextPage || false); - } catch (error) { - console.error('Error fetching search results:', error); - setError('Failed to search anime. Please try again later.'); - } finally { - setIsLoading(false); - } - }; - - fetchSearchResults(); - }, [decodedQuery, currentPage, getFiltersForApi, fetchPopularAnime]); - - // Apply client-side filters whenever search results or filter settings change - useEffect(() => { - const filteredResults = applyClientSideFilters(searchResults); - setFilteredResults(filteredResults); - }, [searchResults, applyClientSideFilters]); - - const handleLoadMore = () => { - setCurrentPage(prev => prev + 1); - }; - - // Filter handlers - const handleGenreChange = (genre) => { - setSelectedGenre(genre); - if (currentPage !== 1) setCurrentPage(1); - }; - - const handleYearChange = (year) => { - setYearFilter(year); - if (currentPage !== 1) setCurrentPage(1); - }; - - const handleSortChange = (order) => { - setSortOrder(order); - if (currentPage !== 1) setCurrentPage(1); - }; - - const handleSeasonChange = (seasons) => { - setSelectedSeasons(seasons); - if (currentPage !== 1) setCurrentPage(1); - }; - - const handleTypeChange = (types) => { - setSelectedTypes(types); - if (currentPage !== 1) setCurrentPage(1); - }; - - const handleStatusChange = (status) => { - setSelectedStatus(status); - if (currentPage !== 1) setCurrentPage(1); - }; - - const handleLanguageChange = (languages) => { - setSelectedLanguages(languages); - if (currentPage !== 1) setCurrentPage(1); - }; - - return ( -
-
-

- {decodedQuery.trim() ? `Search Results for "${decodedQuery}"` : 'Popular Anime'} -

- - {/* Filters */} - {}} - selectedSeasons={selectedSeasons} - onSeasonChange={handleSeasonChange} - selectedTypes={selectedTypes} - onTypeChange={handleTypeChange} - selectedStatus={selectedStatus} - onStatusChange={handleStatusChange} - selectedLanguages={selectedLanguages} - onLanguageChange={handleLanguageChange} - /> -
- - {isLoading && currentPage === 1 ? ( -
-
-
- ) : error ? ( -
-

Error

-

{error}

-
- ) : filteredResults.length > 0 ? ( - <> -
- {filteredResults.map((anime) => ( - - ))} -
- - {hasNextPage && ( -
- -
- )} - - ) : ( -
-

No results found

-

- We couldn't find any anime matching your search criteria. Please try different filters or a different search term. -

-
- )} -
- ); -} \ No newline at end of file diff --git a/src/app/search/layout.js b/src/app/search/layout.js deleted file mode 100644 index f44e019..0000000 --- a/src/app/search/layout.js +++ /dev/null @@ -1,5 +0,0 @@ -import SharedLayout from '@/components/SharedLayout'; - -export default function SearchLayout({ children }) { - return {children}; -} \ No newline at end of file diff --git a/src/app/search/page.js b/src/app/search/page.js deleted file mode 100644 index dd5d63f..0000000 --- a/src/app/search/page.js +++ /dev/null @@ -1,433 +0,0 @@ -'use client'; - -import { useState, useEffect, useCallback, Suspense } from 'react'; -import { useSearchParams } from 'next/navigation'; -import { searchAnime, fetchMostPopular } from '@/lib/api'; -import AnimeCard from '@/components/AnimeCard'; -import AnimeFilters from '@/components/AnimeFilters'; - -function SearchResults() { - const searchParams = useSearchParams(); - const queryTerm = searchParams.get('q') || ''; - const genreParam = searchParams.get('genre') || null; - - const [animeList, setAnimeList] = useState([]); - const [filteredList, setFilteredList] = useState([]); - const [isLoading, setIsLoading] = useState(true); - const [currentPage, setCurrentPage] = useState(1); - const [hasNextPage, setHasNextPage] = useState(false); - const [selectedGenre, setSelectedGenre] = useState(genreParam); - const [yearFilter, setYearFilter] = useState('all'); - const [sortOrder, setSortOrder] = useState('default'); - const [selectedSeasons, setSelectedSeasons] = useState([]); - const [selectedTypes, setSelectedTypes] = useState([]); - const [selectedStatus, setSelectedStatus] = useState([]); - const [selectedLanguages, setSelectedLanguages] = useState([]); - const [error, setError] = useState(null); - const [isEmptySearch, setIsEmptySearch] = useState(false); - - // Current year for filtering - const currentYear = new Date().getFullYear(); - - // Process and augment anime data to ensure all items have year information - const processAnimeData = useCallback((animeData) => { - if (!animeData || !animeData.results) return animeData; - - // Create a copy of the data to avoid mutating the original - const processedData = { - ...animeData, - results: animeData.results.map(anime => { - const processed = { ...anime }; - - // Extract or estimate year from various properties - // Fallback to randomized year range between 2000-current year if no year data available - if (!processed.year) { - if (processed.releaseDate && !isNaN(parseInt(processed.releaseDate))) { - processed.year = parseInt(processed.releaseDate); - } else if (processed.date && !isNaN(parseInt(processed.date))) { - processed.year = parseInt(processed.date); - } else { - // Assign a semi-random year based on anime ID to ensure consistency - const hash = processed.id.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0); - processed.year = 2000 + (hash % (currentYear - 2000 + 1)); - } - } - - return processed; - }) - }; - - return processedData; - }, [currentYear]); - - // Create filters object for API request - const getFiltersForApi = useCallback(() => { - const filters = {}; - - if (selectedGenre) filters.genre = selectedGenre; - if (yearFilter !== 'all') filters.year = yearFilter; - if (sortOrder !== 'default') filters.sort = sortOrder; - - // Support all client-side filters in API call when possible - if (selectedSeasons.length > 0) filters.season = selectedSeasons.join(','); - if (selectedTypes.length > 0) filters.type = selectedTypes.join(','); - if (selectedStatus.length > 0) filters.status = selectedStatus.join(','); - if (selectedLanguages.length > 0) filters.language = selectedLanguages.join(','); - - return filters; - }, [selectedGenre, yearFilter, sortOrder, selectedSeasons, selectedTypes, selectedStatus, selectedLanguages]); - - // Apply client-side filters for things not supported by API - const applyClientSideFilters = useCallback((animeList) => { - if (!animeList.length) return []; - - let result = [...animeList]; - - // Apply season filter if selected - if (selectedSeasons.length > 0) { - result = result.filter(anime => { - if (!anime.season) return false; - - const animeSeason = typeof anime.season === 'string' - ? anime.season - : anime.season?.name || ''; - - return selectedSeasons.some(season => - animeSeason.toLowerCase().includes(season.toLowerCase()) - ); - }); - } - - // Apply type filter if selected - if (selectedTypes.length > 0) { - result = result.filter(anime => { - if (!anime.type) return false; - - return selectedTypes.some(type => - anime.type.toLowerCase() === type.toLowerCase() - ); - }); - } - - // Apply status filter if selected - if (selectedStatus.length > 0) { - result = result.filter(anime => { - if (!anime.status) return false; - - return selectedStatus.some(status => - anime.status.toLowerCase().includes(status.toLowerCase()) - ); - }); - } - - // Apply language filter if selected - if (selectedLanguages.length > 0) { - result = result.filter(anime => { - // If no language info, assume subbed (most common) - const animeLanguage = anime.language || 'Subbed'; - - return selectedLanguages.some(language => - animeLanguage.toLowerCase().includes(language.toLowerCase()) - ); - }); - } - - // Apply client-side sorting (when API sort is not supported) - if (sortOrder !== 'default') { - switch (sortOrder) { - case 'title-asc': - result.sort((a, b) => (a.title || '').localeCompare(b.title || '')); - break; - case 'title-desc': - result.sort((a, b) => (b.title || '').localeCompare(a.title || '')); - break; - case 'year-desc': - result.sort((a, b) => (parseInt(b.year) || 0) - (parseInt(a.year) || 0)); - break; - case 'year-asc': - result.sort((a, b) => (parseInt(a.year) || 0) - (parseInt(b.year) || 0)); - break; - // Default order from API is used when sortOrder is 'default' - } - } - - return result; - }, [selectedSeasons, selectedTypes, selectedStatus, selectedLanguages, sortOrder]); - - // Fetch most popular anime when search is empty - const fetchPopularAnime = useCallback(async () => { - setIsLoading(true); - setError(null); - setIsEmptySearch(true); - - try { - const data = await fetchMostPopular(1); - const processedData = processAnimeData(data); - - const results = processedData.results || []; - setAnimeList(results); - - // Apply client-side filters - const filteredResults = applyClientSideFilters(results); - setFilteredList(filteredResults); - - setHasNextPage(processedData.hasNextPage || false); - } catch (error) { - console.error('Error fetching popular anime:', error); - setError('Failed to fetch popular anime. Please try again later.'); - setAnimeList([]); - setFilteredList([]); - } finally { - setIsLoading(false); - } - }, [processAnimeData, applyClientSideFilters]); - - // Fetch data from API when search term or main filters change - useEffect(() => { - const fetchData = async () => { - if (!queryTerm.trim()) { - // Show popular anime instead of empty results - fetchPopularAnime(); - return; - } - - setIsLoading(true); - setError(null); - setCurrentPage(1); - setIsEmptySearch(false); - - try { - const filters = getFiltersForApi(); - console.log(`[Search] Searching for: "${queryTerm}" with filters:`, filters); - - const data = await searchAnime(queryTerm, 1, filters); - - // If no results but no error was thrown, show empty state - if (!data || (!data.results || data.results.length === 0)) { - console.log('[Search] No results found for search term:', queryTerm); - setError(`No results found for "${queryTerm}"`); - setAnimeList([]); - setFilteredList([]); - setIsLoading(false); - return; - } - - const processedData = processAnimeData(data); - const results = processedData.results || []; - setAnimeList(results); - - // Only apply client-side filters for things not supported by API - const filteredResults = applyClientSideFilters(results); - setFilteredList(filteredResults); - - setHasNextPage(processedData.hasNextPage || false); - } catch (error) { - console.error('[Search] Error searching anime:', error); - setError('Failed to search anime. Please try again later or check your internet connection.'); - setAnimeList([]); - setFilteredList([]); - } finally { - setIsLoading(false); - } - }; - - fetchData(); - }, [queryTerm, getFiltersForApi, processAnimeData, applyClientSideFilters, fetchPopularAnime]); - - // Handle pagination - useEffect(() => { - // Skip if it's the first page (already fetched in the previous effect) - // or if no search term is provided - if (currentPage === 1) { - return; - } - - const loadMoreData = async () => { - setIsLoading(true); - - try { - // If it's an empty search query, load more popular anime - if (isEmptySearch) { - const data = await fetchMostPopular(currentPage); - const processedData = processAnimeData(data); - - const newResults = processedData.results || []; - setAnimeList(prev => [...prev, ...newResults]); - - // Apply client-side filters to new results - const filteredNewResults = applyClientSideFilters(newResults); - setFilteredList(prev => [...prev, ...filteredNewResults]); - - setHasNextPage(processedData.hasNextPage || false); - } else { - // For search results, include filters - const filters = getFiltersForApi(); - const data = await searchAnime(queryTerm, currentPage, filters); - const processedData = processAnimeData(data); - - const newResults = processedData.results || []; - setAnimeList(prev => [...prev, ...newResults]); - - // Only apply client-side filters for things not supported by API - const filteredNewResults = applyClientSideFilters(newResults); - setFilteredList(prev => [...prev, ...filteredNewResults]); - - setHasNextPage(processedData.hasNextPage || false); - } - } catch (error) { - console.error('Error loading more anime:', error); - setError('Failed to load more results. Please try again later.'); - } finally { - setIsLoading(false); - } - }; - - loadMoreData(); - }, [currentPage, queryTerm, isEmptySearch, getFiltersForApi, processAnimeData, applyClientSideFilters]); - - // Re-apply client-side filters when filters change but don't need API refetch - useEffect(() => { - const applyFilters = () => { - const filteredResults = applyClientSideFilters(animeList); - setFilteredList(filteredResults); - }; - - applyFilters(); - }, [selectedSeasons, selectedTypes, selectedStatus, selectedLanguages, animeList, applyClientSideFilters]); - - const handleLoadMore = () => { - setCurrentPage(prev => prev + 1); - }; - - const handleGenreChange = (genre) => { - setSelectedGenre(genre); - if (currentPage !== 1) setCurrentPage(1); - }; - - const handleYearChange = (year) => { - setYearFilter(year); - if (currentPage !== 1) setCurrentPage(1); - }; - - const handleSortChange = (order) => { - setSortOrder(order); - if (currentPage !== 1) setCurrentPage(1); - }; - - const handleSeasonChange = (seasons) => { - setSelectedSeasons(seasons); - if (currentPage !== 1) setCurrentPage(1); - }; - - const handleTypeChange = (types) => { - setSelectedTypes(types); - if (currentPage !== 1) setCurrentPage(1); - }; - - const handleStatusChange = (status) => { - setSelectedStatus(status); - if (currentPage !== 1) setCurrentPage(1); - }; - - const handleLanguageChange = (languages) => { - setSelectedLanguages(languages); - if (currentPage !== 1) setCurrentPage(1); - }; - - return ( -
- {/* Horizontal filters at the top */} -
- {}} - selectedSeasons={selectedSeasons} - onSeasonChange={handleSeasonChange} - selectedTypes={selectedTypes} - onTypeChange={handleTypeChange} - selectedStatus={selectedStatus} - onStatusChange={handleStatusChange} - selectedLanguages={selectedLanguages} - onLanguageChange={handleLanguageChange} - /> -
- - {/* Main content */} -
-
-

- {queryTerm ? `Results for "${queryTerm}"` : 'Popular Anime'} -

-
- {filteredList.length > 0 && ( - {filteredList.length} {filteredList.length === 1 ? 'result' : 'results'} - )} -
-
- - {error ? ( -
-

{error}

-
- ) : isLoading && currentPage === 1 ? ( -
- {/* Loading skeleton */} - {[...Array(24)].map((_, index) => ( -
- ))} -
- ) : filteredList.length === 0 ? ( -
-

No anime found matching your filters.

-
- ) : ( - <> -
- {filteredList.map((anime) => ( - - ))} -
- - {/* Load more button */} - {hasNextPage && ( -
- -
- )} - - )} -
-
- ); -} - -export default function SearchPage() { - return ( - Loading...}> - - - ); -} \ No newline at end of file diff --git a/src/app/terms-and-services/page.jsx b/src/app/terms-and-services/page.jsx deleted file mode 100644 index 3b80de2..0000000 --- a/src/app/terms-and-services/page.jsx +++ /dev/null @@ -1,191 +0,0 @@ -'use client'; - -import SharedLayout from '@/components/SharedLayout'; - -export default function TermsPage() { - return ( - -
-

Terms of Service & Privacy Policy

- -
-
-

Terms of Service

- -
-
-

1. Acceptance of Terms

-

- By accessing and using JustAnime, you acknowledge that you have read, understood, and agree to be bound by these Terms of Service. - If you do not agree with any part of these terms, you may not use our services. -

-
- -
-

2. Service Description

-

- JustAnime is a platform that provides information and links to anime content. - We do not host, upload, or distribute any content directly. - Our service aggregates links to third-party websites and services that host the actual content. -

-
- -
-

3. User Conduct

-

- Users of JustAnime agree not to: -

-
    -
  • Use our service for any illegal purpose or in violation of any local, state, national, or international law
  • -
  • Harass, abuse, or harm another person
  • -
  • Interfere with or disrupt the service or servers connected to the service
  • -
  • Create multiple accounts for disruptive or abusive purposes
  • -
  • Attempt to access any portion of the service that you are not authorized to access
  • -
-
- -
-

4. Content Disclaimer

-

- JustAnime does not host any content on its servers. We are not responsible for the content, accuracy, or practices of third-party websites that our service may link to. - These links are provided solely as a convenience to users, and we do not endorse the content of such third-party sites. -

-
- -
-

5. Intellectual Property

-

- All trademarks, logos, service marks, and trade names are the property of their respective owners. - JustAnime respects intellectual property rights and expects users to do the same. - If you believe content linked through our service infringes on your copyright, please contact us with details. -

-
- -
-

6. Modification of Terms

-

- JustAnime reserves the right to modify these Terms of Service at any time. - We will provide notice of significant changes through our website. - Your continued use of our service after such modifications constitutes your acceptance of the updated terms. -

-
- -
-

7. Termination

-

- JustAnime reserves the right to terminate or suspend your access to our service at any time, without prior notice or liability, for any reason whatsoever, including without limitation if you breach these Terms of Service. -

-
-
-
- -
-

Privacy Policy

- -
-
-

1. Information We Collect

-

- JustAnime collects the following types of information: -

-
    -
  • Information you provide: We may collect personal information such as your email address when you sign up for an account or contact us.
  • -
  • Usage data: We automatically collect information about your interactions with our service, including the pages you visit and your preferences.
  • -
  • Device information: We collect information about your device and internet connection, including IP address, browser type, and operating system.
  • -
-
- -
-

2. How We Use Your Information

-

- We use the information we collect to: -

-
    -
  • Provide, maintain, and improve our service
  • -
  • Communicate with you about updates, support, and features
  • -
  • Monitor and analyze usage patterns and trends
  • -
  • Protect against, identify, and prevent fraud and other illegal activity
  • -
  • Comply with legal obligations
  • -
-
- -
-

3. Cookies and Similar Technologies

-

- JustAnime uses cookies and similar tracking technologies to track activity on our service and hold certain information. - Cookies are files with a small amount of data that may include an anonymous unique identifier. - You can instruct your browser to refuse all cookies or to indicate when a cookie is being sent. -

-
- -
-

4. Data Sharing and Disclosure

-

- We may share your information in the following circumstances: -

-
    -
  • With service providers who perform services on our behalf
  • -
  • To comply with legal obligations
  • -
  • To protect the rights, property, or safety of JustAnime, our users, or others
  • -
  • In connection with a business transfer, such as a merger or acquisition
  • -
-
- -
-

5. Data Security

-

- JustAnime takes reasonable measures to protect your information from unauthorized access, alteration, disclosure, or destruction. - However, no method of transmission over the Internet or electronic storage is 100% secure, and we cannot guarantee absolute security. -

-
- -
-

6. Your Rights

-

- Depending on your location, you may have certain rights regarding your personal data, including: -

-
    -
  • The right to access and receive a copy of your data
  • -
  • The right to rectify or update your data
  • -
  • The right to delete your data
  • -
  • The right to restrict processing of your data
  • -
  • The right to object to processing of your data
  • -
  • The right to data portability
  • -
-

- To exercise these rights, please contact us at privacy@justanime.com. -

-
- -
-

7. Children's Privacy

-

- JustAnime does not knowingly collect personal information from children under 13. - If you are a parent or guardian and you believe your child has provided us with personal information, please contact us. -

-
- -
-

8. Changes to This Privacy Policy

-

- We may update our Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on this page and updating the "Last Updated" date. -

-
- -
-

9. Contact Us

-

- If you have any questions about this Privacy Policy, please contact us at privacy@justanime.com. -

-
- -
-

Last Updated: May 5, 2024

-
-
-
-
-
-
- ); -} \ No newline at end of file diff --git a/src/app/top-airing/layout.js b/src/app/top-airing/layout.js deleted file mode 100644 index a55c076..0000000 --- a/src/app/top-airing/layout.js +++ /dev/null @@ -1,5 +0,0 @@ -import SharedLayout from '@/components/SharedLayout'; - -export default function TopAiringLayout({ children }) { - return {children}; -} \ No newline at end of file diff --git a/src/app/top-airing/page.js b/src/app/top-airing/page.js deleted file mode 100644 index afff6f5..0000000 --- a/src/app/top-airing/page.js +++ /dev/null @@ -1,276 +0,0 @@ -'use client'; - -import { useState, useEffect, useRef } from 'react'; -import AnimeCard from '@/components/AnimeCard'; -import AnimeFilters from '@/components/AnimeFilters'; -import { fetchTopAiring } from '@/lib/api'; - -export default function TopAiringPage() { - const [animeList, setAnimeList] = useState([]); - const [filteredList, setFilteredList] = useState([]); - const [isLoading, setIsLoading] = useState(true); - const [currentPage, setCurrentPage] = useState(1); - const [hasNextPage, setHasNextPage] = useState(false); - const [selectedGenre, setSelectedGenre] = useState(null); - const [yearFilter, setYearFilter] = useState('all'); - const [sortOrder, setSortOrder] = useState('default'); - const [searchQuery, setSearchQuery] = useState(''); - const [selectedSeasons, setSelectedSeasons] = useState([]); - const [selectedTypes, setSelectedTypes] = useState([]); - const [selectedStatus, setSelectedStatus] = useState([]); - const [selectedLanguages, setSelectedLanguages] = useState([]); - const [error, setError] = useState(null); - - // Current year for filtering - const currentYear = new Date().getFullYear(); - - // Add ref to track if this is the first render - const initialRender = useRef(true); - - useEffect(() => { - const fetchData = async () => { - setIsLoading(true); - try { - const data = await fetchTopAiring(currentPage); - - if (currentPage === 1) { - setAnimeList(data.results || []); - } else { - setAnimeList(prev => [...prev, ...(data.results || [])]); - } - - setHasNextPage(data.hasNextPage || false); - } catch (error) { - console.error('Error fetching top airing anime:', error); - setError('Failed to load anime. Please try again later.'); - } finally { - setIsLoading(false); - } - }; - - fetchData(); - }, [currentPage]); - - // Apply filters and sorting whenever the anime list or filter settings change - useEffect(() => { - // Skip the initial render effect to avoid duplicate filtering - if (initialRender.current) { - initialRender.current = false; - return; - } - - if (!animeList.length) { - setFilteredList([]); - return; - } - - let result = [...animeList]; - - // Search filter - if (searchQuery && searchQuery.trim() !== '') { - const query = searchQuery.toLowerCase().trim(); - result = result.filter(anime => { - const title = (anime.title || '').toLowerCase(); - const otherNames = (anime.otherNames || '').toLowerCase(); - return title.includes(query) || otherNames.includes(query); - }); - } - - // Filter by genre if selected - if (selectedGenre) { - result = result.filter(anime => { - if (anime.genres && Array.isArray(anime.genres)) { - return anime.genres.some(g => - g.toLowerCase() === selectedGenre.toLowerCase() || - (g.name && g.name.toLowerCase() === selectedGenre.toLowerCase()) - ); - } else if (anime.genre) { - return anime.genre.toLowerCase().includes(selectedGenre.toLowerCase()); - } - return false; - }); - } - - // Filter by season - if (selectedSeasons.length > 0) { - result = result.filter(anime => { - const season = getAnimeSeason(anime); - return selectedSeasons.includes(season); - }); - } - - // Filter by year - if (yearFilter !== 'all') { - result = result.filter(anime => { - const animeYear = parseInt(anime.year) || 0; - if (yearFilter === 'older') { - return animeYear < 2000; - } else { - return animeYear.toString() === yearFilter; - } - }); - } - - // Filter by type - if (selectedTypes.length > 0) { - result = result.filter(anime => - selectedTypes.includes(anime.type) - ); - } - - // Filter by status - if (selectedStatus.length > 0) { - result = result.filter(anime => { - const status = anime.status || getDefaultStatus(anime); - return selectedStatus.includes(status); - }); - } - - // Filter by language - if (selectedLanguages.length > 0) { - result = result.filter(anime => { - const language = anime.language || getDefaultLanguage(anime); - return selectedLanguages.includes(language); - }); - } - - // Apply sorting - switch (sortOrder) { - case 'title-asc': - result.sort((a, b) => (a.title || '').localeCompare(b.title || '')); - break; - case 'title-desc': - result.sort((a, b) => (b.title || '').localeCompare(a.title || '')); - break; - case 'year-desc': - result.sort((a, b) => (parseInt(b.year) || 0) - (parseInt(a.year) || 0)); - break; - case 'year-asc': - result.sort((a, b) => (parseInt(a.year) || 0) - (parseInt(b.year) || 0)); - break; - default: - // Default order from API - break; - } - - setFilteredList(result); - }, [animeList, selectedGenre, yearFilter, sortOrder, searchQuery, selectedSeasons, selectedTypes, selectedStatus, selectedLanguages]); - - const handleLoadMore = () => { - setCurrentPage(prev => prev + 1); - }; - - const handleGenreChange = (genre) => { - setSelectedGenre(genre); - }; - - const handleYearChange = (year) => { - setYearFilter(year); - }; - - const handleSortChange = (order) => { - setSortOrder(order); - }; - - const handleSearchChange = (value) => { - setSearchQuery(value); - }; - - const handleSeasonChange = (seasons) => { - setSelectedSeasons(seasons); - }; - - const handleTypeChange = (types) => { - setSelectedTypes(types); - }; - - const handleStatusChange = (status) => { - setSelectedStatus(status); - }; - - const handleLanguageChange = (languages) => { - setSelectedLanguages(languages); - }; - - return ( -
-

Top Airing Anime

- - {/* Filters */} -
- -
- - {isLoading && animeList.length === 0 ? ( -
- {[...Array(14)].map((_, index) => ( -
-
-
-
-
-
-
- ))} -
- ) : (filteredList.length > 0 || animeList.length > 0) ? ( - <> -
- {(filteredList.length > 0 ? filteredList : animeList).map((anime) => ( - - ))} -
- - {hasNextPage && ( -
- -
- )} - - ) : ( -
-

No anime found

-

- We couldn't find any top airing anime at this time. Please check back later. -

-
- )} -
- ); -} \ No newline at end of file diff --git a/src/app/watch/[episodeId]/page.js b/src/app/watch/[episodeId]/page.js deleted file mode 100644 index a2a9d7c..0000000 --- a/src/app/watch/[episodeId]/page.js +++ /dev/null @@ -1,664 +0,0 @@ -'use client'; - -import { useState, useEffect } from 'react'; -import { useParams, useRouter, usePathname, useSearchParams } from 'next/navigation'; -import Link from 'next/link'; -import Image from 'next/image'; -import VideoPlayer from '@/components/VideoPlayer'; -import EpisodeList from '@/components/EpisodeList'; -import { - fetchEpisodeSources, - fetchAnimeInfo, - fetchEpisodeServers, - fetchAnimeEpisodes -} from '@/lib/api'; - -export default function WatchPage() { - const { episodeId } = useParams(); - const router = useRouter(); - const pathname = usePathname(); - const [videoSource, setVideoSource] = useState(null); - const [anime, setAnime] = useState(null); - const [currentEpisode, setCurrentEpisode] = useState(null); - const [isDub, setIsDub] = useState(false); - const [isLoading, setIsLoading] = useState(true); - const [error, setError] = useState(null); - const [videoHeaders, setVideoHeaders] = useState({}); - const [subtitles, setSubtitles] = useState([]); - const [thumbnails, setThumbnails] = useState(null); - const [animeId, setAnimeId] = useState(null); - const [episodeData, setEpisodeData] = useState(null); - const [isRetrying, setIsRetrying] = useState(false); - const [currentPage, setCurrentPage] = useState(1); - const episodesPerPage = 100; - const [showFullSynopsis, setShowFullSynopsis] = useState(false); - const [autoSkip, setAutoSkip] = useState(false); - const [currentEpisodeId, setCurrentEpisodeId] = useState(episodeId); - const [availableServers, setAvailableServers] = useState([]); - const [selectedServer, setSelectedServer] = useState('hd-2'); - const [episodes, setEpisodes] = useState([]); - - // Handle URL updates when currentEpisodeId changes - useEffect(() => { - if (currentEpisodeId && currentEpisodeId !== episodeId) { - const newUrl = `/watch/${currentEpisodeId}`; - window.history.pushState({ episodeId: currentEpisodeId }, '', newUrl); - } - }, [currentEpisodeId, episodeId]); - - // Listen for popstate (browser back/forward) events - useEffect(() => { - const handlePopState = (event) => { - const path = window.location.pathname; - const match = path.match(/\/watch\/(.+)$/); - if (match) { - const newEpisodeId = match[1]; - setCurrentEpisodeId(newEpisodeId); - } - }; - - window.addEventListener('popstate', handlePopState); - return () => window.removeEventListener('popstate', handlePopState); - }, []); - - // Extract animeId from the URL - useEffect(() => { - if (episodeId) { - // Log the raw episodeId from the URL for debugging - console.log('[Watch] Raw episodeId from URL:', episodeId); - - // Extract animeId from the episodeId parameter - // The API response contains episode.id in the format "anime-id?ep=episode-number" - let extractedAnimeId = episodeId; - - // If the ID contains a query parameter, extract just the anime ID - if (episodeId.includes('?')) { - extractedAnimeId = episodeId.split('?')[0]; - } - - setAnimeId(extractedAnimeId); - console.log('[Watch] Extracted anime ID:', extractedAnimeId); - - setCurrentEpisodeId(episodeId); - } - }, [episodeId]); - - // First fetch episode servers to get available servers and subtitles - useEffect(() => { - if (!currentEpisodeId || currentEpisodeId === 'undefined') { - setError('Invalid episode ID'); - setIsLoading(false); - return; - } - - const fetchServers = async () => { - setIsLoading(true); - - try { - console.log(`[Watch] Fetching servers for episode ${currentEpisodeId}`); - - // Fetch available servers from the API - const data = await fetchEpisodeServers(currentEpisodeId); - - if (!data || !data.servers || data.servers.length === 0) { - console.warn('[Watch] No servers available for this episode'); - } else { - // Filter servers based on current audio preference (sub/dub) - const filteredServers = data.servers.filter(server => - server.category === (isDub ? 'dub' : 'sub') - ); - - setAvailableServers(filteredServers); - console.log(`[Watch] Available ${isDub ? 'dub' : 'sub'} servers:`, filteredServers); - - // Set default server if available - // First try to find HD-1 server - let preferredServer = filteredServers.find(server => - server.serverName && server.serverName.toLowerCase() === 'hd-2' - ); - - // If not found, look for vidstreaming - if (!preferredServer) { - preferredServer = filteredServers.find(server => - server.serverName && server.serverName.toLowerCase().includes('vidstreaming') - ); - } - - if (preferredServer && preferredServer.serverName) { - setSelectedServer(preferredServer.serverName.toLowerCase()); - console.log(`[Watch] Selected preferred server: ${preferredServer.serverName}`); - } else if (filteredServers.length > 0 && filteredServers[0].serverName) { - setSelectedServer(filteredServers[0].serverName.toLowerCase()); - console.log(`[Watch] Selected first available server: ${filteredServers[0].serverName}`); - } - } - - // Continue to fetch video sources with the selected server - fetchVideoSources(currentEpisodeId, isDub, selectedServer); - - } catch (error) { - console.error('[Watch] Error fetching episode servers:', error); - // Continue to sources even if servers fail - fetchVideoSources(currentEpisodeId, isDub, selectedServer); - } - }; - - fetchServers(); - }, [currentEpisodeId, isDub]); - - // Fetch video sources function - const fetchVideoSources = async (episodeId, dub, server) => { - setIsLoading(true); - setError(null); - setVideoSource(null); - - try { - console.log(`[Watch] Fetching video for episode ${episodeId} (dub: ${dub}, server: ${server})`); - - // Fetch the episode sources from the API - const data = await fetchEpisodeSources(episodeId, dub, server); - - console.log('[Watch] Episode sources API response:', data); - setEpisodeData(data); - - if (!data || !data.sources || data.sources.length === 0) { - throw new Error('No video sources available for this episode'); - } - - // Extract headers if they exist in the response - if (data.headers) { - console.log('[Watch] Headers from API:', data.headers); - setVideoHeaders(data.headers); - } else { - // Set default headers if none provided - const defaultHeaders = { - "Referer": "https://hianime.to/", - "Origin": "https://hianime.to" - }; - setVideoHeaders(defaultHeaders); - } - - // Set subtitles if available in the sources response - // Check both subtitles and tracks fields since API might return either - const subtitleData = data.subtitles || data.tracks || []; - if (subtitleData.length > 0) { - // Filter out thumbnails from subtitles array - const filteredSubtitles = subtitleData.filter(sub => - sub.lang && sub.lang.toLowerCase() !== 'thumbnails' - ); - - // Look for thumbnails separately - const thumbnailTrack = subtitleData.find(sub => - sub.lang && sub.lang.toLowerCase() === 'thumbnails' - ); - - if (thumbnailTrack && thumbnailTrack.url) { - console.log('[Watch] Found thumbnails track:', thumbnailTrack.url); - setThumbnails(thumbnailTrack.url); - } - - if (filteredSubtitles.length > 0) { - console.log('[Watch] Found subtitles:', filteredSubtitles.length); - setSubtitles(filteredSubtitles); - } - } - - // Try to find the best source in order of preference - // 1. HLS (m3u8) sources - // 2. High quality MP4 sources - const hlsSource = data.sources.find(src => src.isM3U8); - const mp4Source = data.sources.find(src => !src.isM3U8); - - let selectedSource = null; - - if (hlsSource && hlsSource.url) { - console.log('[Watch] Selected HLS source:', hlsSource.url); - selectedSource = hlsSource.url; - } else if (mp4Source && mp4Source.url) { - console.log('[Watch] Selected MP4 source:', mp4Source.url); - selectedSource = mp4Source.url; - } else if (data.sources[0] && data.sources[0].url) { - console.log('[Watch] Falling back to first available source:', data.sources[0].url); - selectedSource = data.sources[0].url; - } else { - throw new Error('No valid video URLs found'); - } - - setVideoSource(selectedSource); - setIsLoading(false); - - } catch (error) { - console.error('[Watch] Error fetching video sources:', error); - setError(error.message || 'Failed to load video'); - setIsLoading(false); - - // If this is the first try, attempt to retry once - if (!isRetrying) { - console.log('[Watch] First error, attempting retry...'); - setIsRetrying(true); - setTimeout(() => { - console.log('[Watch] Executing retry...'); - fetchVideoSources(episodeId, dub, server); - }, 2000); - } - } - }; - - // Effect to refetch sources when server or dub changes - useEffect(() => { - if (currentEpisodeId && selectedServer) { - fetchVideoSources(currentEpisodeId, isDub, selectedServer); - } - }, [selectedServer, isDub]); - - // Fetch anime info and episodes using animeId - useEffect(() => { - if (animeId) { - const fetchAnimeDetails = async () => { - try { - setIsRetrying(true); - console.log(`[Watch] Fetching anime info for ID: ${animeId}`); - - // Fetch basic anime info - const animeData = await fetchAnimeInfo(animeId); - if (animeData) { - console.log('[Watch] Anime info received:', animeData.info?.name); - setAnime({ - id: animeId, - title: animeData.info?.name || 'Unknown Anime', - image: animeData.info?.poster || '', - description: animeData.info?.description || 'No description available', - status: animeData.moreInfo?.status || 'Unknown', - type: animeData.info?.stats?.type || 'TV', - totalEpisodes: animeData.info?.stats?.episodes?.sub || 0, - genres: animeData.moreInfo?.genres || [] - }); - } - - // Fetch episodes separately - const episodesData = await fetchAnimeEpisodes(animeId); - if (episodesData && episodesData.episodes && episodesData.episodes.length > 0) { - console.log('[Watch] Episodes found:', episodesData.episodes.length); - setEpisodes(episodesData.episodes); - - // Find current episode in episode list - const findCurrentEpisode = () => { - // Find the episode by direct ID match - const directMatch = episodesData.episodes.find(ep => ep.id === currentEpisodeId); - if (directMatch) { - console.log('[Watch] Found episode by direct ID match:', directMatch.number); - return directMatch; - } - - // If no match found, return first episode as fallback - console.warn('[Watch] Could not find matching episode, falling back to first episode'); - return episodesData.episodes[0]; - }; - - const episode = findCurrentEpisode(); - if (episode) { - setCurrentEpisode(episode); - console.log('[Watch] Current episode found:', episode.number); - } else { - console.warn('[Watch] Current episode not found in episode list'); - } - } else { - console.warn('[Watch] No episodes found for this anime'); - } - } catch (error) { - console.error('[Watch] Error fetching anime details:', error); - } finally { - setIsRetrying(false); - } - }; - - fetchAnimeDetails(); - } - }, [animeId, currentEpisodeId]); - - const handleDubToggle = () => { - setIsDub(prev => { - const newDubState = !prev; - // Refetch servers for the new audio type - fetchEpisodeServers(currentEpisodeId).then(data => { - if (data && data.servers && data.servers.length > 0) { - // Filter servers based on new audio preference - const filteredServers = data.servers.filter(server => - server.category === (newDubState ? 'dub' : 'sub') - ); - - setAvailableServers(filteredServers); - - // Update selected server if needed - // First try to find HD-1 server - let preferredServer = filteredServers.find(server => - server.serverName && server.serverName.toLowerCase() === 'hd-2' - ); - - // If not found, look for vidstreaming - if (!preferredServer) { - preferredServer = filteredServers.find(server => - server.serverName && server.serverName.toLowerCase().includes('vidstreaming') - ); - } - - if (preferredServer && preferredServer.serverName) { - setSelectedServer(preferredServer.serverName.toLowerCase()); - console.log(`[Watch] Selected preferred server: ${preferredServer.serverName}`); - } else if (filteredServers.length > 0 && filteredServers[0].serverName) { - setSelectedServer(filteredServers[0].serverName.toLowerCase()); - console.log(`[Watch] Selected first available server: ${filteredServers[0].serverName}`); - } - } - }); - return newDubState; - }); - }; - - const handleServerChange = (server) => { - setSelectedServer(server); - }; - - const handleEpisodeClick = (newEpisodeId) => { - if (newEpisodeId !== currentEpisodeId) { - console.log(`[Watch] Episode clicked, ID: ${newEpisodeId}`); - - // Use the episode ID directly as it should already be in the correct format - // from the API response (animeId?ep=episodeNumber) - - // Update the URL using history API - const newUrl = `/watch/${newEpisodeId}`; - window.history.pushState({ episodeId: newEpisodeId }, '', newUrl); - - // Update state to trigger video reload - setCurrentEpisodeId(newEpisodeId); - - // Update current episode in state - if (episodes) { - const newEpisode = episodes.find(ep => ep.id === newEpisodeId); - if (newEpisode) { - setCurrentEpisode(newEpisode); - } - } - } - }; - - const findAdjacentEpisodes = () => { - if (!episodes || !currentEpisode) return { prev: null, next: null }; - - const currentIndex = episodes.findIndex(ep => ep.number === currentEpisode.number); - if (currentIndex === -1) return { prev: null, next: null }; - - return { - prev: currentIndex > 0 ? episodes[currentIndex - 1] : null, - next: currentIndex < episodes.length - 1 ? episodes[currentIndex + 1] : null - }; - }; - - const { prev, next } = findAdjacentEpisodes(); - - return ( -
-
-
- {/* Left Side - Video Player (70%) */} -
-
- {/* Video Player Container */} -
-
-
- {error ? ( -
-
Error: {error}
-

- The video source couldn't be loaded. Please try again or check back later. -

-
- ) : isLoading ? ( -
-
-
Loading video...
-
- ) : videoSource ? ( -
- -
- ) : ( -
-
No video source available
-

- Please try again or check back later. -

-
- )} -
-
-
- - {/* Video Controls - Slimmer and without container background */} -
- {/* Audio and Playback Controls */} -
- {/* Playback Settings */} -
-

Playback Settings

-
- {/* Auto Skip Checkbox */} - {(episodeData?.intro || episodeData?.outro) && ( - - )} -
-
- - {/* Server Selection */} - {availableServers.length > 0 && ( -
-

Servers

-
- {availableServers.map((server) => - server.serverName ? ( - - ) : null - )} -
-
- )} - - {/* Audio Toggle */} -
-

Audio

-
- - -
-
-
- - {/* Episode Navigation */} -
- {episodes && episodes.length > 0 && ( - <> - - - - )} -
-
- - {/* Anime Info Section */} - {anime && ( -
-
- {/* Cover Image */} -
-
- {anime.title} -
-
- - {/* Details */} -
- -

- {anime.title} -

- - - {/* Status Bar */} -
- {anime.status} - - {anime.type} - - {anime.totalEpisodes} Episodes -
- - {/* Synopsis Section */} -
-

Synopsis

-
-
- {anime.description} -
- -
-
- - {/* Genres */} - {anime.genres && ( -
- {anime.genres.map((genre, index) => ( - - {genre} - - ))} -
- )} -
-
-
- )} -
-
- - {/* Right Side - Episode List (30%) */} -
- {episodes && episodes.length > 0 ? ( -
- -
- ) : ( -
-
- {isLoading ? 'Loading episodes...' : 'No episodes available'} -
-
- )} -
-
-
-
- ); -} \ No newline at end of file diff --git a/src/app/watch/layout.js b/src/app/watch/layout.js deleted file mode 100644 index 3fca793..0000000 --- a/src/app/watch/layout.js +++ /dev/null @@ -1,5 +0,0 @@ -import SharedLayout from '@/components/SharedLayout'; - -export default function WatchLayout({ children }) { - return {children}; -} \ No newline at end of file diff --git a/src/components/AnimeCalendar.js b/src/components/AnimeCalendar.js deleted file mode 100644 index c4e3b53..0000000 --- a/src/components/AnimeCalendar.js +++ /dev/null @@ -1,210 +0,0 @@ -'use client'; - -import { useState, useEffect } from 'react'; -import Link from 'next/link'; -import Image from 'next/image'; -import { fetchSchedule } from '@/lib/api'; - -export default function AnimeCalendar() { - const [selectedDay, setSelectedDay] = useState(getCurrentDayIndex()); - const [scheduleData, setScheduleData] = useState([]); - const [isLoading, setIsLoading] = useState(true); - - // Add custom scrollbar styles - useEffect(() => { - // Add custom styles for the calendar scrollbar - const style = document.createElement('style'); - style.textContent = ` - .schedule-scrollbar::-webkit-scrollbar { - width: 4px; - } - .schedule-scrollbar::-webkit-scrollbar-track { - background: var(--card); - } - .schedule-scrollbar::-webkit-scrollbar-thumb { - background-color: var(--border); - border-radius: 4px; - } - `; - document.head.appendChild(style); - - // Cleanup function - return () => { - document.head.removeChild(style); - }; - }, []); - - // Get current day index (0-6, Sunday is 0) - function getCurrentDayIndex() { - const dayIndex = new Date().getDay(); - return dayIndex; // Sunday is 0, Monday is 1, etc. - } - - // Get current date info for the header - const getCurrentDateInfo = () => { - const today = new Date(); - const dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; - const monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; - - // Calculate the date for the selected day - const currentDayIndex = today.getDay(); - let daysDiff = selectedDay - currentDayIndex; - - // Always get the previous occurrence (or today if it's the current day) - if (daysDiff > 0) { - daysDiff -= 7; // Go back to previous week - } - - const selectedDate = new Date(today); - selectedDate.setDate(today.getDate() + daysDiff); - - return { - day: dayNames[selectedDay], - date: selectedDate.getDate(), - month: monthNames[selectedDate.getMonth()] - }; - }; - - const dateInfo = getCurrentDateInfo(); - - // Generate week days for the calendar - const days = [ - { label: 'Mon', value: 1 }, - { label: 'Tue', value: 2 }, - { label: 'Wed', value: 3 }, - { label: 'Thu', value: 4 }, - { label: 'Fri', value: 5 }, - { label: 'Sat', value: 6 }, - { label: 'Sun', value: 0 }, - ]; - - useEffect(() => { - async function loadScheduleData() { - setIsLoading(true); - try { - // Get the date for the selected day - const today = new Date(); - const currentDayIndex = today.getDay(); - let daysDiff = selectedDay - currentDayIndex; - - if (daysDiff > 0) { - daysDiff -= 7; - } - - const selectedDate = new Date(today); - selectedDate.setDate(today.getDate() + daysDiff); - - // Format date as YYYY-MM-DD - const formattedDate = selectedDate.toISOString().split('T')[0]; - - // Fetch schedule data for the selected date - const data = await fetchSchedule(formattedDate); - - if (data && data.scheduledAnimes) { - // Process and sort the scheduled animes by time - const processedData = data.scheduledAnimes - .map(anime => ({ - id: anime.id, - title: anime.name, - japaneseTitle: anime.jname, - time: anime.time, - airingTimestamp: anime.airingTimestamp, - secondsUntilAiring: anime.secondsUntilAiring - })) - .sort((a, b) => { - // Convert time strings to comparable values (assuming 24-hour format) - const timeA = a.time.split(':').map(Number); - const timeB = b.time.split(':').map(Number); - return (timeA[0] * 60 + timeA[1]) - (timeB[0] * 60 + timeB[1]); - }); - - setScheduleData(processedData); - } else { - setScheduleData([]); - } - } catch (error) { - console.error('Error loading schedule data:', error); - setScheduleData([]); - } finally { - setIsLoading(false); - } - } - - loadScheduleData(); - }, [selectedDay]); - - return ( -
- {/* Header */} -
-
-

Release Calendar

-
- {dateInfo.month} {dateInfo.date} -
-
- - {/* Day selector */} -
- {days.map((day) => ( - - ))} -
-
- - {/* Schedule list */} -
- {isLoading ? ( -
-
-
- ) : scheduleData.length > 0 ? ( -
- {scheduleData.map((anime) => ( - -
- {/* Time */} -
- {anime.time} -
- - {/* Anime info */} -
-

- {anime.title} -

- {anime.japaneseTitle && ( -

- {anime.japaneseTitle} -

- )} -
-
- - ))} -
- ) : ( -
- No releases scheduled -
- )} -
-
- ); -} \ No newline at end of file diff --git a/src/components/AnimeCard.js b/src/components/AnimeCard.js deleted file mode 100644 index 14952c0..0000000 --- a/src/components/AnimeCard.js +++ /dev/null @@ -1,158 +0,0 @@ -'use client'; - -import React, { useState, useEffect, useRef } from 'react'; -import Image from 'next/image'; -import Link from 'next/link'; -import { fetchAnimeEpisodes } from '@/lib/api'; - -export default function AnimeCard({ anime, isRecent }) { - const [imageError, setImageError] = useState(false); - const [firstEpisodeId, setFirstEpisodeId] = useState(null); - const [isLoading, setIsLoading] = useState(false); - const timerRef = useRef(null); - - // Fetch first episode ID when component mounts for recent anime - useEffect(() => { - const fetchFirstEpisode = async () => { - // Only fetch for recent anime and if we don't already have the episode ID - if (isRecent && anime?.id && !firstEpisodeId && !isLoading) { - setIsLoading(true); - try { - console.log(`[AnimeCard] Fetching episodes for anime: ${anime.id}`); - const response = await fetchAnimeEpisodes(anime.id); - console.log(`[AnimeCard] Episodes response for ${anime.name}:`, response); - - if (response.episodes && response.episodes.length > 0) { - // Check for the episode ID in the format expected by the watch page - const firstEp = response.episodes[0]; - if (firstEp.id) { - setFirstEpisodeId(firstEp.id); - console.log(`[AnimeCard] First episode ID (id) for ${anime.name}: ${firstEp.id}`); - } else if (firstEp.episodeId) { - setFirstEpisodeId(firstEp.episodeId); - console.log(`[AnimeCard] First episode ID (episodeId) for ${anime.name}: ${firstEp.episodeId}`); - } else { - // Create a fallback ID if neither id nor episodeId are available - const fallbackId = `${anime.id}?ep=1`; - setFirstEpisodeId(fallbackId); - console.log(`[AnimeCard] Using fallback ID for ${anime.name}: ${fallbackId}`); - } - } else if (anime.id) { - // If no episodes found, create a fallback ID - const fallbackId = `${anime.id}?ep=1`; - setFirstEpisodeId(fallbackId); - console.log(`[AnimeCard] No episodes found for ${anime.name}, using fallback ID: ${fallbackId}`); - } - } catch (error) { - console.error(`[AnimeCard] Error fetching episodes for ${anime.id}:`, error); - // Even on error, try to use fallback - if (anime.id) { - const fallbackId = `${anime.id}?ep=1`; - setFirstEpisodeId(fallbackId); - console.log(`[AnimeCard] Error for ${anime.name}, using fallback ID: ${fallbackId}`); - } - } finally { - setIsLoading(false); - } - } - }; - - fetchFirstEpisode(); - - // Clean up timer if component unmounts - return () => { - if (timerRef.current) clearTimeout(timerRef.current); - }; - }, [anime?.id, anime?.name, isRecent, firstEpisodeId, isLoading]); - - if (!anime) return null; - - const handleImageError = () => { - console.log("Image error for:", anime.name); - setImageError(true); - }; - - // Get image URL with fallback - const imageSrc = imageError ? '/images/placeholder.png' : anime.poster; - - // Generate appropriate links - const infoLink = `/anime/${anime.id}`; - - // Build the watch URL based on the first episode ID or fallback - const watchLink = isRecent && firstEpisodeId - ? `/watch/${firstEpisodeId}` - : isRecent - ? `/anime/${anime.id}` // Temporarily link to info page while loading - : `/anime/${anime.id}`; // Non-recent anime always link to info - - return ( -
- {/* Image card linking to watch page for recent anime, or info page otherwise */} - -
- {/* Hover overlay */} -
- - {/* Play button triangle - appears on hover */} -
- - - -
- - {anime.name - - {/* Badges in bottom left */} -
- {/* Episode badges */} - {anime.episodes && ( - <> - {anime.episodes.sub > 0 && ( -
- SUB {anime.episodes.sub} -
- )} - {anime.episodes.dub > 0 && ( -
- DUB {anime.episodes.dub} -
- )} - - )} - - {/* Type badge */} - {anime.type && ( -
- {anime.type} -
- )} -
-
- - - {/* Title linking to info page */} - -

- {anime.name} -

- -
- ); -} \ No newline at end of file diff --git a/src/components/AnimeDetails.js b/src/components/AnimeDetails.js deleted file mode 100644 index 68c2654..0000000 --- a/src/components/AnimeDetails.js +++ /dev/null @@ -1,585 +0,0 @@ -'use client'; - -import { useState, useRef, useEffect } from 'react'; -import Image from 'next/image'; -import Link from 'next/link'; -import AnimeRow from './AnimeRow'; -import SeasonRow from './SeasonRow'; -import { fetchAnimeEpisodes } from '@/lib/api'; - -export default function AnimeDetails({ anime }) { - const [isExpanded, setIsExpanded] = useState(false); - const [activeVideo, setActiveVideo] = useState(null); - const [activeTab, setActiveTab] = useState('synopsis'); - const [synopsisOverflows, setSynopsisOverflows] = useState(false); - const [firstEpisodeId, setFirstEpisodeId] = useState(null); - const [isLoadingEpisodes, setIsLoadingEpisodes] = useState(false); - const synopsisRef = useRef(null); - - // Check if synopsis overflows when component mounts or when content changes - useEffect(() => { - if (synopsisRef.current) { - const element = synopsisRef.current; - setSynopsisOverflows(element.scrollHeight > element.clientHeight); - } - }, [anime?.info?.description, activeTab]); - - // Fetch first episode ID when component mounts - useEffect(() => { - const fetchFirstEpisode = async () => { - if (anime?.info?.id) { - setIsLoadingEpisodes(true); - try { - console.log(`[AnimeDetails] Fetching episodes for anime: ${anime.info.id}`); - const response = await fetchAnimeEpisodes(anime.info.id); - console.log('[AnimeDetails] Episodes response:', response); - - if (response.episodes && response.episodes.length > 0) { - // Log the first episode to check its structure - console.log('[AnimeDetails] First episode:', response.episodes[0]); - - // Get the first episode's id - const firstEp = response.episodes[0]; - if (firstEp.id) { - setFirstEpisodeId(firstEp.id); - console.log(`[AnimeDetails] First episode ID found: ${firstEp.id}`); - } else if (firstEp.episodeId) { - // Fallback to episodeId if id is not available - setFirstEpisodeId(firstEp.episodeId); - console.log(`[AnimeDetails] Falling back to episodeId: ${firstEp.episodeId}`); - } else { - // If no episode ID is found in the API response, create a fallback ID - const fallbackId = `${anime.info.id}?ep=1`; - setFirstEpisodeId(fallbackId); - console.log(`[AnimeDetails] Using fallback ID: ${fallbackId}`); - } - } else if (anime.info.id) { - // If no episodes found but anime ID is available, use fallback - const fallbackId = `${anime.info.id}?ep=1`; - setFirstEpisodeId(fallbackId); - console.log(`[AnimeDetails] No episodes found, using fallback ID: ${fallbackId}`); - } else { - console.warn('[AnimeDetails] No episodes found and no anime ID available'); - } - } catch (error) { - console.error('[AnimeDetails] Error fetching episodes:', error); - // Even on error, try to use fallback - if (anime.info.id) { - const fallbackId = `${anime.info.id}?ep=1`; - setFirstEpisodeId(fallbackId); - console.log(`[AnimeDetails] Error occurred, using fallback ID: ${fallbackId}`); - } - } finally { - setIsLoadingEpisodes(false); - } - } - }; - - fetchFirstEpisode(); - }, [anime?.info?.id]); - - // Add a useEffect to debug when and why firstEpisodeId changes - useEffect(() => { - console.log('[AnimeDetails] firstEpisodeId changed:', firstEpisodeId); - }, [firstEpisodeId]); - - if (!anime?.info) { - return null; - } - - const { info, moreInfo, relatedAnime, recommendations, seasons } = anime; - const hasCharacters = info.characterVoiceActor?.length > 0 || info.charactersVoiceActors?.length > 0; - const hasVideos = info.promotionalVideos && info.promotionalVideos.length > 0; - - // Build the watch URL based on the first episode ID - const watchUrl = firstEpisodeId - ? `/watch/${firstEpisodeId}` - : ''; // Empty string if no episodes available - this shouldn't happen with our fallback - - // Add debug log here - console.log('[AnimeDetails] Rendered with watchUrl:', watchUrl, 'firstEpisodeId:', firstEpisodeId); - - // Video modal for promotional videos - const VideoModal = ({ video, onClose }) => { - if (!video) return null; - - return ( -
-
- - -
- -
-
-
- ); - }; - - // Format status with aired date - const getStatusWithAired = () => { - let status = moreInfo?.status || ''; - if (moreInfo?.aired) { - status += ` (${moreInfo.aired})`; - } - return status; - }; - - return ( -
- {/* Video Modal */} - {activeVideo && setActiveVideo(null)} />} - - {/* Background Image with Gradient Overlay - Desktop Only */} -
- {info.poster && ( - <> - {info.name} -
- - )} -
- - {/* Main Content */} -
- {/* MOBILE LAYOUT - Only visible on mobile */} -
-
- {/* Mobile Header with Title + Rating */} -
-

{info.name}

- {info.stats?.rating && ( -
- - - - {info.stats.rating} -
- )} -
- - {/* Japanese Title */} - {moreInfo?.japanese && ( -

{moreInfo.japanese}

- )} - - {/* Mobile Two-Column Layout */} -
- {/* Left Column - Poster */} -
-
-
- {info.name} -
-
-
- - {/* Right Column - Info Card */} -
- {/* Type & Episodes on same row */} -
- {info.stats?.type && ( -
{info.stats.type}
- )} - - {info.stats?.episodes && ( -
- {info.stats.episodes.sub > 0 && `Sub: ${info.stats.episodes.sub}`} - {info.stats.episodes.dub > 0 && info.stats.episodes.sub > 0 && ' • '} - {info.stats.episodes.dub > 0 && `Dub: ${info.stats.episodes.dub}`} -
- )} -
- - {/* Clean Info Layout */} -
- {/* Status */} - {moreInfo?.status && ( -
- Status: - {getStatusWithAired()} -
- )} - - {/* Quality */} - {info.stats?.quality && ( -
- Quality: - {info.stats.quality} -
- )} - - {/* Duration */} - {info.stats?.duration && ( -
- Duration: - {info.stats.duration} -
- )} - - {/* Studio */} - {moreInfo?.studios && ( -
- Studio: - {moreInfo.studios} -
- )} -
- - {/* Mobile Genres */} - {moreInfo?.genres && moreInfo.genres.length > 0 && ( -
- {moreInfo.genres.slice(0, 5).map((genre, index) => ( - - {genre} - - ))} - {moreInfo.genres.length > 5 && ( - +{moreInfo.genres.length - 5} - )} -
- )} -
-
- - {/* Watch Button - Mobile */} - {firstEpisodeId && ( - - - - - Start Watching - - )} -
-
- - {/* DESKTOP LAYOUT - Only visible on desktop */} -
- {/* Poster */} -
-
-
- {info.name} -
-
- - {/* Watch Button - Desktop */} - {firstEpisodeId && ( - - - - - Start Watching - - )} -
- - {/* Title and Metadata */} -
- {/* Title Section */} -
-

- {info.name} -

- - {moreInfo?.japanese && ( -

{moreInfo.japanese}

- )} - - {/* Synonyms */} - {moreInfo?.synonyms && ( -
-

{moreInfo.synonyms}

-
- )} -
- - {/* Status Badges */} -
- {info.stats?.rating && ( -
- - - - {info.stats.rating} -
- )} - - {/* Status with Aired Date */} - {moreInfo?.status && ( -
- {getStatusWithAired()} -
- )} - - {info.stats?.type && ( -
- {info.stats.type} -
- )} - - {info.stats?.episodes && ( -
- {info.stats.episodes.sub > 0 && `SUB ${info.stats.episodes.sub}`} - {info.stats.episodes.dub > 0 && info.stats.episodes.sub > 0 && ' | '} - {info.stats.episodes.dub > 0 && `DUB ${info.stats.episodes.dub}`} -
- )} - - {info.stats?.quality && ( -
- {info.stats.quality} -
- )} - - {info.stats?.duration && ( -
- {info.stats.duration} -
- )} -
- - {/* Genres & Studios */} -
- {/* Genres */} - {moreInfo?.genres && moreInfo.genres.length > 0 && ( -
-

Genres

-
- {moreInfo.genres.map((genre, index) => ( - - {genre} - - ))} -
-
- )} - - {/* Studios */} - {moreInfo?.studios && ( -
-

Studios

-
-
- {moreInfo.studios} -
-
-
- )} -
-
-
- - {/* Tabs Section - Different for Mobile/Desktop */} -
- {/* Tab Navigation */} -
- {/* Synopsis Tab */} - - - {/* Characters Tab */} - {hasCharacters && ( - - )} - - {/* Videos Tab */} - {hasVideos && ( - - )} -
- - {/* Tab Content */} -
- {/* Synopsis Tab */} - {activeTab === 'synopsis' && ( -
-

- {info.description || 'No description available for this anime.'} -

- {synopsisOverflows && ( - - )} -
- )} - - {/* Characters Tab */} - {activeTab === 'characters' && hasCharacters && ( -
- {(info.characterVoiceActor || info.charactersVoiceActors || []).map((item, index) => ( -
- {/* Character Image */} -
- {item.character.name} -
- - {/* Text content in the middle */} -
-
- {/* Character Name */} -
-

{item.character.name}

-

{item.character.cast || 'Main'}

-
- - {/* Voice Actor Name */} -
-

{item.voiceActor.name}

-

{item.voiceActor.cast || 'Japanese'}

-
-
-
- - {/* Voice Actor Image */} -
- {item.voiceActor.name} -
-
- ))} -
- )} - - {/* Videos Tab */} - {activeTab === 'videos' && hasVideos && ( -
- {info.promotionalVideos.map((video, index) => ( -
setActiveVideo(video)} - > -
-
- - - -
-
- {video.title -
- ))} -
- )} -
-
- - {/* Seasons Section */} - {seasons && seasons.length > 0 && ( - - )} - - {/* Related Anime Section */} - {relatedAnime && relatedAnime.length > 0 && ( - - )} - - {/* Recommendations Section */} - {recommendations && recommendations.length > 0 && ( - - )} -
-
- ); -} \ No newline at end of file diff --git a/src/components/AnimeFilters.js b/src/components/AnimeFilters.js deleted file mode 100644 index 2a7a507..0000000 --- a/src/components/AnimeFilters.js +++ /dev/null @@ -1,597 +0,0 @@ -'use client'; - -import { useState, useEffect, useRef } from 'react'; -import { fetchGenres } from '@/lib/api'; -import { ChevronDownIcon, CheckIcon, XMarkIcon } from '@heroicons/react/24/outline'; - -// Helper function to capitalize first letter of each word -const capitalizeFirstLetter = (string) => { - if (!string) return ''; - return string.split(' ').map(word => - word.charAt(0).toUpperCase() + word.slice(1).toLowerCase() - ).join(' '); -}; - -export default function AnimeFilters({ - selectedGenre, - onGenreChange, - yearFilter, - onYearChange, - sortOrder, - onSortChange, - showGenreFilter = true, - searchQuery = '', - onSearchChange, - selectedSeasons = [], - onSeasonChange, - selectedTypes = [], - onTypeChange, - selectedStatus = [], - onStatusChange, - selectedLanguages = [], - onLanguageChange -}) { - const [genres, setGenres] = useState([]); - const [isLoading, setIsLoading] = useState(true); - const [error, setError] = useState(null); - const [dropdowns, setDropdowns] = useState({ - genre: false, - season: false, - year: false, - type: false, - status: false, - language: false, - sort: false - }); - const dropdownRefs = useRef({ - genre: null, - season: null, - year: null, - type: null, - status: null, - language: null, - sort: null - }); - - // Available years for filter (current year down to 2000 and 'older') - const currentYear = new Date().getFullYear(); - const years = ['all', ...Array.from({ length: currentYear - 1999 }, (_, i) => (currentYear - i).toString()), 'older']; - - // Seasons data - const seasons = ['Winter', 'Spring', 'Summer', 'Fall']; - - // Types data - const types = ['TV', 'Movie', 'OVA', 'ONA', 'Special']; - - // Status data - const statuses = ['Ongoing', 'Completed', 'Upcoming']; - - // Languages data - const languages = ['Subbed', 'Dubbed', 'Chinese', 'English']; - - // Fetch genres on component mount - useEffect(() => { - const getGenres = async () => { - if (!showGenreFilter) return; - - try { - setIsLoading(true); - const genreData = await fetchGenres(); - // Capitalize each genre - const capitalizedGenres = genreData ? genreData.map(capitalizeFirstLetter) : []; - setGenres(capitalizedGenres); - } catch (error) { - console.error('Error fetching genres:', error); - setError('Failed to load genres. Please try again later.'); - } finally { - setIsLoading(false); - } - }; - - getGenres(); - }, [showGenreFilter]); - - // Toggle dropdown visibility - const toggleDropdown = (dropdown) => { - setDropdowns(prev => { - // Close other dropdowns when opening one - const newState = { - genre: false, - season: false, - year: false, - type: false, - status: false, - language: false, - sort: false, - [dropdown]: !prev[dropdown] - }; - return newState; - }); - }; - - // Initialize refs for each dropdown - useEffect(() => { - dropdownRefs.current = { - genre: dropdownRefs.current.genre, - season: dropdownRefs.current.season, - year: dropdownRefs.current.year, - type: dropdownRefs.current.type, - status: dropdownRefs.current.status, - language: dropdownRefs.current.language, - sort: dropdownRefs.current.sort - }; - }, []); - - // Close all dropdowns when clicking outside - useEffect(() => { - const handleClickOutside = (event) => { - // Check if the click was outside all dropdown containers - let isOutside = true; - Object.keys(dropdownRefs.current).forEach(key => { - if (dropdownRefs.current[key] && dropdownRefs.current[key].contains(event.target)) { - isOutside = false; - } - }); - - if (isOutside) { - setDropdowns({ - genre: false, - season: false, - year: false, - type: false, - status: false, - language: false, - sort: false - }); - } - }; - - document.addEventListener('mousedown', handleClickOutside); - return () => { - document.removeEventListener('mousedown', handleClickOutside); - }; - }, []); - - // Prevent dropdown from closing when selecting an item in multiselect - const keepDropdownOpen = (e, dropdown) => { - e.stopPropagation(); - // Don't toggle the dropdown state on item click for multi-select dropdowns - }; - - const handleClearGenre = (e) => { - e.stopPropagation(); - if (onGenreChange) { - onGenreChange(null); - } - }; - - // Toggle multi-select filter - const handleMultiSelectToggle = (type, value, onChange) => { - if (!onChange) return; - - let updatedSelection; - if (type.includes(value)) { - updatedSelection = type.filter(item => item !== value); - } else { - updatedSelection = [...type, value]; - } - onChange(updatedSelection); - }; - - // Modify the onClick handlers for each button to prevent event propagation - const handleGenreSelect = (e, genre) => { - e.stopPropagation(); - if (onGenreChange) { - onGenreChange(genre); - // Close genre dropdown after selection since it's a single select - setDropdowns(prev => ({ ...prev, genre: false })); - } - }; - - const handleYearSelect = (e, year) => { - e.stopPropagation(); - if (onYearChange) { - onYearChange(year); - // Close year dropdown after selection since it's a single select - setDropdowns(prev => ({ ...prev, year: false })); - } - }; - - const handleSortSelect = (e, sort) => { - e.stopPropagation(); - if (onSortChange) { - onSortChange(sort); - // Close sort dropdown after selection since it's a single select - setDropdowns(prev => ({ ...prev, sort: false })); - } - }; - - const handleMultiSelect = (e, type, value, onChange, dropdown) => { - e.stopPropagation(); - let updatedSelection; - if (type.includes(value)) { - updatedSelection = type.filter(item => item !== value); - } else { - updatedSelection = [...type, value]; - } - - if (onChange) { - onChange(updatedSelection); - // Keep dropdown open for multiselect to allow multiple selections - // Without closing the dropdown - } - }; - - // Add clear filter handlers - const clearAllFilters = (e) => { - e.stopPropagation(); - if (onGenreChange) onGenreChange(null); - if (onYearChange) onYearChange('all'); - if (onSortChange) onSortChange('default'); - if (onSeasonChange) onSeasonChange([]); - if (onTypeChange) onTypeChange([]); - if (onStatusChange) onStatusChange([]); - if (onLanguageChange) onLanguageChange([]); - }; - - const clearGenre = (e) => { - e.stopPropagation(); - if (onGenreChange) onGenreChange(null); - }; - - const clearYear = (e) => { - e.stopPropagation(); - if (onYearChange) onYearChange('all'); - }; - - const clearSort = (e) => { - e.stopPropagation(); - if (onSortChange) onSortChange('default'); - }; - - const clearSeasons = (e) => { - e.stopPropagation(); - if (onSeasonChange) onSeasonChange([]); - }; - - const clearTypes = (e) => { - e.stopPropagation(); - if (onTypeChange) onTypeChange([]); - }; - - const clearStatus = (e) => { - e.stopPropagation(); - if (onStatusChange) onStatusChange([]); - }; - - const clearLanguages = (e) => { - e.stopPropagation(); - if (onLanguageChange) onLanguageChange([]); - }; - - // Get display text for filters - const getYearDisplayText = () => { - if (yearFilter === 'all') return 'Year'; - if (yearFilter === 'older') return 'Before 2000'; - return yearFilter; - }; - - const getSortDisplayText = () => { - switch (sortOrder) { - case 'title-asc': return 'Title (A-Z)'; - case 'title-desc': return 'Title (Z-A)'; - case 'year-desc': return 'Newest First'; - case 'year-asc': return 'Oldest First'; - default: return 'Default'; - } - }; - - // Check if any filter is active - const isAnyFilterActive = () => { - return selectedGenre !== null || - yearFilter !== 'all' || - sortOrder !== 'default' || - selectedSeasons.length > 0 || - selectedTypes.length > 0 || - selectedStatus.length > 0 || - selectedLanguages.length > 0; - }; - - return ( -
-
- {/* Genre Filter */} -
dropdownRefs.current.genre = el}> - - {dropdowns.genre && ( -
-
- {genres.map((genre) => ( - - ))} -
-
- )} -
- - {/* Year Filter */} -
dropdownRefs.current.year = el}> - - {dropdowns.year && ( -
-
- {years.map((year) => ( - - ))} -
-
- )} -
- - {/* Season Filter */} -
dropdownRefs.current.season = el}> - - {dropdowns.season && ( -
keepDropdownOpen(e, 'season')} className="absolute z-50 w-full mt-2 py-1 bg-[#141414] rounded-lg border border-white/[0.04] shadow-xl"> - {seasons.map((season) => ( - - ))} -
- )} -
- - {/* Format Filter */} -
dropdownRefs.current.type = el}> - - {dropdowns.type && ( -
keepDropdownOpen(e, 'type')} className="absolute z-50 w-full mt-2 py-1 bg-[#141414] rounded-lg border border-white/[0.04] shadow-xl"> - {types.map((type) => ( - - ))} -
- )} -
- - {/* Status Filter */} -
dropdownRefs.current.status = el}> - - {dropdowns.status && ( -
keepDropdownOpen(e, 'status')} className="absolute z-50 w-full mt-2 py-1 bg-[#141414] rounded-lg border border-white/[0.04] shadow-xl"> - {statuses.map((status) => ( - - ))} -
- )} -
- - {/* Language Filter */} -
dropdownRefs.current.language = el}> - - {dropdowns.language && ( -
keepDropdownOpen(e, 'language')} className="absolute z-50 w-full mt-2 py-1 bg-[#141414] rounded-lg border border-white/[0.04] shadow-xl"> - {languages.map((language) => ( - - ))} -
- )} -
- - {/* Sort Filter */} -
dropdownRefs.current.sort = el}> - - {dropdowns.sort && ( -
- - - - - -
- )} -
- - {/* Clear All Button - Always visible */} - -
-
- ); -} \ No newline at end of file diff --git a/src/components/AnimeRow.js b/src/components/AnimeRow.js deleted file mode 100644 index e153fb6..0000000 --- a/src/components/AnimeRow.js +++ /dev/null @@ -1,131 +0,0 @@ -'use client'; - -import { useRef, useState, useEffect } from 'react'; -import AnimeCard from './AnimeCard'; - -export default function AnimeRow({ title, animeList }) { - const scrollContainerRef = useRef(null); - const contentRef = useRef(null); - const [showLeftButton, setShowLeftButton] = useState(false); - const [showRightButton, setShowRightButton] = useState(false); - - useEffect(() => { - if (!animeList || animeList.length <= 7) { - setShowRightButton(false); - return; - } - - setShowRightButton(true); - - const checkScroll = () => { - if (!scrollContainerRef.current) return; - - const { scrollLeft, scrollWidth, clientWidth } = scrollContainerRef.current; - setShowLeftButton(scrollLeft > 0); - setShowRightButton(scrollLeft + clientWidth < scrollWidth - 10); - }; - - const scrollContainer = scrollContainerRef.current; - scrollContainer.addEventListener('scroll', checkScroll); - - // Initial check - checkScroll(); - - return () => { - if (scrollContainer) { - scrollContainer.removeEventListener('scroll', checkScroll); - } - }; - }, [animeList]); - - const scroll = (direction) => { - if (!scrollContainerRef.current) return; - - const container = scrollContainerRef.current; - // Calculate single card width based on viewport - const isMobile = window.innerWidth < 640; // sm breakpoint in Tailwind - const cardsPerRow = isMobile ? 3 : 7; - const singleCardWidth = container.clientWidth / cardsPerRow; - - if (direction === 'left') { - container.scrollBy({ left: -singleCardWidth, behavior: 'smooth' }); - } else { - container.scrollBy({ left: singleCardWidth, behavior: 'smooth' }); - } - }; - - if (!animeList || animeList.length === 0) return null; - - // Create groups of cards for pagination - 3 for mobile, 7 for larger screens - const cardGroups = []; - const isMobileView = typeof window !== 'undefined' && window.innerWidth < 640; - const groupSize = isMobileView ? 3 : 7; - - for (let i = 0; i < animeList.length; i += groupSize) { - cardGroups.push(animeList.slice(i, i + groupSize)); - } - - return ( -
-
-

{title}

-
- -
- {showLeftButton && ( - - )} - -
-
- {cardGroups.map((group, groupIndex) => ( -
- {group.map((anime, index) => ( -
- -
- ))} - {/* Add empty placeholders if needed to ensure slots are filled */} - {Array.from({ length: (typeof window !== 'undefined' && window.innerWidth < 640) ? - Math.max(0, 3 - group.length) : - Math.max(0, 7 - group.length) }).map((_, index) => ( -
- ))} -
- ))} -
-
- - {showRightButton && ( - - )} -
-
- ); -} \ No newline at end of file diff --git a/src/components/AnimeTabs.js b/src/components/AnimeTabs.js deleted file mode 100644 index 5d878cf..0000000 --- a/src/components/AnimeTabs.js +++ /dev/null @@ -1,86 +0,0 @@ -'use client'; - -import React, { useState } from 'react'; -import AnimeCard from './AnimeCard'; -import Link from 'next/link'; - -const tabs = [ - { id: 'topAiring', label: 'TOP AIRING' }, - { id: 'popular', label: 'POPULAR' }, - { id: 'latestCompleted', label: 'LATEST COMPLETED' } -]; - -export default function AnimeTabs({ topAiring = [], popular = [], latestCompleted = [] }) { - const [activeTab, setActiveTab] = useState('topAiring'); - - const getActiveList = () => { - switch (activeTab) { - case 'topAiring': - return topAiring; - case 'popular': - return popular; - case 'latestCompleted': - return latestCompleted; - default: - return []; - } - }; - - const getViewAllLink = () => { - switch (activeTab) { - case 'topAiring': - return '/top-airing'; - case 'popular': - return '/most-popular'; - case 'latestCompleted': - return '/latest-completed'; - default: - return '/'; - } - }; - - return ( -
- {/* Tabs Navigation */} -
- {tabs.map((tab) => ( - - ))} - - View All - - - - -
- - {/* Anime Grid */} -
- {getActiveList().slice(0, 18).map((anime, index) => ( - - ))} -
-
- ); -} \ No newline at end of file diff --git a/src/components/EpisodeList.js b/src/components/EpisodeList.js deleted file mode 100644 index c52a8b0..0000000 --- a/src/components/EpisodeList.js +++ /dev/null @@ -1,239 +0,0 @@ -import { useState, useMemo, useEffect } from 'react'; - -export default function EpisodeList({ episodes, currentEpisode, onEpisodeClick, isDub = false }) { - const [currentPage, setCurrentPage] = useState(1); - const [isGridView, setIsGridView] = useState(false); - const [searchQuery, setSearchQuery] = useState(''); - const [activeEpisodeId, setActiveEpisodeId] = useState(null); - const episodesPerPage = 100; - - // Update active episode when currentEpisode changes - useEffect(() => { - if (currentEpisode?.id) { - setActiveEpisodeId(currentEpisode.id); - } - }, [currentEpisode]); - - // Sync with URL to identify current episode - useEffect(() => { - const checkCurrentEpisode = () => { - const path = window.location.pathname; - const match = path.match(/\/watch\/(.+)$/); - if (match) { - const urlEpisodeId = match[1]; - setActiveEpisodeId(urlEpisodeId); - - // Find the episode and update page - const episode = episodes.find(ep => ep.id === urlEpisodeId); - - if (episode) { - const pageNumber = Math.ceil(episode.number / episodesPerPage); - setCurrentPage(pageNumber); - } - } - }; - - // Check initially - checkCurrentEpisode(); - - // Set up listener for URL changes using the History API - const handleUrlChange = () => { - checkCurrentEpisode(); - }; - - window.addEventListener('popstate', handleUrlChange); - - // Clean up - return () => { - window.removeEventListener('popstate', handleUrlChange); - }; - }, [episodes, episodesPerPage]); - - const filteredEpisodes = useMemo(() => { - if (!searchQuery) return episodes; - const query = searchQuery.toLowerCase(); - return episodes.filter(episode => - episode.number.toString().includes(query) || - (episode.title && episode.title.toLowerCase().includes(query)) - ); - }, [episodes, searchQuery]); - - const totalPages = Math.ceil(filteredEpisodes.length / episodesPerPage); - const indexOfLastEpisode = currentPage * episodesPerPage; - const indexOfFirstEpisode = indexOfLastEpisode - episodesPerPage; - const currentEpisodes = filteredEpisodes.slice(indexOfFirstEpisode, indexOfLastEpisode); - - const getPageRange = (pageNum) => { - const start = (pageNum - 1) * episodesPerPage + 1; - const end = Math.min(pageNum * episodesPerPage, filteredEpisodes.length); - return `${start}-${end}`; - }; - - const isCurrentEpisode = (episode) => { - if (!episode || !episode.id || !activeEpisodeId) return false; - return episode.id === activeEpisodeId; - }; - - const handleEpisodeSelect = (episode, e) => { - e.preventDefault(); - if (onEpisodeClick && episode.id) { - // Use the episode ID directly as it's already in the correct format from the API - console.log(`[EpisodeList] Selected episode: ${episode.number}, ID: ${episode.id}`); - onEpisodeClick(episode.id); - setActiveEpisodeId(episode.id); - } - }; - - // Scroll active episode into view when page changes or active episode changes - useEffect(() => { - if (activeEpisodeId) { - setTimeout(() => { - const activeElement = document.querySelector(`[data-episode-id="${activeEpisodeId}"]`); - if (activeElement) { - activeElement.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); - } - }, 100); - } - }, [activeEpisodeId, currentPage]); - - return ( -
- {/* Header */} -
-
-
- { - setSearchQuery(e.target.value); - setCurrentPage(1); - }} - className="w-full bg-[#2a2a2a] text-white text-sm rounded-lg px-4 py-1.5 pl-9 focus:outline-none focus:ring-2 focus:ring-[var(--primary)] placeholder-gray-500" - /> - - - -
-
- - -
-
-
- - {/* Episodes Container */} -
-
- {isGridView ? ( - // Grid View -
- {currentEpisodes.map((episode) => ( - - ))} -
- ) : ( - // List View -
- {currentEpisodes.map((episode) => ( - - ))} -
- )} -
-
-
- ); -} \ No newline at end of file diff --git a/src/components/GenreBar.js b/src/components/GenreBar.js deleted file mode 100644 index 97543e8..0000000 --- a/src/components/GenreBar.js +++ /dev/null @@ -1,230 +0,0 @@ -'use client'; - -import Link from 'next/link'; -import { useState, useEffect, useRef, useMemo } from 'react'; -import { fetchGenres } from '@/lib/api'; - -export default function GenreBar() { - const [genres, setGenres] = useState([]); - const [isLoading, setIsLoading] = useState(true); - const [showLeftButton, setShowLeftButton] = useState(true); // Always show left button initially - const [showRightButton, setShowRightButton] = useState(true); - const [isMobile, setIsMobile] = useState(false); - const scrollContainerRef = useRef(null); - const containerRef = useRef(null); - const [visibleGenres, setVisibleGenres] = useState(14); - - // Function to capitalize first letter - const capitalizeFirstLetter = (string) => { - return string.charAt(0).toUpperCase() + string.slice(1); - }; - - // Predefined genres exactly as specified - wrapped in useMemo to prevent recreation on every render - const defaultGenres = useMemo(() => [ - "Action", "Adventure", "Comedy", "Drama", "Ecchi", "Fantasy", - "Horror", "Mahou Shoujo", "Mecha", "Music", "Mystery", "Psychological", - "Romance", "Sci-Fi", "Slice of Life", "Sports", "Supernatural", "Thriller" - ], []); - - // Handle long names on mobile - const getMobileGenreName = (genre) => { - // Abbreviate long genre names for mobile view - switch(genre) { - case "Psychological": return "Psycho"; - case "Mahou Shoujo": return "Mahou"; - case "Supernatural": return "Super"; - case "Slice of Life": return "SoL"; - default: return genre; - } - }; - - // Detect mobile devices - useEffect(() => { - const checkIfMobile = () => { - setIsMobile(window.innerWidth < 768); - }; - - checkIfMobile(); - window.addEventListener('resize', checkIfMobile); - - return () => window.removeEventListener('resize', checkIfMobile); - }, []); - - // Calculate the number of genres that fit in the container - useEffect(() => { - const calculateVisibleGenres = () => { - const container = containerRef.current; - if (container) { - const containerWidth = container.offsetWidth; - // Approximate width of each genre button - const genreButtonWidth = isMobile ? 72 : 88; // Slightly larger on mobile to fit text - const visibleCount = Math.floor((containerWidth - 80) / genreButtonWidth); - // Minimum genres visible (smaller minimum on mobile) - setVisibleGenres(Math.max(visibleCount, isMobile ? 4 : 8)); - } - }; - - calculateVisibleGenres(); - window.addEventListener('resize', calculateVisibleGenres); - - return () => { - window.removeEventListener('resize', calculateVisibleGenres); - }; - }, [isMobile]); - - useEffect(() => { - // Force scroll position slightly to the right initially - // to ensure there are genres on both sides for scrolling - setTimeout(() => { - if (scrollContainerRef.current) { - scrollContainerRef.current.scrollLeft = 40; // Start slightly scrolled - // Trigger scroll event to update button states - scrollContainerRef.current.dispatchEvent(new Event('scroll')); - } - }, 100); - - setGenres(defaultGenres); - setIsLoading(false); - }, [defaultGenres]); - - // Check scroll position to determine button visibility - useEffect(() => { - const handleScroll = () => { - if (scrollContainerRef.current) { - const { scrollLeft, scrollWidth, clientWidth } = scrollContainerRef.current; - - // Show left button if not at the start - setShowLeftButton(scrollLeft > 5); - - // Show right button if not at the end - setShowRightButton(scrollLeft < scrollWidth - clientWidth - 5); - } - }; - - const scrollContainer = scrollContainerRef.current; - if (scrollContainer) { - scrollContainer.addEventListener('scroll', handleScroll); - // Initial check - handleScroll(); - - return () => { - scrollContainer.removeEventListener('scroll', handleScroll); - }; - } - }, []); - - // Scroll left/right functions - const scrollLeft = () => { - if (scrollContainerRef.current) { - const scrollAmount = isMobile ? -80 : -200; - scrollContainerRef.current.scrollBy({ left: scrollAmount, behavior: 'smooth' }); - } - }; - - const scrollRight = () => { - if (scrollContainerRef.current) { - const scrollAmount = isMobile ? 80 : 200; - scrollContainerRef.current.scrollBy({ left: scrollAmount, behavior: 'smooth' }); - } - }; - - // Mobile-specific styles - const mobileButtonStyle = { - padding: '0.15rem 0.5rem', - fontSize: '0.65rem', - height: '1.5rem', - minWidth: '4rem', - maxWidth: '5.5rem', - textAlign: 'center', - whiteSpace: 'nowrap', - overflow: 'hidden', - textOverflow: 'ellipsis', - display: 'flex', - alignItems: 'center', - justifyContent: 'center' - }; - - if (isLoading) { - return ( -
-
- {[...Array(isMobile ? 5 : visibleGenres)].map((_, i) => ( -
- ))} -
-
- ); - } - - return ( -
- {/* Left fade effect */} -
-
- - {/* Left scroll button - only visible when not at the leftmost position */} - {showLeftButton && ( - - )} - - {/* Scrollable genre container */} -
-
- {genres.map((genre) => ( - - {isMobile ? getMobileGenreName(genre) : genre} - - ))} -
-
- - {/* Right fade effect */} -
-
- - {/* Right scroll button - only visible when not at the rightmost position */} - {showRightButton && ( - - )} -
- ); -} \ No newline at end of file diff --git a/src/components/GenreList.js b/src/components/GenreList.js deleted file mode 100644 index f0c5e71..0000000 --- a/src/components/GenreList.js +++ /dev/null @@ -1,93 +0,0 @@ -'use client'; - -import Link from 'next/link'; -import { useState, useEffect } from 'react'; -import { fetchGenres } from '@/lib/api'; - -export default function GenreList() { - const [genres, setGenres] = useState([]); - const [isLoading, setIsLoading] = useState(true); - const [showAll, setShowAll] = useState(false); - - useEffect(() => { - async function loadGenres() { - try { - const genreData = await fetchGenres(); - setGenres(genreData || []); - } catch (error) { - console.error("Error fetching genres:", error); - } finally { - setIsLoading(false); - } - } - - loadGenres(); - }, []); - - // Predefined popular genres if API doesn't return them - const defaultGenres = [ - "Action", "Adventure", "Comedy", "Drama", "Fantasy", - "Horror", "Mystery", "Romance", "Sci-Fi", "Slice of Life", - "Supernatural", "Thriller", "Isekai", "Mecha", "Sports" - ]; - - // Use fetched genres or fallback to default genres - const displayGenres = genres.length > 0 ? genres : defaultGenres; - - // Show only first 12 genres if not showing all - const visibleGenres = showAll ? displayGenres : displayGenres.slice(0, 12); - - if (isLoading) { - return ( -
-
-

Genres

-
-
- {[...Array(12)].map((_, i) => ( -
- ))} -
-
- ); - } - - return ( -
-
-

Genres

-
- -
- {visibleGenres.map((genre) => ( - - {genre} - - ))} -
- - {displayGenres.length > 12 && ( -
- -
- )} -
- ); -} \ No newline at end of file diff --git a/src/components/Loader/AnimeInfo.loader.jsx b/src/components/Loader/AnimeInfo.loader.jsx new file mode 100644 index 0000000..3a20c22 --- /dev/null +++ b/src/components/Loader/AnimeInfo.loader.jsx @@ -0,0 +1,58 @@ +import { Skeleton } from "@/src/components/ui/Skeleton/Skeleton"; +import CategoryCardLoader from "./CategoryCard.loader"; +import SidecardLoader from "./Sidecard.loader"; + +const SkeletonItems = ({ count, className }) => ( + [...Array(count)].map((_, index) => ) +); + +function AnimeInfoLoader() { + return ( + <> +
+ +
+ +
+
    + +
+
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+
+
+
+
+
+ +
+ +
+ +
+
+ +
+
+
+
+ + +
+ + ); +} +export default AnimeInfoLoader; diff --git a/src/components/Loader/AtoZ.loader.jsx b/src/components/Loader/AtoZ.loader.jsx new file mode 100644 index 0000000..8c9ba62 --- /dev/null +++ b/src/components/Loader/AtoZ.loader.jsx @@ -0,0 +1,26 @@ +import { Skeleton } from "../ui/Skeleton/Skeleton"; +import CategoryCardLoader from "./CategoryCard.loader"; + +const SkeletonItems = ({ count, className }) => ( + [...Array(count)].map((_, index) => ) +); + +function AtoZLoader() { + return ( +
+
    + + +
+
+ +
+ +
+
+ +
+ ); +} + +export default AtoZLoader; diff --git a/src/components/Loader/Cart.loader.jsx b/src/components/Loader/Cart.loader.jsx new file mode 100644 index 0000000..2467415 --- /dev/null +++ b/src/components/Loader/Cart.loader.jsx @@ -0,0 +1,27 @@ +import { Skeleton } from "../ui/Skeleton/Skeleton" +const SkeletonItems = ({ count, className }) => ( + [...Array(count)].map((_, index) => ) +); +function CartLoader() { + return ( +
+ +
+ {[...Array(5)].map((item, index) => ( +
+ +
+ +
+ +
+
+
+ ))} +
+ +
+ ) +} + +export default CartLoader \ No newline at end of file diff --git a/src/components/Loader/Category.loader.jsx b/src/components/Loader/Category.loader.jsx new file mode 100644 index 0000000..45a6b21 --- /dev/null +++ b/src/components/Loader/Category.loader.jsx @@ -0,0 +1,23 @@ +import { Skeleton } from "../ui/Skeleton/Skeleton" +import CategoryCardLoader from "./CategoryCard.loader" +import SidecardLoader from "./Sidecard.loader" + +function CategoryLoader() { + return ( +
+
+ +
+ + +
+
+
+ + +
+
+ ) +} + +export default CategoryLoader \ No newline at end of file diff --git a/src/components/Loader/CategoryCard.loader.jsx b/src/components/Loader/CategoryCard.loader.jsx new file mode 100644 index 0000000..c170069 --- /dev/null +++ b/src/components/Loader/CategoryCard.loader.jsx @@ -0,0 +1,35 @@ +import { Skeleton } from "../ui/Skeleton/Skeleton"; + +function CategoryCardLoader({ className, showLabelSkeleton = true }) { + return ( +
+ {showLabelSkeleton && ( + + )} +
+ {[...Array(12)].map((_, index) => ( +
+
+ +
+ + +
+
+ +
+ + +
+
+ ))} +
+
+ ); +} + +export default CategoryCardLoader; diff --git a/src/components/Loader/Home.loader.jsx b/src/components/Loader/Home.loader.jsx new file mode 100644 index 0000000..21f8491 --- /dev/null +++ b/src/components/Loader/Home.loader.jsx @@ -0,0 +1,32 @@ +import CartLoader from "./Cart.loader"; +import CategoryCardLoader from "./CategoryCard.loader"; +import SidecardLoader from "./Sidecard.loader"; +import SpotlightLoader from "./Spotlight.loader"; +import Trendingloader from "./Trending.loader"; +function HomeLoader() { + return ( +
+ + +
+ + + + +
+
+
+ + + +
+
+ + +
+
+
+ ); +} + +export default HomeLoader; diff --git a/src/components/Loader/Loader.jsx b/src/components/Loader/Loader.jsx new file mode 100644 index 0000000..e6a7886 --- /dev/null +++ b/src/components/Loader/Loader.jsx @@ -0,0 +1,24 @@ +import AnimeInfoLoader from "./AnimeInfo.loader"; +import HomeLoader from "./Home.loader"; +import CategoryLoader from "./Category.loader"; +import AtoZLoader from "./AtoZ.loader"; +import ProducerLoader from "./Producer.loader"; + +const Loader = ({ type }) => { + switch (type) { + case "home": + return ; + case "animeInfo": + return ; + case "category": + return ; + case "producer": + return ; + case "AtoZ": + return ; + default: + return
; + } +}; + +export default Loader; diff --git a/src/components/Loader/Producer.loader.jsx b/src/components/Loader/Producer.loader.jsx new file mode 100644 index 0000000..b48b908 --- /dev/null +++ b/src/components/Loader/Producer.loader.jsx @@ -0,0 +1,15 @@ +import CategoryCardLoader from "./CategoryCard.loader"; +import SidecardLoader from "./Sidecard.loader"; + +function ProducerLoader() { + return ( +
+
+ + +
+
+ ); +} + +export default ProducerLoader; diff --git a/src/components/Loader/Sidecard.loader.jsx b/src/components/Loader/Sidecard.loader.jsx new file mode 100644 index 0000000..8f9d7d5 --- /dev/null +++ b/src/components/Loader/Sidecard.loader.jsx @@ -0,0 +1,26 @@ +import { Skeleton } from "../ui/Skeleton/Skeleton"; +function SidecardLoader({ className }) { + return ( +
+ +
+ {[...Array(10)].map((_, index) => ( +
+
+ +
+ +
+ + +
+
+
+
+ ))} +
+
+ ); +} + +export default SidecardLoader; diff --git a/src/components/Loader/Spotlight.loader.jsx b/src/components/Loader/Spotlight.loader.jsx new file mode 100644 index 0000000..583d74c --- /dev/null +++ b/src/components/Loader/Spotlight.loader.jsx @@ -0,0 +1,34 @@ +import { Skeleton } from "../ui/Skeleton/Skeleton" +const SkeletonItems = ({ count, className }) => ( + [...Array(count)].map((_, index) => ) +); +function SpotlightLoader() { + return ( +
+
+ + +
+ +
+ +
+ +
+
+
+
+ + + +
+
+ + +
+
+
+ ) +} + +export default SpotlightLoader \ No newline at end of file diff --git a/src/components/Loader/Trending.loader.jsx b/src/components/Loader/Trending.loader.jsx new file mode 100644 index 0000000..bf777db --- /dev/null +++ b/src/components/Loader/Trending.loader.jsx @@ -0,0 +1,34 @@ +import { useState, useEffect } from "react"; +import { Skeleton } from "../ui/Skeleton/Skeleton"; + +function TrendingLoader() { + const [count, setCount] = useState(() => window.innerWidth < 720 ? 3 : window.innerWidth < 1300 ? 4 : 6); + useEffect(() => { + const updateCount = () => { + if (window.innerWidth < 720) { + setCount(3); + } else if (window.innerWidth < 1300) { + setCount(4); + } else { + setCount(6); + } + }; + updateCount(); + window.addEventListener("resize", updateCount); + return () => window.removeEventListener("resize", updateCount); + }, []); + return ( +
+ +
+ {[...Array(count)].map((_, index) => ( +
+ +
+ ))} +
+
+ ); +} + +export default TrendingLoader; diff --git a/src/components/Loader/VoiceActorlist.loader.jsx b/src/components/Loader/VoiceActorlist.loader.jsx new file mode 100644 index 0000000..f4b975e --- /dev/null +++ b/src/components/Loader/VoiceActorlist.loader.jsx @@ -0,0 +1,21 @@ +import { Skeleton } from "../ui/Skeleton/Skeleton" + +function VoiceActorlistLoader() { + return ( +
+ {[...Array(10)].map((_, index) => ( +
+
+ +
+ + +
+
+
+ ))} +
+ ) +} + +export default VoiceActorlistLoader \ No newline at end of file diff --git a/src/components/Navbar.js b/src/components/Navbar.js deleted file mode 100644 index be281e9..0000000 --- a/src/components/Navbar.js +++ /dev/null @@ -1,628 +0,0 @@ -'use client'; - -import Link from 'next/link'; -import Image from 'next/image'; -import { useState, useEffect, useRef } from 'react'; -import { useRouter } from 'next/navigation'; -import { - fetchSearchSuggestions, - fetchMostPopular, - fetchTopAiring, - fetchRecentEpisodes, - fetchMostFavorite, - fetchTopUpcoming -} from '@/lib/api'; - -export default function Navbar() { - const [isMenuOpen, setIsMenuOpen] = useState(false); - const [searchQuery, setSearchQuery] = useState(''); - const [searchSuggestions, setSearchSuggestions] = useState([]); - const [showSuggestions, setShowSuggestions] = useState(false); - const [isScrolled, setIsScrolled] = useState(false); - const [isLoading, setIsLoading] = useState(false); - const [isRandomLoading, setIsRandomLoading] = useState(false); - const suggestionRef = useRef(null); - const searchInputRef = useRef(null); - const router = useRouter(); - - // Track scroll position - useEffect(() => { - const handleScroll = () => { - if (window.scrollY > 10) { - setIsScrolled(true); - } else { - setIsScrolled(false); - } - }; - - window.addEventListener('scroll', handleScroll); - return () => window.removeEventListener('scroll', handleScroll); - }, []); - - // Update suggestions when search query changes - useEffect(() => { - const updateSuggestions = async () => { - // Only search if we have at least 2 characters - if (searchQuery.trim().length >= 2) { - setIsLoading(true); - setShowSuggestions(true); // Always show the suggestions container when typing - - try { - console.log(`Fetching suggestions for: ${searchQuery}`); - const apiSuggestions = await fetchSearchSuggestions(searchQuery); - console.log('API returned:', apiSuggestions); - - if (Array.isArray(apiSuggestions) && apiSuggestions.length > 0) { - // Take top 5 results - setSearchSuggestions(apiSuggestions.slice(0, 5)); - } else { - // Create a generic suggestion based on the search query - setSearchSuggestions([{ - id: searchQuery.toLowerCase().replace(/\s+/g, '-'), - title: `Search for "${searchQuery}"`, - type: "SEARCH", - image: null - }]); - } - } catch (error) { - console.error('Error in search component:', error); - // Create a generic suggestion - setSearchSuggestions([{ - id: searchQuery.toLowerCase().replace(/\s+/g, '-'), - title: `Search for "${searchQuery}"`, - type: "SEARCH", - image: null - }]); - } finally { - setIsLoading(false); - } - } else { - setSearchSuggestions([]); - setShowSuggestions(false); - } - }; - - const debounceTimer = setTimeout(() => { - updateSuggestions(); - }, 300); // 300ms debounce time - - return () => clearTimeout(debounceTimer); - }, [searchQuery]); - - // Close suggestions when clicking outside - useEffect(() => { - const handleClickOutside = (event) => { - if ( - suggestionRef.current && - !suggestionRef.current.contains(event.target) && - !searchInputRef.current?.contains(event.target) - ) { - setShowSuggestions(false); - } - }; - - document.addEventListener('mousedown', handleClickOutside); - return () => { - document.removeEventListener('mousedown', handleClickOutside); - }; - }, []); - - const handleSearch = (e) => { - e.preventDefault(); - // Navigate to search page regardless if search is empty or not - router.push(searchQuery.trim() ? `/search?q=${encodeURIComponent(searchQuery)}` : '/search'); - setSearchQuery(''); - setShowSuggestions(false); - setIsMenuOpen(false); - }; - - // Handle suggestion item click - const handleAnimeClick = (id) => { - router.push(`/anime/${id}`); - setSearchQuery(''); - setShowSuggestions(false); - setIsMenuOpen(false); - }; - - // Handle search by query click - const handleSearchByQueryClick = () => { - router.push(`/search?q=${encodeURIComponent(searchQuery)}`); - setSearchQuery(''); - setShowSuggestions(false); - setIsMenuOpen(false); - }; - - // Helper function to render clear button - const renderClearButton = () => { - if (searchQuery) { - return ( - - ); - } - return null; - }; - - // Function to handle input focus - const handleInputFocus = () => { - if (searchQuery.trim().length >= 2) { - setShowSuggestions(true); - } - }; - - // Function to handle random anime click - const handleRandomAnimeClick = async () => { - setIsRandomLoading(true); - try { - // Randomly select a category to fetch from - const categories = [ - { name: 'Most Popular', fetch: fetchMostPopular }, - { name: 'Top Airing', fetch: fetchTopAiring }, - { name: 'Recent Episodes', fetch: fetchRecentEpisodes }, - { name: 'Most Favorite', fetch: fetchMostFavorite }, - { name: 'Top Upcoming', fetch: fetchTopUpcoming } - ]; - - // Select a random category - const randomCategoryIndex = Math.floor(Math.random() * categories.length); - const selectedCategory = categories[randomCategoryIndex]; - - console.log(`Fetching random anime from: ${selectedCategory.name}`); - - // Fetch anime from the selected category - use a random page number to get more variety - const randomPage = Math.floor(Math.random() * 5) + 1; // Random page between 1-5 - const animeList = await selectedCategory.fetch(randomPage); - - if (animeList && animeList.results && animeList.results.length > 0) { - // Skip the first few results as they tend to be more popular - const skipCount = Math.min(5, Math.floor(animeList.results.length / 3)); - let availableAnime = animeList.results.slice(skipCount); - - if (availableAnime.length === 0) { - // If we've filtered out everything, use the original list - availableAnime = animeList.results; - } - - // Get a random index - const randomAnimeIndex = Math.floor(Math.random() * availableAnime.length); - - // Get the random anime ID - const randomAnimeId = availableAnime[randomAnimeIndex].id; - - console.log(`Selected random anime: ${availableAnime[randomAnimeIndex].title} (ID: ${randomAnimeId})`); - - // Navigate to the anime page - router.push(`/anime/${randomAnimeId}`); - } else { - console.error('No anime found to select randomly from'); - - // Fallback to most popular if the chosen category fails, but use a higher page number - const fallbackPage = Math.floor(Math.random() * 5) + 2; // Pages 2-6 for more obscure options - const fallbackList = await fetchMostPopular(fallbackPage); - - if (fallbackList && fallbackList.results && fallbackList.results.length > 0) { - const randomIndex = Math.floor(Math.random() * fallbackList.results.length); - const randomAnimeId = fallbackList.results[randomIndex].id; - router.push(`/anime/${randomAnimeId}`); - } - } - } catch (error) { - console.error('Error fetching random anime:', error); - } finally { - setIsRandomLoading(false); - } - }; - - return ( - - ); -} \ No newline at end of file diff --git a/src/components/SeasonCard.js b/src/components/SeasonCard.js deleted file mode 100644 index 2123710..0000000 --- a/src/components/SeasonCard.js +++ /dev/null @@ -1,56 +0,0 @@ -'use client'; - -import Image from 'next/image'; -import Link from 'next/link'; -import { useState } from 'react'; - -export default function SeasonCard({ season }) { - const [imageError, setImageError] = useState(false); - - if (!season) return null; - - const handleImageError = () => { - console.log("Image error for:", season.name); - setImageError(true); - }; - - // Get image URL with fallback - const imageSrc = imageError ? '/images/placeholder.png' : season.poster; - - // Generate link - const infoLink = `/anime/${season.id}`; - - return ( - -
- {/* Background image with blur */} -
-
- {season.name -
- - {/* Content overlay */} -
-
-

- {season.title || season.name} -

-
-
-
- - ); -} \ No newline at end of file diff --git a/src/components/SeasonRow.js b/src/components/SeasonRow.js deleted file mode 100644 index e54c4b7..0000000 --- a/src/components/SeasonRow.js +++ /dev/null @@ -1,162 +0,0 @@ -'use client'; - -import { useRef, useState, useEffect } from 'react'; -import SeasonCard from './SeasonCard'; - -export default function SeasonRow({ title, seasons }) { - const scrollContainerRef = useRef(null); - const contentRef = useRef(null); - const [showLeftButton, setShowLeftButton] = useState(false); - const [showRightButton, setShowRightButton] = useState(false); - - useEffect(() => { - if (!seasons || seasons.length <= 7) { - setShowRightButton(false); - return; - } - - setShowRightButton(true); - - const checkScroll = () => { - if (!scrollContainerRef.current) return; - - const { scrollLeft, scrollWidth, clientWidth } = scrollContainerRef.current; - setShowLeftButton(scrollLeft > 0); - setShowRightButton(scrollLeft + clientWidth < scrollWidth - 10); - }; - - const scrollContainer = scrollContainerRef.current; - scrollContainer.addEventListener('scroll', checkScroll); - - // Initial check - checkScroll(); - - return () => { - if (scrollContainer) { - scrollContainer.removeEventListener('scroll', checkScroll); - } - }; - }, [seasons]); - - // Updated effect to handle mobile view arrows - useEffect(() => { - if (!seasons) return; - - // Check if we're on mobile and have more than 3 seasons - const isMobileView = typeof window !== 'undefined' && window.innerWidth < 640; - const showArrowsOnMobile = isMobileView && seasons.length > 3; - - // On desktop, show arrows if more than 7 seasons - const showArrowsOnDesktop = !isMobileView && seasons.length > 7; - - if (showArrowsOnMobile || showArrowsOnDesktop) { - setShowRightButton(true); - } else { - setShowRightButton(false); - } - - // Listen for resize events to update arrow visibility - const handleResize = () => { - const isMobile = window.innerWidth < 640; - const showArrows = isMobile ? seasons.length > 3 : seasons.length > 7; - setShowRightButton(showArrows); - }; - - window.addEventListener('resize', handleResize); - - return () => { - window.removeEventListener('resize', handleResize); - }; - }, [seasons]); - - const scroll = (direction) => { - if (!scrollContainerRef.current) return; - - const container = scrollContainerRef.current; - // Calculate single card width based on viewport - const isMobile = window.innerWidth < 640; // sm breakpoint in Tailwind - const cardsPerRow = isMobile ? 3 : 7; - const singleCardWidth = container.clientWidth / cardsPerRow; - - if (direction === 'left') { - container.scrollBy({ left: -singleCardWidth, behavior: 'smooth' }); - } else { - container.scrollBy({ left: singleCardWidth, behavior: 'smooth' }); - } - }; - - if (!seasons || seasons.length === 0) return null; - - // Create groups of cards for pagination - 3 for mobile, 7 for larger screens - const seasonGroups = []; - const isMobileView = typeof window !== 'undefined' && window.innerWidth < 640; - const groupSize = isMobileView ? 3 : 7; - - for (let i = 0; i < seasons.length; i += groupSize) { - seasonGroups.push(seasons.slice(i, i + groupSize)); - } - - return ( -
-
-

{title || 'Seasons'}

-
- -
- {showLeftButton && ( - - )} - -
-
- {seasonGroups.map((group, groupIndex) => ( -
- {group.map((season, index) => ( -
- -
- ))} - {/* Add empty placeholders if needed to ensure slots are filled */} - {Array.from({ length: (typeof window !== 'undefined' && window.innerWidth < 640) ? - Math.max(0, 3 - group.length) : - Math.max(0, 7 - group.length) }).map((_, index) => ( -
- ))} -
- ))} -
-
- - {showRightButton && ( - - )} -
-
- ); -} \ No newline at end of file diff --git a/src/components/SharedLayout.js b/src/components/SharedLayout.js deleted file mode 100644 index f42d5f2..0000000 --- a/src/components/SharedLayout.js +++ /dev/null @@ -1,86 +0,0 @@ -'use client'; - -import Navbar from './Navbar'; -import Image from 'next/image'; - -const Footer = () => { - return ( - - ); -}; - -export default function SharedLayout({ children }) { - return ( - <> - -
- {children} -
-