async function searchResults(keyword) { const results = []; const headers = { "Host": 'graphql.anilist.co', "User-Agent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:147.0) Gecko/20100101 Firefox/147.0', "Accept": 'application/json', "Accept-Language": 'en-US,en;q=0.9', "Accept-Encoding": 'gzip, deflate, br, zstd', "Referer": 'https://anicore.tv/', "Content-Type": 'application/json', "Content-Length": '1380', "Origin": 'https://anicore.tv', "Connection": 'keep-alive', "Sec-Fetch-Dest": 'empty', "Sec-Fetch-Mode": 'cors', "Sec-Fetch-Site": 'cross-site', "Priority": 'u=4', "TE": 'trailers' }; const postData = {"query":"\nquery ($page: Int = 1, $perPage: Int = 50, $type: MediaType = ANIME, $search: String, $format_in: [MediaFormat], $status: MediaStatus, $countryOfOrigin: CountryCode, $season: MediaSeason, $seasonYear: Int, $genre_in: [String], $tag_in: [String], $sort:[MediaSort], $isAdult: Boolean) {\n Page(page: $page, perPage: $perPage) {\n pageInfo {\n total\n perPage\n currentPage\n lastPage\n hasNextPage\n }\n media(type: $type, sort: $sort, season: $season, seasonYear: $seasonYear, search: $search, genre_in: $genre_in, tag_in: $tag_in, format_in: $format_in, status: $status, countryOfOrigin: $countryOfOrigin, isAdult: $isAdult){\n id\n title {\n english\n romaji\n }\n coverImage {\n extraLarge\n color\n }\n startDate {\n year\n month\n day\n }\n bannerImage\n season\n seasonYear\n description\n type\n format\n status(version: 2)\n episodes\n duration\n chapters\n volumes\n genres\n isAdult\n averageScore\n popularity\n nextAiringEpisode {\n airingAt\n timeUntilAiring\n episode\n }\n mediaListEntry {\n id\n status\n }\n }\n }\n}","variables":{"search":`${keyword}`,"type":"ANIME","sort":"POPULARITY_DESC","page":1}}; try { const response = await fetchv2("https://graphql.anilist.co/", headers, "POST", postData); const data = await response.json(); if (data.data && data.data.Page && data.data.Page.media) { const media = data.data.Page.media; for (const item of media) { results.push({ title: item.title.english || item.title.romaji || "Unknown", image: item.coverImage.extraLarge || "", href: `${item.id}` }); } } return JSON.stringify(results); } catch (err) { return JSON.stringify([{ title: "Error", image: "Error", href: "Error" }]); } } async function extractDetails(ID) { try { const headers = { "Host": 'graphql.anilist.co', "User-Agent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:147.0) Gecko/20100101 Firefox/147.0', "Accept": 'application/json', "Accept-Language": 'en-US,en;q=0.9', "Accept-Encoding": 'gzip, deflate, br, zstd', "Referer": 'https://anicore.tv/', "Content-Type": 'application/json', "Content-Length": '1380', "Origin": 'https://anicore.tv', "Connection": 'keep-alive', "Sec-Fetch-Dest": 'empty', "Sec-Fetch-Mode": 'cors', "Sec-Fetch-Site": 'cross-site', "Priority": 'u=4', "TE": 'trailers' }; const postData = {"query":"query media($id:Int,$type:MediaType,$isAdult:Boolean){Media(id:$id,type:$type,isAdult:$isAdult){id title{userPreferred romaji english native}coverImage{extraLarge large}bannerImage startDate{year month day}endDate{year month day}description season seasonYear type format status(version:2)episodes duration chapters volumes genres synonyms source(version:3)isAdult isLocked meanScore averageScore popularity favourites isFavouriteBlocked hashtag countryOfOrigin isLicensed isFavourite isRecommendationBlocked isFavouriteBlocked isReviewBlocked nextAiringEpisode{airingAt timeUntilAiring episode}relations{edges{id relationType(version:2)node{id title{userPreferred}format type status(version:2)bannerImage coverImage{large}}}}characterPreview:characters(perPage:6,sort:[ROLE,RELEVANCE,ID]){edges{id role name voiceActors(language:JAPANESE,sort:[RELEVANCE,ID]){id name{userPreferred}language:languageV2 image{large}}node{id name{userPreferred}image{large}}}}staffPreview:staff(perPage:8,sort:[RELEVANCE,ID]){edges{id role node{id name{userPreferred}language:languageV2 image{large}}}}studios{edges{isMain node{id name}}}reviewPreview:reviews(perPage:2,sort:[RATING_DESC,ID]){pageInfo{total}nodes{id summary rating ratingAmount user{id name avatar{large}}}}recommendations(perPage:7,sort:[RATING_DESC,ID]){pageInfo{total}nodes{id rating userRating mediaRecommendation{id title{userPreferred}format type status(version:2)bannerImage coverImage{large}}user{id name avatar{large}}}}externalLinks{id site url type language color icon notes isDisabled}streamingEpisodes{site title thumbnail url}trailer{id site}rankings{id rank type format year season allTime context}tags{id name description rank isMediaSpoiler isGeneralSpoiler userId}mediaListEntry{id status score}stats{statusDistribution{status amount}scoreDistribution{score amount}}}}","variables":{"id":ID,"type":"ANIME"}}; const response = await fetchv2("https://graphql.anilist.co/", headers, "POST", postData); const data = await response.json(); const media = data.data.Media; return JSON.stringify([{ description: clean(media.description), aliases: media.title.romaji + " / " + media.title.english + " / " + media.title.native, airdate: media.startDate.year }]); } catch (err) { return JSON.stringify([{ description: "Error", aliases: "Error", airdate: "Error" }]); } } async function extractEpisodes(ID) { const results = []; try { const response = await fetchv2("https://anicore-api.vercel.app/api/episodes?id=" + ID); const data = await response.json(); if (Array.isArray(data)) { for (const episode of data) { results.push({ href: `${ID}-${episode.number}`, number: episode.number }); } } return JSON.stringify(results); } catch (err) { return JSON.stringify([{ href: "Error", number: "Error" }]); } } async function extractStreamUrl(url) { try { const parts = url.split('-'); const animeID = parts[0]; const episodeNumber = parseInt(parts[1], 10); const episodesResponse = await fetchv2("https://anicore-api.vercel.app/api/episodes?id=" + animeID); const episodesData = await episodesResponse.json(); const episode = episodesData.find(ep => ep.number === episodeNumber); if (!episode) { return JSON.stringify({ streams: [], subtitle: "" }); } const excludedProviders = ['oni', 'yuki', 'kami']; const subProviders = (episode.subProviders || []).filter(p => !excludedProviders.includes(p)); const dubProviders = (episode.dubProviders || []).filter(p => !excludedProviders.includes(p)); if (subProviders.length === 0 && dubProviders.length === 0) { return JSON.stringify({ streams: [], subtitle: "" }); } const streamPromises = []; for (const provider of subProviders) { streamPromises.push( fetchv2(`https://anicore-api.vercel.app/api/stream?id=${animeID}&host=${provider}&ep=${episodeNumber}&type=sub`) .then(res => res.json()) .then(data => ({ provider, type: 'sub', data })) .catch(() => ({ provider, type: 'sub', data: null })) ); } for (const provider of dubProviders) { streamPromises.push( fetchv2(`https://anicore-api.vercel.app/api/stream?id=${animeID}&host=${provider}&ep=${episodeNumber}&type=dub`) .then(res => res.json()) .then(data => ({ provider, type: 'dub', data })) .catch(() => ({ provider, type: 'dub', data: null })) ); } const streamResults = await Promise.all(streamPromises); const streams = []; let englishSubtitle = ""; let zenResult = null; for (const result of streamResults) { if (result.data && result.data.sources && result.data.sources.length > 0) { const source = result.data.sources[0]; const typeLabel = result.type === 'dub' ? 'DUB' : 'SUB'; streams.push({ title: `${result.provider.toUpperCase()} - ${typeLabel}`, streamUrl: source.url, headers: result.data.headers || {} }); if (result.provider === 'zen' && result.type === 'sub') { zenResult = result; } } } if (zenResult && zenResult.data && Array.isArray(zenResult.data.subtitles)) { const engSub = zenResult.data.subtitles.find(sub => (sub.lang.includes('eng') || sub.lang.includes('en')) && !sub.label.toLowerCase().includes('signs') && !sub.label.toLowerCase().includes('songs') ); if (engSub) { englishSubtitle = engSub.url || ""; } } if (!englishSubtitle) { for (const result of streamResults) { if (result.type === 'sub' && result.data) { if (Array.isArray(result.data.subtitles)) { const engSub = result.data.subtitles.find(sub => (sub.lang.includes('eng') || sub.lang.includes('en') || sub.language === 'eng' || sub.language === 'en' || sub.name === 'eng' || sub.name === 'en') && !(sub.label && (sub.label.toLowerCase().includes('signs') || sub.label.toLowerCase().includes('songs'))) ); if (engSub) { englishSubtitle = engSub.url || ""; break; } } if (!englishSubtitle && Array.isArray(result.data.audio)) { const engAudio = result.data.audio.find(audio => audio.language === 'eng' || audio.language === 'en' || audio.name === 'eng' || audio.name === 'en' ); if (engAudio) { englishSubtitle = engAudio.url || ""; break; } } } } } console.log(JSON.stringify({ streams: streams.length > 0 ? streams : [], subtitles: englishSubtitle })); return JSON.stringify({ streams: streams.length > 0 ? streams : [], subtitles: englishSubtitle }); } catch (err) { return JSON.stringify({ streams: [], subtitles: "" }); } } const clean = html => html .replace(//gi, '\n') .replace(/<\/?i>/gi, '') .replace(/<\/?b>/gi, '') .replace(/<\/?[^>]+>/g, '');