]*class=["'][^"']*limiter[^"']*["'][^>]*>([\s\S]*?)<\/div>/i
);
const description = _stripTags(
(descMatch && descMatch[1]) || _extractMeta(html, "name", "description") || "No description available"
) || "No description available";
let aliases = _extractMeta(html, "property", "og:title") || "";
aliases = aliases.replace(/\s*(?:>|\u00BB)+\s*SameBand\s*$/i, "").trim();
return JSON.stringify([
{
description,
aliases: aliases || "SameBand",
airdate: _bestYearCandidate(html)
}
]);
} catch (_) {
return JSON.stringify([]);
}
}
async function extractEpisodes(url) {
try {
const animeUrl = _extractAnimeUrl(url);
if (!animeUrl) return JSON.stringify([]);
const page = await fetchv2(animeUrl, _htmlHeaders(SEARCH_URL));
const html = await page.text();
const iframeSrc = _extractIframeSrc(html);
if (!iframeSrc) return JSON.stringify([]);
const candidates = _buildListCandidates(iframeSrc);
const playlist = await _fetchPlaylistArray(candidates, animeUrl);
if (!playlist.length) return JSON.stringify([]);
const episodes = playlist.map((item, index) => {
const titleHtml = String(item?.title || "");
const title = _extractEpisodeTitle(titleHtml, index + 1);
const number = _extractEpisodeNumber(title, index + 1);
const imgTag = (titleHtml.match(/
![]()
]*>/i) || [""])[0];
const image = _absUrl(_attr(imgTag, "src"), BASE_URL);
const payload = {
animeUrl,
file: String(item?.file || ""),
thumbnails: String(item?.thumbnails || ""),
title,
image
};
const out = {
href: _packEpisode(payload),
number,
title
};
if (image) out.image = image;
return out;
});
episodes.sort((a, b) => Number(a.number) - Number(b.number));
return JSON.stringify(episodes);
} catch (_) {
return JSON.stringify([]);
}
}
async function extractStreamUrl(href) {
try {
const payload = _unpackEpisode(href);
const fileField = payload?.file ? String(payload.file) : "";
if (!fileField) {
return JSON.stringify({ streams: [], subtitle: "https://none.com" });
}
const variants = _parseFileVariants(fileField);
if (!variants.length) {
return JSON.stringify({ streams: [], subtitle: "https://none.com" });
}
const byQuality = {
1080: "",
720: "",
480: ""
};
for (const v of variants) {
if ((v.quality === 1080 || v.quality === 720 || v.quality === 480) && !byQuality[v.quality]) {
byQuality[v.quality] = v.url;
}
}
const url1080 = byQuality[1080] || null;
const url720 = byQuality[720] || null;
const url480 = byQuality[480] || null;
const headers = {
"User-Agent": _ua(),
"Referer": payload?.animeUrl ? String(payload.animeUrl) : (BASE_URL + "/"),
"Origin": BASE_URL
};
const streams = [];
if (url1080) {
streams.push({
title: "1080p",
streamUrl: url1080,
url1080,
url720,
url480,
headers
});
}
if (url720) {
streams.push({
title: "720p",
streamUrl: url720,
url1080,
url720,
url480,
headers
});
}
if (url480) {
streams.push({
title: "480p",
streamUrl: url480,
url1080,
url720,
url480,
headers
});
}
if (!streams.length) {
const first = variants[0];
if (first?.url) {
streams.push({
title: "1080p",
streamUrl: first.url,
url1080: first.url,
url720: null,
url480: null,
headers
});
}
}
return JSON.stringify({
streams,
subtitle: "https://none.com"
});
} catch (_) {
return JSON.stringify({ streams: [], subtitle: "https://none.com" });
}
}