async function searchResults(keyword) { const results = []; try { const response = await fetchv2("https://api.cdnlibs.org/api/anime?fields[]=rate_avg&fields[]=rate&fields[]=releaseDate&q=" + keyword); const json = await response.json(); if (json && Array.isArray(json.data)) { for (const item of json.data) { const image = item.cover?.default || item.cover?.thumbnail || ""; results.push({ title: item.eng_name || item.name || "Unknown", image: "https://passthrough-worker.simplepostrequest.workers.dev/?simple=" + image + "&referer=https://animelib.org/", href: item.slug_url || item.slug || item.id }); } } return JSON.stringify(results); } catch (err) { return JSON.stringify([{ title: "Error", image: "Error", href: "Error" }]); } } async function extractDetails(slug) { try { const response = await fetchv2( "https://api.cdnlibs.org/api/anime/" + slug + "?fields[]=background&fields[]=eng_name&fields[]=otherNames&fields[]=summary&fields[]=releaseDate&fields[]=type_id&fields[]=caution&fields[]=views&fields[]=close_view&fields[]=rate_avg&fields[]=rate&fields[]=genres&fields[]=tags&fields[]=teams&fields[]=user&fields[]=franchise&fields[]=authors&fields[]=publisher&fields[]=userRating&fields[]=moderated&fields[]=metadata&fields[]=metadata.count&fields[]=metadata.close_comments&fields[]=anime_status_id&fields[]=time&fields[]=episodes&fields[]=episodes_count&fields[]=episodesSchedule&fields[]=shiki_rate" ); const json = await response.json(); const data = json.data || {}; const aliases = Array.isArray(data.otherNames) ? data.otherNames.join(", ") : ""; return JSON.stringify([{ description: data.summary || "No summary available", airdate: data.releaseDate || "Unknown", aliases: aliases }]); } catch (err) { return JSON.stringify([{ description: "Error", airdate: "Error", aliases: "" }]); } } async function extractEpisodes(slug) { const results = []; try { const response = await fetchv2("https://api.cdnlibs.org/api/episodes?anime_id=" + slug); const json = await response.json(); if (json && Array.isArray(json.data)) { for (const episode of json.data) { results.push({ href: episode.id ? String(episode.id) : "", number: parseFloat(episode.number) || 0 }); } } return JSON.stringify(results); } catch (err) { return JSON.stringify([{ href: "Error", number: "Error" }]); } } async function extractStreamUrl(ID) { try { const response = await fetchv2("https://api.cdnlibs.org/api/episodes/" + ID); const json = await response.json(); const data = json.data || {}; const players = data.players || []; const parserPromises = players .filter(player => player.src && player.team && player.team.name) .map(async (player) => { try { const kodikUrl = "https:" + player.src; const qualitiesJson = await kodikParser(kodikUrl); const qualities = JSON.parse(qualitiesJson); let highestQuality = null; let highestQualityNum = 0; for (const quality in qualities) { if (qualities[quality].src) { const qualityNum = parseInt(quality.replace('p', '')) || 0; if (qualityNum > highestQualityNum) { highestQualityNum = qualityNum; highestQuality = qualities[quality].src; } } } if (highestQuality) { if (highestQuality.startsWith('//')) { highestQuality = 'https:' + highestQuality; } return { title: player.team.name, streamUrl: highestQuality, headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Referer": "https://kodik.info/" } }; } return null; } catch (err) { return null; } }); const results = await Promise.all(parserPromises); const streams = results.filter(stream => stream !== null); return JSON.stringify({ streams: streams, subtitle: "https://none.com" }); } catch (err) { return JSON.stringify({ streams: [], subtitle: "https://none.com" }); } } async function kodikParser(url) { try { const headers = { "Referer": "https://v3.animelib.org/", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3" }; const response = await fetchv2(url, headers); const htmlText = await response.text(); const urlParamsMatch = htmlText.match(/var\s+urlParams\s*=\s*'([^']+)'/); const videoInfoTypeMatch = htmlText.match(/videoInfo\.type\s*=\s*'([^']+)'/); const videoInfoHashMatch = htmlText.match(/videoInfo\.hash\s*=\s*'([^']+)'/); const videoInfoIdMatch = htmlText.match(/videoInfo\.id\s*=\s*'([^']+)'/); const urlParams = urlParamsMatch ? JSON.parse(urlParamsMatch[1]) : {}; const videoInfo_type = videoInfoTypeMatch ? videoInfoTypeMatch[1] : ''; const videoInfo_hash = videoInfoHashMatch ? videoInfoHashMatch[1] : ''; const videoInfo_id = videoInfoIdMatch ? videoInfoIdMatch[1] : ''; const finalData = `d=${urlParams.d}` + `&d_sign=${urlParams.d_sign}` + `&pd=${urlParams.pd}` + `&pd_sign=${urlParams.pd_sign}` + `&ref=${urlParams.ref}` + `&ref_sign=${urlParams.ref_sign}` + `&bad_user=false&cdn_is_working=false` + `&type=${videoInfo_type}&hash=${videoInfo_hash}&id=${videoInfo_id}&info=%7B%7D`; const headers2 = { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Referer": "https://kodik.info", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3", "X-Requested-With": "XMLHttpRequest" }; const apiResponse = await fetchv2("https://kodik.info/ftor", headers2, "POST", finalData); const apiJson = await apiResponse.json(); const qualities = {}; if (apiJson?.links) { for (const quality in apiJson.links) { const qualityData = apiJson.links[quality]; if (qualityData && qualityData[0] && qualityData[0].src) { const encodedSrc = qualityData[0].src; const decodedUrl = decode(encodedSrc); qualities[quality] = { src: decodedUrl, type: qualityData[0].type || 'application/x-mpegURL' }; } } } return JSON.stringify(qualities, null, 2); } catch (error) { console.log(error); return JSON.stringify({ error: "error.org" }); } } function decode(input) { const _0x1a = ["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "=", String.fromCharCode, ">="]; (function() {})(); const _map = _0x1a[0]; let _o = '', _b = 0, _c = 0; const _r = []; for (let _i = 0; _i < input.length; _i++) { const _ch = input[_i]; if (/[a-zA-Z]/.test(_ch)) { const _cc = _ch.charCodeAt(0); const _max = _ch <= 'Z' ? 90 : 122; let _sh = _cc + 18; _r.push(String.fromCharCode(_sh <= _max ? _sh : _sh - 26)); } else _r.push(_ch); } const _rot = _r.join(''); for (let _j = 0; _j < _rot.length; _j++) { const _ch = _rot[_j]; if (_ch === _0x1a[1]) break; const _v = _map.indexOf(_ch); if (_v === -1) continue; _b = (_b << 6) | _v; _c += 6; if (_c >= 8) { _c -= 8; _o += _0x1a[2]((_b >> _c) & 0xFF); } } return _o; }