kalo ad bug benerin ajh sendiri.
qrtz
javascript
9
7
https://vip.oploverz.ltd
24 Jun 2026
Code
import axios from "axios";
import * as cheerio from "cheerio";
import fs from "fs";
import https from "https";
const BASE = "https://vip.oploverz.ltd";
const BACKAPI = "https://backapi.oploverz.ac/uploads/";
const TIMEOUT = 30000;
const MAX_RETRIES = 5;
const RETRY_DELAY = 1000;
const USER_AGENTS = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0",
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
"Mozilla/5.0 (iPad; CPU OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
"Mozilla/5.0 (Android 14; Mobile; rv:133.0) Gecko/133.0 Firefox/133.0",
"Mozilla/5.0 (Android 14; Mobile; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 OPR/115.0.0.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 OPR/115.0.0.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Vivaldi/6.9.0.0",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Vivaldi/6.8.0.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Vivaldi/6.9.0.0",
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0",
];
function randomUA() {
return USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)];
}
function randomDelay(min = 100, max = 1500) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function getHeaders() {
const ua = randomUA();
return {
"User-Agent": ua,
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Cache-Control": "max-age=0",
"Sec-Ch-Ua": '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": '"Windows"',
"Referer": "https://vip.oploverz.ltd/",
"Origin": "https://vip.oploverz.ltd",
};
}
const http = axios.create({
baseURL: BASE,
timeout: TIMEOUT,
withCredentials: true,
httpsAgent: new https.Agent({ rejectUnauthorized: false, keepAlive: true }),
});
const AD_DOMAINS = [
"blogger.com", "blogspot.com", "paladindrama",
"glamour", "mayhap", "histats",
"slot", "casino", "mpo", "judol",
"placehold.co", "comentario", "cloudflareinsights",
];
function isClean(url = "") {
if (!url) return false;
const lower = url.toLowerCase();
return !AD_DOMAINS.some(d => lower.includes(d));
}
function decodeSvelteFlat(raw) {
if (!raw || !Array.isArray(raw.nodes)) return null;
const dataNode = raw.nodes.find(n => n?.type === "data" && Array.isArray(n.data));
if (!dataNode) return null;
const arr = dataNode.data;
function resolve(idx) {
if (idx === null || idx === undefined) return null;
const val = arr[idx];
if (val === null || val === undefined) return val;
if (typeof val !== "object") return val;
if (Array.isArray(val)) return val.map(i => resolve(i));
const result = {};
for (const [k, v] of Object.entries(val)) result[k] = resolve(v);
return result;
}
return resolve(0);
}
async function fetchDataJson(path, referer, retries = MAX_RETRIES) {
const endpoint = (path === "/" ? "" : path) + "/__data.json?x-sveltekit-invalidated=001";
for (let i = 0; i < retries; i++) {
try {
const headers = getHeaders();
headers.Referer = referer || BASE + "/";
const res = await http.get(endpoint, { headers });
if (res.status === 403 || res.status === 503) {
throw new Error(`Blocked (${res.status})`);
}
return decodeSvelteFlat(res.data);
} catch (e) {
if (i === retries - 1) throw e;
const delay = RETRY_DELAY * Math.pow(2, i) + randomDelay(0, 500);
await new Promise(r => setTimeout(r, delay));
}
}
}
async function fetchHTML(path, retries = MAX_RETRIES) {
for (let i = 0; i < retries; i++) {
try {
const headers = getHeaders();
const res = await http.get(path, { headers });
if (res.status === 403 || res.status === 503) {
throw new Error(`Blocked (${res.status})`);
}
return res.data;
} catch (e) {
if (i === retries - 1) throw e;
const delay = RETRY_DELAY * Math.pow(2, i) + randomDelay(0, 500);
await new Promise(r => setTimeout(r, delay));
}
}
}
function fullUrl(path) {
if (!path) return null;
if (path.startsWith("http")) return path;
return BACKAPI + path;
}
function fmtStreamUrls(streamUrl = []) {
return (streamUrl || [])
.filter(s => s?.url && isClean(s.url))
.map(s => ({ label: s.source, url: s.url }));
}
function fmtDownloads(downloadUrl = []) {
return (downloadUrl || []).flatMap(fmt =>
(fmt?.resolutions || []).flatMap(res =>
(res?.download_links || [])
.filter(l => l?.url && isClean(l.url))
.map(l => ({
format: fmt.format || null,
quality: res.quality || null,
host: l.host || null,
url: l.url,
}))
)
);
}
function fmtSeries(s) {
if (!s?.slug) return null;
return {
id: s.id || null,
title: s.title || null,
japaneseTitle: s.japaneseTitle || null,
slug: s.slug,
status: s.status || null,
poster: fullUrl(s.poster),
score: s.score || null,
genres: (s.genres || []).map(g => g?.name || g).filter(Boolean),
studio: s.studio?.name || null,
season: s.season?.name || null,
totalEpisodes: s.totalEpisodes || null,
releaseDate: s.releaseDate || null,
releaseType: s.releaseType || null,
url: `${BASE}/series/${s.slug}`,
};
}
function fmtEpisodeCard(ep) {
if (!ep) return null;
return {
id: ep.id || null,
seriesTitle: ep.series?.title || null,
seriesSlug: ep.series?.slug || null,
episodeNumber: ep.episodeNumber || null,
subbed: ep.subbed || null,
poster: fullUrl(ep.series?.poster) || null,
releasedAt: ep.releasedAt || null,
streamUrls: fmtStreamUrls(ep.streamUrl),
downloadUrls: fmtDownloads(ep.downloadUrl),
url: ep.series?.slug
? `${BASE}/series/${ep.series.slug}/episode/${ep.episodeNumber}`
: null,
};
}
async function home() {
const decoded = await fetchDataJson("/", BASE + "/");
if (!decoded) throw new Error("Gagal decode home __data.json");
const trending = decoded.trending || {};
const recently = decoded.recently || {};
const latestEpisodes = decoded.latestEpisodes || {};
const html = await fetchHTML("/");
const $ = cheerio.load(html);
const banners = [];
$("[data-embla-slide]").each((_, el) => {
const img = $(el).find("img[src*='banners']").attr("src") || null;
const slug = $(el).find("a[href^='/series/']").first().attr("href")?.replace("/series/", "").replace(/\/.*/, "");
const title = $(el).find("h1 span, h2 span").first().text().trim();
const desc = $(el).find("p").filter((_, p) => $(p).text().trim().length > 5).first().text().trim();
if (img && slug && !banners.find(b => b.slug === slug)) {
banners.push({ image: img, title, slug, description: desc, url: `${BASE}/series/${slug}` });
}
});
return {
creator: "rynaqrtz",
page: "home",
banners,
trending: (trending.data || []).map(fmtSeries).filter(Boolean),
recently: (recently.data || []).map(fmtSeries).filter(Boolean),
latestEpisodes: (latestEpisodes.data || []).map(fmtEpisodeCard).filter(Boolean),
meta: {
trending: trending.meta || {},
recently: recently.meta || {},
latestEpisodes: latestEpisodes.meta || {},
},
};
}
async function seriesList(page = 1, sort_by = "recently", genre = "", limit = 20) {
const query = new URLSearchParams({ page, sort_by, ...(genre && { genre }) });
const decoded = await fetchDataJson(`/series?${query}`, BASE + "/");
let items = (decoded?.allSeries?.data || []).map(s => fmtSeries(s)).filter(Boolean);
if (!items.length) {
const html = await fetchHTML(`/series?${query}`);
const $ = cheerio.load(html);
$("a[href^='/series/']").each((_, el) => {
const slug = $(el).attr("href")?.replace("/series/", "").replace(/\/.*/, "");
const title = $(el).find("img").attr("alt") || "";
const img = $(el).find("img").attr("src") || null;
if (slug && title && !items.find(x => x.slug === slug))
items.push({ slug, title, poster: fullUrl(img), url: `${BASE}/series/${slug}` });
});
}
const total = items.length;
const start = (page - 1) * limit;
const end = start + limit;
const pagedItems = items.slice(start, end);
return {
creator: "rynaqrtz",
page: "series",
total,
pagination: {
currentPage: page,
lastPage: Math.ceil(total / limit) || 1,
perPage: limit,
},
items: pagedItems,
};
}
async function detail(slug) {
const decoded = await fetchDataJson(`/series/${slug}`, BASE + "/");
if (!decoded) throw new Error(`Gagal decode __data.json untuk: ${slug}`);
const s = decoded.series || {};
const eps = decoded.episodes || {};
const epList = (eps.data || eps || []);
return {
creator: "rynaqrtz",
page: "detail",
id: s.id || null,
title: s.title || null,
japaneseTitle: s.japaneseTitle || null,
slug,
description: s.description || null,
status: s.status || null,
poster: fullUrl(s.poster),
score: s.score || null,
genres: (s.genres || []).map(g => g?.name || g).filter(Boolean),
studio: s.studio?.name || null,
season: s.season?.name || null,
totalEpisodes: s.totalEpisodes || epList.length,
releaseDate: s.releaseDate || null,
releaseType: s.releaseType || null,
batchDownload: s.batchDownloadUrl || null,
episodesMeta: {
currentPage: eps.meta?.currentPage || 1,
lastPage: eps.meta?.lastPage || 1,
total: eps.meta?.total || epList.length,
},
episodes: Array.isArray(epList)
? epList
.map(ep => ({
episodeNumber: ep.episodeNumber || null,
title: ep.title || null,
releasedAt: ep.releasedAt || null,
url: `${BASE}/series/${slug}/episode/${ep.episodeNumber}`,
}))
.filter(ep => ep.episodeNumber)
.sort((a, b) => +a.episodeNumber - +b.episodeNumber)
: [],
url: `${BASE}/series/${slug}`,
};
}
async function watch(slug, epNumber) {
const decoded = await fetchDataJson(
`/series/${slug}/episode/${epNumber}`,
`${BASE}/series/${slug}`
);
if (!decoded) throw new Error(`Gagal decode __data.json untuk: ${slug} ep ${epNumber}`);
const ep = decoded.episode || {};
const all = decoded.allEpisodes || decoded.episodes || {};
const allList = all.data || all || [];
return {
page: "watch",
id: ep.id || null,
seriesTitle: ep.series?.title || decoded.series?.title || null,
seriesSlug: ep.series?.slug || slug,
episodeNumber: ep.episodeNumber || epNumber,
subbed: ep.subbed || null,
poster: fullUrl(ep.series?.poster) || fullUrl(decoded.series?.poster) || null,
releasedAt: ep.releasedAt || null,
streamUrls: fmtStreamUrls(ep.streamUrl),
downloadUrls: fmtDownloads(ep.downloadUrl),
allEpisodes: Array.isArray(allList)
? allList
.map(e => ({
episodeNumber: e.episodeNumber || null,
releasedAt: e.releasedAt || null,
url: `${BASE}/series/${slug}/episode/${e.episodeNumber}`,
}))
.filter(e => e.episodeNumber)
.sort((a, b) => +a.episodeNumber - +b.episodeNumber)
: [],
url: `${BASE}/series/${slug}/episode/${epNumber}`,
};
}
async function episodes(slug, limit = 0) {
const detailData = await detail(slug);
const epList = detailData.episodes || [];
const result = [];
for (let i = 0; i < epList.length; i++) {
if (limit > 0 && i >= limit) break;
const ep = epList[i];
const epNum = ep.episodeNumber;
try {
const watchData = await watch(slug, epNum);
result.push(watchData);
} catch (e) {
result.push({ ...ep, error: e.message });
}
await new Promise(r => setTimeout(r, randomDelay(300, 800)));
}
return {
creator: "rynaqrtz",
page: "episodes",
seriesTitle: detailData.title,
slug,
total: result.length,
episodes: result,
};
}
async function search(query, limit = 20) {
const decoded = await fetchDataJson(`/search?q=${encodeURIComponent(query)}`, BASE + "/");
let items = (decoded?.allSeries?.data || []).map(s => fmtSeries(s)).filter(Boolean);
if (!items.length) {
const html = await fetchHTML(`/search?q=${encodeURIComponent(query)}`);
const $ = cheerio.load(html);
$("a[href^='/series/']").each((_, el) => {
const slug = $(el).attr("href")?.replace("/series/", "").replace(/\/.*/, "");
const title = $(el).find("img").attr("alt") || "";
const img = $(el).find("img").attr("src") || null;
if (slug && title && !items.find(x => x.slug === slug))
items.push({ slug, title, poster: fullUrl(img), url: `${BASE}/series/${slug}` });
});
}
const filtered = items.filter(item => item.title && item.title.toLowerCase().includes(query.toLowerCase()));
const total = filtered.length;
const paged = filtered.slice(0, limit);
return {
creator: "rynaqrtz",
page: "search",
query,
total,
pagination: { currentPage: 1, lastPage: Math.ceil(total / limit), perPage: limit },
items: paged,
};
}
const COMMANDS = {
home: () => home(),
series: ([p, s, g, l] = []) => {
const page = parseInt(p) || 1;
const sort = s || "recently";
const genre = g || "";
const limit = parseInt(l) || 20;
return seriesList(page, sort, genre, limit);
},
detail: ([slug]) => {
if (!slug) throw new Error("Usage: detail <slug>");
return detail(slug);
},
watch: ([slug, ep]) => {
if (!slug || !ep) throw new Error("Usage: watch <slug> <episode>");
return watch(slug, ep);
},
episodes: ([slug, limit]) => {
if (!slug) throw new Error("Usage: episodes <slug> [limit]");
return episodes(slug, parseInt(limit) || 0);
},
search: (args) => {
if (!args.length) throw new Error("Usage: search <query> [limit]");
let query, limit = 20;
const last = args[args.length - 1];
if (/^\d+$/.test(last)) {
limit = parseInt(last, 10);
query = args.slice(0, -1).join(" ");
} else {
query = args.join(" ");
}
return search(query, limit);
},
};
async function main() {
const [,, cmd, ...args] = process.argv;
if (!cmd || !COMMANDS[cmd]) {
console.error(`Usage: node oploverz.js [${Object.keys(COMMANDS).join("|")}] [...args]`);
console.error(" node oploverz.js home");
console.error(" node oploverz.js series [page] [sort] [genre] [limit]");
console.error(" node oploverz.js detail <slug>");
console.error(" node oploverz.js watch <slug> <episode>");
console.error(" node oploverz.js episodes <slug> [limit]");
console.error(" node oploverz.js search <query> [limit]");
process.exit(1);
}
try {
const result = await COMMANDS[cmd](args);
console.log(JSON.stringify(result, null, 2));
} catch (e) {
console.error("[error]", e.message);
if (e.response) console.error(`HTTP ${e.response.status} → ${e.config?.url}`);
process.exit(1);
}
}
if (import.meta.url === `file://${process.argv[1]}`) {
main();
}
export {
BASE,
BACKAPI,
http,
AD_DOMAINS,
isClean,
decodeSvelteFlat,
fetchDataJson,
fetchHTML,
fullUrl,
fmtStreamUrls,
fmtDownloads,
fmtSeries,
fmtEpisodeCard,
home,
seriesList,
detail,
watch,
episodes,
search,
COMMANDS,
main,
};Rating
Gimana snippet ini menurutmu?
Embed ke website / blog
<iframe src="https://qrtzcode.vercel.app/api/embed/anime/oploverz" style="width:100%;height:400px;border:none;border-radius:12px;"></iframe>