window.MANGA_API = (function () { var RATE_MSG = 'MangaDex đang giới hạn yêu cầu. Vui lòng thử lại sau'; var RATING_SAFE = '&contentRating[]=safe&contentRating[]=suggestive'; var RATING_ALL = RATING_SAFE + '&contentRating[]=erotica&contentRating[]=pornographic'; var FEED_LIMIT = 100; function api(url) { function request() { return fetch(window.MD_WORKER + url).then(function (r) { if (r.status === 404) throw { notFound: true }; if (r.status === 429) throw { rateLimited: true }; if (r.status >= 500) throw { serverError: true }; if (!r.ok) return r.text().then(function (t) { throw new Error('HTTP ' + r.status + (t ? ': ' + t : '')); }); return r.json(); }); } return request().catch(function (e) { if (!(e && e.rateLimited)) throw e; return new Promise(function (resolve) { setTimeout(resolve, 2000); }).then(request); }); } function contentRatingParam(nsfw) { return nsfw ? RATING_ALL : RATING_SAFE; } function feedUrl(mangaId, lang, nsfw, offset) { return '/manga/' + mangaId + '/feed?limit=' + FEED_LIMIT + '&offset=' + offset + '&order[chapter]=asc&includes[]=scanlation_group' + (lang && lang !== 'all' ? '&translatedLanguage[]=' + lang : '') + contentRatingParam(nsfw); } function fetchLang(mangaId, lang, nsfw) { var all = []; var offset = 0; function page() { return api(feedUrl(mangaId, lang, nsfw, offset)).then(function (j) { all = all.concat(j.data || []); offset += FEED_LIMIT; if (j.data && j.data.length === FEED_LIMIT) return page(); return all; }); } return page(); } function chooseChapters(mangaId, nsfw, want) { var w = want || 'vi'; return fetchLang(mangaId, w, nsfw).then(function (chs) { if (chs.length) return { lang: w, chapters: chs }; if (w === 'vi') { return fetchLang(mangaId, 'en', nsfw).then(function (en) { if (en.length) return { lang: 'en', chapters: en }; return fetchLang(mangaId, 'all', nsfw).then(function (all) { return { lang: 'all', chapters: all }; }); }); } if (w === 'en') { return fetchLang(mangaId, 'all', nsfw).then(function (all) { return { lang: 'all', chapters: all }; }); } return { lang: w, chapters: chs }; }); } function chapterPages(chapterId) { return api('/at-home/server/' + chapterId).then(function (j) { return { base: j.baseUrl, hash: j.chapter && j.chapter.hash, files: (j.chapter && j.chapter.data) || [], saver: (j.chapter && j.chapter.dataSaver) || [] }; }); } function pageSrc(base, hash, file, saver) { var direct = base + (saver ? '/data-saver/' : '/data/') + hash + '/' + file; if (window.MD_WORKER) { var workerBase = String(window.MD_WORKER).replace(/\/+$/, ''); return workerBase + '/img?u=' + encodeURIComponent(direct); } return direct; } function langName(l) { return l === 'vi' ? 'Vietsub' : l === 'en' ? 'English' : 'All'; } function errorMessage(e) { if (e && e.notFound) return 'Content not found.'; if (e && e.rateLimited) return RATE_MSG; if (e && e.serverError) return 'MangaDex đang gặp lỗi tạm thời. Vui lòng thử lại sau.'; return null; } function qs(n) { var m = new RegExp('[?&]' + n + '=([^&]*)').exec(location.search); return m ? decodeURIComponent(m[1]) : null; } function chapterLabel(ch) { var a = ch.attributes || {}; var s = a.chapter ? 'Chương ' + a.chapter : 'Chương khác'; if (a.title) s += ': ' + a.title; return s; } return { RATE_MSG: RATE_MSG, api: api, fetchLang: fetchLang, chooseChapters: chooseChapters, chapterPages: chapterPages, pageSrc: pageSrc, langName: langName, errorMessage: errorMessage, qs: qs, chapterLabel: chapterLabel }; })();