Spaces:
Running
Running
Upload index.html
Browse files- index.html +8 -316
index.html
CHANGED
|
@@ -781,21 +781,6 @@
|
|
| 781 |
#dlTopBtn .nav-badge{top:-8px;right:-10px}
|
| 782 |
/* ── Player controls (Netflix/YouTube style) ── */
|
| 783 |
.vwrap{position:relative;width:100%;aspect-ratio:16/9;max-height:100%;background:#000;-webkit-user-select:none;user-select:none}
|
| 784 |
-
.jmx-ad{margin:14px 12px;position:relative}
|
| 785 |
-
.jmx-ad-l{font-size:10px;letter-spacing:.6px;text-transform:uppercase;color:var(--muted,#8a8a8a);margin:0 0 4px 2px}
|
| 786 |
-
.jmx-ad-b{width:100%;overflow:hidden;border-radius:10px;background:rgba(255,255,255,.04)}
|
| 787 |
-
.jmx-ad-b iframe{border:0;display:block;transform-origin:0 0;background:transparent}
|
| 788 |
-
.jmx-noad .jmx-sb{display:none!important}
|
| 789 |
-
.jmx-pre-fixed{position:fixed!important;inset:0;z-index:100000!important}
|
| 790 |
-
.jmx-pre{position:absolute;inset:0;z-index:9999;background:#000;display:flex;align-items:center;justify-content:center}
|
| 791 |
-
.jmx-pre video{width:100%;height:100%;object-fit:contain;background:#000}
|
| 792 |
-
.jmx-pre-top{position:absolute;left:0;right:0;top:0;display:flex;justify-content:space-between;align-items:center;padding:10px 12px;background:linear-gradient(rgba(0,0,0,.65),transparent);font-size:12px;color:#fff;pointer-events:none}
|
| 793 |
-
.jmx-pre-btns{position:absolute;right:10px;bottom:14px;display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end}
|
| 794 |
-
.jmx-pre-btn{border:1px solid rgba(255,255,255,.4);background:rgba(0,0,0,.7);color:#fff;border-radius:999px;padding:8px 14px;font-size:13px;font-weight:700;cursor:pointer}
|
| 795 |
-
.jmx-pre-btn[hidden]{display:none}
|
| 796 |
-
.jmx-pre-btn:focus{outline:2px solid var(--accent2);outline-offset:2px}
|
| 797 |
-
.jmx-pre-bar{position:absolute;left:0;right:0;bottom:0;height:3px;background:rgba(255,255,255,.2)}
|
| 798 |
-
.jmx-pre-bar i{display:block;height:100%;width:0;background:var(--accent)}
|
| 799 |
.vwrap video{width:100%;height:100%;max-height:none;aspect-ratio:auto;object-fit:contain}
|
| 800 |
.vwrap:fullscreen,.vwrap:-webkit-full-screen{aspect-ratio:auto;max-height:none;height:100%}
|
| 801 |
.vwrap .seek-zone{top:0;bottom:64px}
|
|
@@ -2072,7 +2057,7 @@ async function setKidsMode(on){
|
|
| 2072 |
if (!ok) return false;
|
| 2073 |
}
|
| 2074 |
}
|
| 2075 |
-
setSettings({ kidsMode: !!on });
|
| 2076 |
return true;
|
| 2077 |
}
|
| 2078 |
function kidsModeFilter(list){
|
|
@@ -2821,7 +2806,7 @@ const I18N_EXTRA7 = {"sw": {"not_live_msg": "Haipatikani kwa LIVE", "vol_warn":
|
|
| 2821 |
Object.keys(I18N_EXTRA7).forEach(l => { I18N[l] = Object.assign(I18N[l] || {}, I18N_EXTRA7[l]); });
|
| 2822 |
const I18N_EXTRA8 = {"sw": {"dq_paused_resume": "Imesimamishwa — gusa ↻ kuendelea"}, "en": {"dq_paused_resume": "Paused — tap ↻ to resume"}, "ar": {"dq_paused_resume": "متوقف مؤقتاً — اضغط ↻ للمتابعة"}, "fr": {"dq_paused_resume": "En pause — touchez ↻ pour reprendre"}};
|
| 2823 |
Object.keys(I18N_EXTRA8).forEach(l => { I18N[l] = Object.assign(I18N[l] || {}, I18N_EXTRA8[l]); });
|
| 2824 |
-
const I18N_EXTRA10 = {"sw": {
|
| 2825 |
Object.keys(I18N_EXTRA10).forEach(l => { I18N[l] = Object.assign(I18N[l] || {}, I18N_EXTRA10[l]); });
|
| 2826 |
function T(k, v) { return t(k, v); }
|
| 2827 |
// Maandishi yaliyoandikwa kwenye HTML kupitia data-i18n / data-i18n-ph / data-i18n-title
|
|
@@ -3239,282 +3224,6 @@ function renderSkeletonRails(count = 3){
|
|
| 3239 |
for (let i = 0; i < count; i++) railsEl.appendChild(skeletonRail());
|
| 3240 |
}
|
| 3241 |
|
| 3242 |
-
// ── Matangazo (Adsterra): banner + native kwenye Home ──
|
| 3243 |
-
// Kila tangazo linaendeshwa ndani ya iframe iliyotengwa (sandbox, bila allow-same-origin) ili msimbo wa mtandao wa matangazo
|
| 3244 |
-
// usiweze kusoma akaunti/token za app. Zima yote: JM_CONFIG.ADS_ENABLED = false kwenye config.js. Hali ya Mtoto haionyeshi matangazo.
|
| 3245 |
-
const JMX_ADS = {
|
| 3246 |
-
banner: { host: 'https://bancadeltempoidea.org', key: '2085a0d997c0512303b51c5bd2a70df3', w: 468, h: 60 },
|
| 3247 |
-
social: { src: 'https://bancadeltempoidea.org/14/e742797728bf0e110ac81ff2ffe58ce0' },
|
| 3248 |
-
native: { src: 'https://bancadeltempoidea.org/21/87f4e31e09a568f8e6c9f0e1f50c2b8d', id: 'container-87f4e31e09a568f8e6c9f0e1f50c2b8d', h: 300 },
|
| 3249 |
-
};
|
| 3250 |
-
function jmxAdsOn(){
|
| 3251 |
-
try { if (window.JM_CONFIG && window.JM_CONFIG.ADS_ENABLED === false) return false; } catch (_) {}
|
| 3252 |
-
return !isKidsMode() && navigator.onLine !== false;
|
| 3253 |
-
}
|
| 3254 |
-
function jmxAdSlot(kind){
|
| 3255 |
-
if (!jmxAdsOn()) return null;
|
| 3256 |
-
const c = JMX_ADS[kind]; if (!c) return null;
|
| 3257 |
-
const wrap = document.createElement('div'); wrap.className = 'jmx-ad';
|
| 3258 |
-
wrap.innerHTML = '<div class="jmx-ad-l">' + esc(T('ad_label')) + '</div><div class="jmx-ad-b"></div>';
|
| 3259 |
-
const box = wrap.querySelector('.jmx-ad-b'), ifr = document.createElement('iframe');
|
| 3260 |
-
ifr.setAttribute('sandbox', 'allow-scripts allow-popups allow-popups-to-escape-sandbox'); ifr.setAttribute('scrolling', 'no'); ifr.loading = 'lazy'; ifr.dataset.kind = kind;
|
| 3261 |
-
const head = '<!doctype html><html><head><meta charset="utf-8"><base target="_blank"><style>html,body{margin:0;background:transparent;overflow:hidden}</style></head><body>';
|
| 3262 |
-
// Baada ya sekunde 7 iframe inaripoti kama tangazo limepakia (ok) na urefu wake; kama tupu, nafasi inaondolewa
|
| 3263 |
-
const probe = '<script>setTimeout(function(){try{var ok=!!document.body.querySelector("iframe,img,ins,a,video,canvas,div>*");parent.postMessage({jmxAd:1,ok:ok,h:document.documentElement.scrollHeight},"*")}catch(e){}},7000)<\/script>';
|
| 3264 |
-
if (kind === 'banner') {
|
| 3265 |
-
ifr.width = c.w; ifr.height = c.h;
|
| 3266 |
-
ifr.srcdoc = head + '<script>atOptions = { "key": "' + c.key + '", "format": "iframe", "height": ' + c.h + ', "width": ' + c.w + ', "params": {} };<\/script><script src="' + c.host + '/22/' + c.key + '"><\/script>' + probe + '</body></html>';
|
| 3267 |
-
const fit = () => { const k = Math.min(1, (box.clientWidth || (window.innerWidth - 24)) / c.w); ifr.style.transform = 'scale(' + k + ')'; box.style.height = Math.round(c.h * k) + 'px'; };
|
| 3268 |
-
requestAnimationFrame(fit); window.addEventListener('resize', fit);
|
| 3269 |
-
} else {
|
| 3270 |
-
ifr.style.width = '100%'; ifr.height = c.h;
|
| 3271 |
-
ifr.srcdoc = head + '<div id="' + c.id + '"></div><script async data-cfasync="false" src="' + c.src + '"><\/script>' + probe + '</body></html>';
|
| 3272 |
-
}
|
| 3273 |
-
box.appendChild(ifr);
|
| 3274 |
-
return wrap;
|
| 3275 |
-
}
|
| 3276 |
-
window.addEventListener('message', e => {
|
| 3277 |
-
const d = e.data; if (!d || d.jmxAd !== 1) return;
|
| 3278 |
-
const ifr = [...document.querySelectorAll('.jmx-ad iframe')].find(f => f.contentWindow === e.source); if (!ifr) return;
|
| 3279 |
-
if (!d.ok) ifr.closest('.jmx-ad').remove();
|
| 3280 |
-
else if (ifr.dataset.kind === 'native' && d.h > 20) ifr.height = Math.min(d.h, 420);
|
| 3281 |
-
});
|
| 3282 |
-
// Social Bar: lazima iendeshwe kwenye ukurasa mkuu (haiwezi kutengwa kwenye iframe). Inafichwa player ikiwa wazi na Hali ya Mtoto ikiwa imewashwa.
|
| 3283 |
-
let __jmxSb = false;
|
| 3284 |
-
function jmxSyncAds(){ try { document.documentElement.classList.toggle('jmx-noad', isKidsMode() || playerEl.classList.contains('on')); } catch (_) {} }
|
| 3285 |
-
function jmxSocialBar(){
|
| 3286 |
-
if (__jmxSb || !jmxAdsOn() || !JMX_ADS.social) return;
|
| 3287 |
-
__jmxSb = true;
|
| 3288 |
-
const known = new Set(document.body.children);
|
| 3289 |
-
new MutationObserver(ms => ms.forEach(m => m.addedNodes.forEach(n => {
|
| 3290 |
-
if (n.nodeType === 1 && n.parentNode === document.body && !known.has(n)) { known.add(n); n.classList.add('jmx-sb'); }
|
| 3291 |
-
}))).observe(document.body, { childList: true });
|
| 3292 |
-
new MutationObserver(jmxSyncAds).observe(playerEl, { attributes: true, attributeFilter: ['class'] });
|
| 3293 |
-
jmxSyncAds();
|
| 3294 |
-
const sc = document.createElement('script'); sc.async = true; sc.setAttribute('data-cfasync', 'false'); sc.src = JMX_ADS.social.src; document.body.appendChild(sc);
|
| 3295 |
-
}
|
| 3296 |
-
// ── Video Ads (VAST) — HilltopAds ──
|
| 3297 |
-
// Pre-roll: kila filamu/series/Live TV/mechi inapoanza (pamoja na kipindi kinachofuata).
|
| 3298 |
-
// Mid-roll: kila dakika 10 za kutazama (kama YouTube). Download: tangazo kabla ya kuanza (juu 2 kwa download nyingi).
|
| 3299 |
-
// HAZIONEKANI: offline (zilizopakuliwa), trailer, Hali ya Mtoto. Tangazo likishindikana kwa sababu yoyote, video inaendelea moja kwa moja.
|
| 3300 |
-
// Zima kabisa: JM_CONFIG.ADS_ENABLED = false, au acha orodha ya JMX_VAST.urls tupu.
|
| 3301 |
-
const JMX_VAST = {
|
| 3302 |
-
// Kampuni za matangazo ya video (VAST). Ongeza kiungo kipya kwenye orodha hii. Zinabadilishana kila tangazo (round-robin);
|
| 3303 |
-
// kampuni moja ikikosa tangazo (hakuna fill/hitilafu), inayofuata inajaribiwa mara moja.
|
| 3304 |
-
urls: [
|
| 3305 |
-
'https://sadpicture.com/dMmlFsz.dhGcNovMZkGwUp/teFmT9hugZPUjl/kUPMT-c/1IM/TQAmxdN/j_kYt/NqzCUsxNM/DREX3AMdwv', // HilltopAds
|
| 3306 |
-
// 'PAKA_VAST_URL_YA_KAMPUNI_YA_PILI_HAPA', // mf. ExoClick / RichAds
|
| 3307 |
-
],
|
| 3308 |
-
fetchMs: 6000, // muda wa juu wa kupata VAST XML
|
| 3309 |
-
startMs: 9000, // muda wa juu wa video ya tangazo kuanza kucheza
|
| 3310 |
-
skipAfter: 5, // sekunde ya kuruhusu "Ruka" kama VAST haijaweka skipoffset
|
| 3311 |
-
maxWrap: 4,
|
| 3312 |
-
midrollEverySec: 10 * 60, // tangazo katikati ya video: kila sekunde hizi za kutazama
|
| 3313 |
-
downloadAds: 2, // idadi ya juu ya matangazo kwa download moja au nyingi kwa pamoja
|
| 3314 |
-
};
|
| 3315 |
-
let __jmxPre = null; // tangazo linaloendelea sasa: { end(reason) }
|
| 3316 |
-
let __jmxRR = 0; // round-robin: kampuni ipi inaanza tangazo linalofuata
|
| 3317 |
-
function jmxVastUrls(){ return (JMX_VAST.urls || []).filter(u => u && /^https?:\/\//i.test(u)); }
|
| 3318 |
-
// Hupata VAST kwa kuzunguka kampuni zote; ya kwanza yenye tangazo halisi inashinda.
|
| 3319 |
-
async function jmxVastPick(){
|
| 3320 |
-
const L = jmxVastUrls(); if (!L.length) throw new Error('no_urls');
|
| 3321 |
-
const start = __jmxRR++ % L.length; let lastErr = null;
|
| 3322 |
-
for (let k = 0; k < L.length; k++) {
|
| 3323 |
-
try { return await jmxVastLoad(L[(start + k) % L.length], 0, { imps: [], errs: [], clickTr: [], track: {}, media: '', click: '', dur: null, skipoff: '' }); }
|
| 3324 |
-
catch (e) { lastErr = e; }
|
| 3325 |
-
}
|
| 3326 |
-
throw lastErr || new Error('no_fill');
|
| 3327 |
-
}
|
| 3328 |
-
let __jmxPrePromise = null; // tangazo la kuanza-kucheza linalosubiriwa na player
|
| 3329 |
-
function jmxPrerollAbort(){ try { if (__jmxPre) __jmxPre.end('aborted'); } catch (_) {} }
|
| 3330 |
-
// Player huita hii kabla ya kuanza kucheza: inasubiri tangazo likiisha. false = mtumiaji alibadilisha/alifunga.
|
| 3331 |
-
async function jmxGate(){
|
| 3332 |
-
const p = __jmxPrePromise; if (!p) return true;
|
| 3333 |
-
return (await p) !== 'aborted';
|
| 3334 |
-
}
|
| 3335 |
-
function jmxStartForPlayer(){
|
| 3336 |
-
const p = jmxPreroll({});
|
| 3337 |
-
__jmxPrePromise = p;
|
| 3338 |
-
p.then(() => { if (__jmxPrePromise === p) __jmxPrePromise = null; });
|
| 3339 |
-
}
|
| 3340 |
-
function jmxVastSecs(s){
|
| 3341 |
-
s = (s || '').trim();
|
| 3342 |
-
const m = /^(\d+):(\d+):(\d+(?:\.\d+)?)$/.exec(s);
|
| 3343 |
-
return m ? (+m[1]) * 3600 + (+m[2]) * 60 + parseFloat(m[3]) : null;
|
| 3344 |
-
}
|
| 3345 |
-
function jmxPing(u, code){
|
| 3346 |
-
if (!u) return;
|
| 3347 |
-
try {
|
| 3348 |
-
u = u.replace(/\[(CACHEBUSTING|TIMESTAMP|RANDOM)\]/g, () => String(Date.now()) + Math.floor(Math.random() * 1e6)).replace(/\[ERRORCODE\]/g, String(code || 900));
|
| 3349 |
-
const i = new Image(); i.referrerPolicy = 'no-referrer-when-downgrade'; i.src = u;
|
| 3350 |
-
} catch (_) {}
|
| 3351 |
-
}
|
| 3352 |
-
async function jmxVastLoad(url, depth, acc){
|
| 3353 |
-
const ctl = new AbortController(), to = setTimeout(() => ctl.abort(), JMX_VAST.fetchMs);
|
| 3354 |
-
let txt;
|
| 3355 |
-
try {
|
| 3356 |
-
const r = await fetch(url, { signal: ctl.signal, credentials: 'omit' });
|
| 3357 |
-
if (!r.ok) throw new Error('http ' + r.status);
|
| 3358 |
-
txt = await r.text();
|
| 3359 |
-
} finally { clearTimeout(to); }
|
| 3360 |
-
const doc = new DOMParser().parseFromString(txt, 'text/xml');
|
| 3361 |
-
if (doc.getElementsByTagName('parsererror').length) throw new Error('xml');
|
| 3362 |
-
const ad = doc.getElementsByTagName('Ad')[0];
|
| 3363 |
-
if (!ad) throw new Error('empty');
|
| 3364 |
-
const tx = el => ((el && el.textContent) || '').trim();
|
| 3365 |
-
const all = tag => Array.from(ad.getElementsByTagName(tag));
|
| 3366 |
-
all('Impression').forEach(e => { const u = tx(e); if (u) acc.imps.push(u); });
|
| 3367 |
-
all('Error').forEach(e => { const u = tx(e); if (u) acc.errs.push(u); });
|
| 3368 |
-
all('ClickTracking').forEach(e => { const u = tx(e); if (u) acc.clickTr.push(u); });
|
| 3369 |
-
all('Tracking').forEach(e => { const ev = e.getAttribute('event'), u = tx(e); if (ev && u) (acc.track[ev] = acc.track[ev] || []).push(u); });
|
| 3370 |
-
if (ad.getElementsByTagName('Wrapper')[0]) {
|
| 3371 |
-
const next = tx(ad.getElementsByTagName('VASTAdTagURI')[0]);
|
| 3372 |
-
if (!next || depth >= JMX_VAST.maxWrap) throw new Error('wrapper');
|
| 3373 |
-
return jmxVastLoad(next, depth + 1, acc);
|
| 3374 |
-
}
|
| 3375 |
-
const lin = all('Linear')[0];
|
| 3376 |
-
if (!lin) throw new Error('no_linear');
|
| 3377 |
-
const files = all('MediaFile').map(e => ({
|
| 3378 |
-
url: tx(e), type: (e.getAttribute('type') || '').toLowerCase(), w: +e.getAttribute('width') || 0,
|
| 3379 |
-
prog: !/streaming/i.test(e.getAttribute('delivery') || 'progressive'),
|
| 3380 |
-
})).filter(f => f.url && /video\/(mp4|webm)/.test(f.type) && f.prog);
|
| 3381 |
-
if (!files.length) throw new Error('no_media');
|
| 3382 |
-
const can = f => { try { return !!document.createElement('video').canPlayType(f.type); } catch (_) { return true; } };
|
| 3383 |
-
const ok = files.filter(can); const pool = ok.length ? ok : files;
|
| 3384 |
-
pool.sort((a, b) => Math.abs((a.w || 640) - 720) - Math.abs((b.w || 640) - 720));
|
| 3385 |
-
acc.media = pool[0].url;
|
| 3386 |
-
acc.click = tx(all('ClickThrough')[0]) || '';
|
| 3387 |
-
acc.dur = jmxVastSecs(tx(all('Duration')[0]));
|
| 3388 |
-
acc.skipoff = lin.getAttribute('skipoffset') || '';
|
| 3389 |
-
return acc;
|
| 3390 |
-
}
|
| 3391 |
-
// opts: { fixed: skrini nzima juu ya app (download), mid: katikati ya video, onReady: ikaitwa tangazo linapokuwa tayari kuonyeshwa }
|
| 3392 |
-
function jmxPreroll(opts){
|
| 3393 |
-
opts = opts || {};
|
| 3394 |
-
if (!jmxVastUrls().length || !jmxAdsOn()) return Promise.resolve('skipped');
|
| 3395 |
-
if (!opts.fixed && playerEl.classList.contains('mini')) return Promise.resolve('skipped');
|
| 3396 |
-
jmxPrerollAbort();
|
| 3397 |
-
return new Promise(resolve => {
|
| 3398 |
-
let ov = null, av = null, host = null, vast = null, done = false, fired = {}, timers = [], mo = null, hostPos = null;
|
| 3399 |
-
const track = (ev) => { if (vast && vast.track[ev]) vast.track[ev].forEach(u => jmxPing(u)); };
|
| 3400 |
-
const once = (ev) => { if (fired[ev]) return; fired[ev] = 1; track(ev); };
|
| 3401 |
-
const end = (reason) => {
|
| 3402 |
-
if (done) return; done = true;
|
| 3403 |
-
timers.forEach(clearTimeout); timers.forEach(clearInterval);
|
| 3404 |
-
try { if (mo) mo.disconnect(); } catch (_) {}
|
| 3405 |
-
try { if (av) { av.pause(); av.removeAttribute('src'); av.load(); } } catch (_) {}
|
| 3406 |
-
try { if (ov && ov.parentNode) ov.parentNode.removeChild(ov); } catch (_) {}
|
| 3407 |
-
try { if (host && hostPos != null) host.style.position = hostPos; } catch (_) {}
|
| 3408 |
-
if (__jmxPre && __jmxPre.end === end) __jmxPre = null;
|
| 3409 |
-
resolve(reason);
|
| 3410 |
-
};
|
| 3411 |
-
__jmxPre = { end };
|
| 3412 |
-
(async () => {
|
| 3413 |
-
try {
|
| 3414 |
-
vast = await jmxVastPick();
|
| 3415 |
-
} catch (e) { return end('failed'); }
|
| 3416 |
-
if (done) return;
|
| 3417 |
-
if (opts.fixed) host = document.body;
|
| 3418 |
-
else {
|
| 3419 |
-
if (!playerEl.classList.contains('on')) return end('failed');
|
| 3420 |
-
host = document.fullscreenElement || stage;
|
| 3421 |
-
if (host && host.tagName === 'VIDEO') { try { document.exitFullscreen(); } catch (_) {} host = stage; }
|
| 3422 |
-
if (!host) return end('failed');
|
| 3423 |
-
if (getComputedStyle(host).position === 'static') { hostPos = host.style.position; host.style.position = 'relative'; }
|
| 3424 |
-
}
|
| 3425 |
-
try { if (opts.onReady) opts.onReady(); } catch (_) {}
|
| 3426 |
-
ov = document.createElement('div'); ov.className = 'jmx-pre' + (opts.fixed ? ' jmx-pre-fixed' : '');
|
| 3427 |
-
ov.innerHTML = '<video playsinline webkit-playsinline preload="auto"></video>' +
|
| 3428 |
-
'<div class="jmx-pre-top"><span>' + esc(T('ad_label')) + '</span><span class="jmx-pre-t"></span></div>' +
|
| 3429 |
-
'<div class="jmx-pre-btns"><button type="button" class="jmx-pre-btn jmx-pre-mute" hidden>🔇</button>' +
|
| 3430 |
-
'<button type="button" class="jmx-pre-btn jmx-pre-open" hidden>' + esc(T('ad_open')) + '</button>' +
|
| 3431 |
-
'<button type="button" class="jmx-pre-btn jmx-pre-skip" hidden></button></div>' +
|
| 3432 |
-
'<div class="jmx-pre-bar"><i></i></div>';
|
| 3433 |
-
host.appendChild(ov);
|
| 3434 |
-
av = ov.querySelector('video');
|
| 3435 |
-
const tEl = ov.querySelector('.jmx-pre-t'), skipB = ov.querySelector('.jmx-pre-skip'), openB = ov.querySelector('.jmx-pre-open'),
|
| 3436 |
-
muteB = ov.querySelector('.jmx-pre-mute'), bar = ov.querySelector('.jmx-pre-bar i');
|
| 3437 |
-
// Kulinda: mtumiaji akifunga player, au kitu kikifuta tangazo, tangazo linaisha
|
| 3438 |
-
if (!opts.fixed) {
|
| 3439 |
-
mo = new MutationObserver(() => { if (!playerEl.classList.contains('on') || !ov.isConnected) end(ov.isConnected ? 'aborted' : 'done'); });
|
| 3440 |
-
mo.observe(playerEl, { attributes: true, attributeFilter: ['class'] });
|
| 3441 |
-
}
|
| 3442 |
-
timers.push(setTimeout(() => { if (!fired.__playing) { vast.errs.forEach(u => jmxPing(u, 402)); end('failed'); } }, JMX_VAST.startMs));
|
| 3443 |
-
av.addEventListener('error', () => { vast.errs.forEach(u => jmxPing(u, 405)); end('failed'); });
|
| 3444 |
-
av.addEventListener('playing', () => {
|
| 3445 |
-
if (fired.__playing) return; fired.__playing = 1;
|
| 3446 |
-
vast.imps.forEach(u => jmxPing(u)); once('creativeView'); once('start');
|
| 3447 |
-
if (vast.click) openB.hidden = false;
|
| 3448 |
-
});
|
| 3449 |
-
av.addEventListener('pause', () => { if (!av.ended && fired.__playing) track('pause'); });
|
| 3450 |
-
av.addEventListener('play', () => { if (fired.__playing) track('resume'); });
|
| 3451 |
-
av.addEventListener('ended', () => { once('complete'); end('done'); });
|
| 3452 |
-
muteB.onclick = () => { av.muted = !av.muted; muteB.textContent = av.muted ? '🔇' : '🔊'; track(av.muted ? 'mute' : 'unmute'); };
|
| 3453 |
-
openB.onclick = () => {
|
| 3454 |
-
vast.clickTr.forEach(u => jmxPing(u));
|
| 3455 |
-
try { window.open(vast.click, '_blank', 'noopener'); } catch (_) {}
|
| 3456 |
-
try { av.pause(); } catch (_) {}
|
| 3457 |
-
};
|
| 3458 |
-
skipB.onclick = () => { if (skipB.disabled) return; track('skip'); end('done'); };
|
| 3459 |
-
const tick = () => {
|
| 3460 |
-
if (!ov.isConnected) return end('done');
|
| 3461 |
-
const d = isFinite(av.duration) && av.duration > 0 ? av.duration : (vast.dur || 0), c = av.currentTime || 0;
|
| 3462 |
-
if (d) {
|
| 3463 |
-
bar.style.width = Math.min(100, c / d * 100) + '%';
|
| 3464 |
-
const left = Math.max(0, Math.ceil(d - c)); tEl.textContent = Math.floor(left / 60) + ':' + String(left % 60).padStart(2, '0');
|
| 3465 |
-
if (c >= d * .25) once('firstQuartile'); if (c >= d * .5) once('midpoint'); if (c >= d * .75) once('thirdQuartile');
|
| 3466 |
-
}
|
| 3467 |
-
let so = jmxVastSecs(vast.skipoff);
|
| 3468 |
-
if (so == null && /%$/.test(vast.skipoff) && d) so = d * parseFloat(vast.skipoff) / 100;
|
| 3469 |
-
if (so == null) so = JMX_VAST.skipAfter;
|
| 3470 |
-
if (d && so >= d) so = Math.max(0, d - 1);
|
| 3471 |
-
skipB.hidden = false;
|
| 3472 |
-
if (c >= so) { skipB.disabled = false; skipB.textContent = T('ad_skip'); }
|
| 3473 |
-
else { skipB.disabled = true; skipB.textContent = T('ad_skip_in', { n: Math.ceil(so - c) }); }
|
| 3474 |
-
};
|
| 3475 |
-
timers.push(setInterval(tick, 250));
|
| 3476 |
-
av.src = vast.media;
|
| 3477 |
-
av.muted = false;
|
| 3478 |
-
const pr = av.play();
|
| 3479 |
-
if (pr && pr.catch) pr.catch(() => { av.muted = true; muteB.hidden = false; muteB.textContent = '🔇'; av.play().catch(() => { vast.errs.forEach(u => jmxPing(u, 400)); end('failed'); }); });
|
| 3480 |
-
setTimeout(() => { if (!done) { muteB.hidden = false; muteB.textContent = av.muted ? '🔇' : '🔊'; } }, 800);
|
| 3481 |
-
})();
|
| 3482 |
-
});
|
| 3483 |
-
}
|
| 3484 |
-
// Tangazo katikati ya video (kama YouTube): kila JMX_VAST.midrollEverySec za kutazama kweli (si wakati imesimama).
|
| 3485 |
-
function jmxMidroll(v){
|
| 3486 |
-
if (!jmxVastUrls().length || !v || v.__jmxMid) return;
|
| 3487 |
-
v.__jmxMid = 1;
|
| 3488 |
-
let acc = 0, busy = false, adOn = false;
|
| 3489 |
-
v.addEventListener('play', () => { if (adOn) { try { v.pause(); } catch (_) {} } });
|
| 3490 |
-
const iv = setInterval(async () => {
|
| 3491 |
-
if (!v.isConnected) return clearInterval(iv);
|
| 3492 |
-
if (busy || v.paused || v.ended || v.seeking || v.readyState < 3 || document.hidden) return;
|
| 3493 |
-
if (!jmxAdsOn() || playerEl.classList.contains('mini')) return;
|
| 3494 |
-
if (++acc < JMX_VAST.midrollEverySec) return;
|
| 3495 |
-
acc = 0; busy = true;
|
| 3496 |
-
let r = 'failed';
|
| 3497 |
-
try { r = await jmxPreroll({ mid: true, onReady: () => { adOn = true; try { v.pause(); } catch (_) {} } }); } catch (_) {}
|
| 3498 |
-
adOn = false; busy = false;
|
| 3499 |
-
if (!v.isConnected || r === 'aborted') return;
|
| 3500 |
-
try { // Live: rudi kwenye wakati wa sasa, si mahali ulipoacha
|
| 3501 |
-
if (!isFinite(v.duration)) {
|
| 3502 |
-
if (hls && hls.liveSyncPosition) v.currentTime = hls.liveSyncPosition;
|
| 3503 |
-
else if (shakaPlayer && shakaPlayer.isLive && shakaPlayer.isLive()) v.currentTime = shakaPlayer.seekRange().end;
|
| 3504 |
-
}
|
| 3505 |
-
} catch (_) {}
|
| 3506 |
-
if (v.paused) v.play().catch(() => {});
|
| 3507 |
-
}, 1000);
|
| 3508 |
-
}
|
| 3509 |
-
// Download: tangazo 1 kwa download moja; kwa nyingi kwa pamoja (mf. 5) matangazo yasizidi JMX_VAST.downloadAds (2).
|
| 3510 |
-
async function jmxDownloadAds(n){
|
| 3511 |
-
if (!jmxVastUrls().length || !jmxAdsOn()) return;
|
| 3512 |
-
const times = Math.max(1, Math.min(JMX_VAST.downloadAds, n || 1));
|
| 3513 |
-
for (let i = 0; i < times; i++) {
|
| 3514 |
-
const r = await jmxPreroll({ fixed: true });
|
| 3515 |
-
if (r !== 'done') break;
|
| 3516 |
-
}
|
| 3517 |
-
}
|
| 3518 |
function renderRails(sections, gridMode = false) {
|
| 3519 |
railsEl.innerHTML = '';
|
| 3520 |
if (isKidsMode()) sections = sections.map(sec => ({ ...sec, items: kidsModeFilter(sec.items) })).filter(sec => sec.items.length);
|
|
@@ -3523,7 +3232,7 @@ function renderRails(sections, gridMode = false) {
|
|
| 3523 |
fadeInScreen(railsEl);
|
| 3524 |
return;
|
| 3525 |
}
|
| 3526 |
-
sections.forEach((sec
|
| 3527 |
const wrap = document.createElement('div');
|
| 3528 |
wrap.className = 'rail';
|
| 3529 |
const scroll = document.createElement('div');
|
|
@@ -3532,9 +3241,7 @@ function renderRails(sections, gridMode = false) {
|
|
| 3532 |
wrap.innerHTML = `<div class="rail-title">${esc(sec.title)}</div>`;
|
| 3533 |
wrap.appendChild(scroll);
|
| 3534 |
railsEl.appendChild(wrap);
|
| 3535 |
-
if (!gridMode && (si === 1 || si === 4)) { const ad = jmxAdSlot(si === 1 ? 'banner' : 'native'); if (ad) railsEl.appendChild(ad); } // banner baada ya rail ya 2, native baada ya ya 5
|
| 3536 |
});
|
| 3537 |
-
if (!gridMode) setTimeout(jmxSocialBar, 4000);
|
| 3538 |
fadeInScreen(railsEl);
|
| 3539 |
}
|
| 3540 |
|
|
@@ -4068,7 +3775,6 @@ function renderTranslatedDetail(d) {
|
|
| 4068 |
if (d.isSeries || d.isParts) { openTranslatedDownloadSheet(d); return; }
|
| 4069 |
const url = urlOf(null, null);
|
| 4070 |
if (!url) { showToast(t('tr_no_dl')); return; }
|
| 4071 |
-
try { await jmxDownloadAds(1); } catch (_) {}
|
| 4072 |
queueTranslatedDownload(d, url, '');
|
| 4073 |
};
|
| 4074 |
document.getElementById('trShareBtn').onclick = () => shareTranslatedTitle(d);
|
|
@@ -4109,13 +3815,12 @@ function playTranslatedUrl(url, title, playlist, meta) {
|
|
| 4109 |
stage.innerHTML = '<video id="vid" controls autoplay playsinline></video>';
|
| 4110 |
const v = document.getElementById('vid');
|
| 4111 |
attachPlayerEnhancements(v);
|
| 4112 |
-
jmxMidroll(v);
|
| 4113 |
renderSpeedChips(v); // speed (gear ⚙) sasa ipo kwenye zilizotafsiriwa pia
|
| 4114 |
if (playlist) setPlayerPlaylist(playlist); // kichupo cha pembeni: vipindi / sehemu
|
| 4115 |
ensureSound(v);
|
| 4116 |
v.addEventListener('ended', () => { const c = window.__pcPlaylist; if (c && typeof c.next === 'function') c.next(); });
|
| 4117 |
// Tangazo la video kwanza (likishindikana/likiruka, filamu inaanza mara moja)
|
| 4118 |
-
|
| 4119 |
// Route ya player: #/translated/ID/play?se=..&ep=..
|
| 4120 |
try {
|
| 4121 |
const id = currentTranslatedDetail && currentTranslatedDetail.id;
|
|
@@ -6242,7 +5947,6 @@ function stopMediaOnly(){
|
|
| 6242 |
currentBlobUrls = [];
|
| 6243 |
}
|
| 6244 |
function stopPlayer(){
|
| 6245 |
-
jmxPrerollAbort();
|
| 6246 |
playerEl.classList.remove('mini');
|
| 6247 |
clearUpNext();
|
| 6248 |
if (document.pictureInPictureElement) { document.exitPictureInPicture().catch(()=>{}); }
|
|
@@ -6259,15 +5963,12 @@ function stopPlayer(){
|
|
| 6259 |
currentResumeMeta = null;
|
| 6260 |
const pipBtn = document.getElementById('pipBtn'); if (pipBtn) pipBtn.style.display = 'none';
|
| 6261 |
}
|
| 6262 |
-
function openPlayerShell(title
|
| 6263 |
liveFb = null;
|
| 6264 |
-
jmxPrerollAbort();
|
| 6265 |
-
__jmxPrePromise = null;
|
| 6266 |
stopPlayer();
|
| 6267 |
ptitle.textContent = title;
|
| 6268 |
playerEl.classList.add('on');
|
| 6269 |
statusMsg(T('stream_searching'));
|
| 6270 |
-
if (!(opts && opts.noAd)) jmxStartForPlayer(); // tangazo la kuanza kila player ya mtandaoni (offline/trailer: noAd)
|
| 6271 |
}
|
| 6272 |
|
| 6273 |
// ════════════════════════════════════════════════════════════════
|
|
@@ -6334,12 +6035,10 @@ function collectUrls(o, out = []) {
|
|
| 6334 |
}
|
| 6335 |
|
| 6336 |
async function playHlsUrl(url, opts = {}) {
|
| 6337 |
-
if (!(await jmxGate())) return; // subiri tangazo la kuanza likiisha
|
| 6338 |
const same = !!(opts.authHeader && opts.sameOriginBase && url.startsWith(opts.sameOriginBase));
|
| 6339 |
stage.innerHTML = '<video id="vid" controls autoplay playsinline></video>';
|
| 6340 |
const v = document.getElementById('vid');
|
| 6341 |
attachPlayerEnhancements(v);
|
| 6342 |
-
jmxMidroll(v);
|
| 6343 |
ensureSound(v);
|
| 6344 |
if (window.Hls && Hls.isSupported()) {
|
| 6345 |
hls = new Hls({ xhrSetup: xhr => { if (same) xhr.setRequestHeader('Authorization', opts.authHeader); } });
|
|
@@ -6387,7 +6086,7 @@ async function openFawaMatch(item) {
|
|
| 6387 |
const urls = collectUrls(data);
|
| 6388 |
const media = urls.find(u => /\.m3u8|\.mp4/i.test(u));
|
| 6389 |
if (media) return playHlsUrl(media, {});
|
| 6390 |
-
if (urls[0]) {
|
| 6391 |
stage.innerHTML = '<pre>' + esc(JSON.stringify(data, null, 2)) + '</pre>';
|
| 6392 |
return;
|
| 6393 |
}
|
|
@@ -6775,7 +6474,6 @@ function attachContinueWatchingTracking(v){
|
|
| 6775 |
}
|
| 6776 |
|
| 6777 |
async function loadIntoVideo(pr, quality){
|
| 6778 |
-
if (!(await jmxGate())) return; // subiri tangazo la kuanza likiisha
|
| 6779 |
const url = (quality && (quality.proxyStreamUrl || quality.streamUrl)) || pr.playUrl;
|
| 6780 |
const type = (pr.streamType || '').toUpperCase();
|
| 6781 |
const gen = ++playGen;
|
|
@@ -6793,7 +6491,6 @@ async function loadIntoVideo(pr, quality){
|
|
| 6793 |
wireUpNext(v);
|
| 6794 |
wireSkipButtons(v);
|
| 6795 |
renderSpeedChips(v);
|
| 6796 |
-
jmxMidroll(v);
|
| 6797 |
|
| 6798 |
if (type === 'DASH' && window.shaka && pr.clearKey && !window.isSecureContext) {
|
| 6799 |
pcError(T('err_drm'), false);
|
|
@@ -6863,7 +6560,6 @@ async function playResultInPlayer(pr, title, resumeMeta){
|
|
| 6863 |
currentResumeMeta = resumeMeta || null;
|
| 6864 |
if (!pr) { statusMsg(T('err_no_stream')); return; }
|
| 6865 |
if (!pr.playUrl && pr.iframeUrl) {
|
| 6866 |
-
if (!(await jmxGate())) return;
|
| 6867 |
stage.innerHTML = '<iframe allowfullscreen allow="autoplay; fullscreen" src="' + esc(pr.iframeUrl) + '"></iframe>';
|
| 6868 |
return;
|
| 6869 |
}
|
|
@@ -7068,7 +6764,7 @@ function formatTrailerDuration(sec){
|
|
| 7068 |
// Hufungua trailer kwenye player ya kawaida ya app (fullscreen, na udhibiti wa kisasa),
|
| 7069 |
// badala ya video ya <video controls> ndani ya ukurasa — sawa na uzoefu wa filamu/vipindi.
|
| 7070 |
function playTrailerUrl(url, title){
|
| 7071 |
-
openPlayerShell(title || 'Trailer'
|
| 7072 |
stage.innerHTML = '<video id="vid" src="' + esc(url) + '" controls autoplay playsinline></video>';
|
| 7073 |
const v = document.getElementById('vid');
|
| 7074 |
attachPlayerEnhancements(v);
|
|
@@ -7612,7 +7308,6 @@ function wireShortsSlideEvents(el) {
|
|
| 7612 |
async function shortsDownloadCurrent(idx) {
|
| 7613 |
const item = shortsQueue[idx];
|
| 7614 |
if (!item || !item.url) { toastMsg(t('dl_short_loading')); setTimeout(() => (toastEl.textContent = ''), 2000); return; }
|
| 7615 |
-
try { await jmxDownloadAds(1); } catch (_) {}
|
| 7616 |
try {
|
| 7617 |
const subs = (item.pr && item.pr.subtitles || []).filter(s => s && s.url).map(s => ({ url: s.url, language: s.language, label: s.label }));
|
| 7618 |
const fname = `${shortsMeta.title || item.title} EP${padEp(item.ep)}.mp4`;
|
|
@@ -8905,7 +8600,7 @@ async function scanEmbeddedSubs(v, file, id){
|
|
| 8905 |
// subs: [{label, language, vtt}] — opts: { id, pick, delay } (id = movie ya maktaba ya offline)
|
| 8906 |
function playLocalVideo(url, title, subs, opts){
|
| 8907 |
opts = opts || {};
|
| 8908 |
-
openPlayerShell(title
|
| 8909 |
offCurId = opts.id || null;
|
| 8910 |
offSubDelay = Number(opts.delay) || 0;
|
| 8911 |
if (offSubScale !== 1) applySubScale();
|
|
@@ -9879,9 +9574,6 @@ async function muxJob(videoUrl, subtitles, filename, onProgress){
|
|
| 9879 |
async function realDlConfirmHandler() {
|
| 9880 |
const items = dlItemsCache.filter(it => dlSelection.has(it.key));
|
| 9881 |
if (!items.length) return;
|
| 9882 |
-
if (window.__dlAdBusy) return;
|
| 9883 |
-
window.__dlAdBusy = true;
|
| 9884 |
-
try { await jmxDownloadAds(items.length); } catch (_) {} finally { window.__dlAdBusy = false; } // tangazo kabla ya download (juu 2 kwa nyingi)
|
| 9885 |
|
| 9886 |
// Washa ruhusa ya arifa (kama mtumiaji ameiwasha kwenye Mipangilio na bado hajajibu)
|
| 9887 |
if (getSettings().downloadNotifications && typeof Notification !== 'undefined' && Notification.permission === 'default') {
|
|
|
|
| 781 |
#dlTopBtn .nav-badge{top:-8px;right:-10px}
|
| 782 |
/* ── Player controls (Netflix/YouTube style) ── */
|
| 783 |
.vwrap{position:relative;width:100%;aspect-ratio:16/9;max-height:100%;background:#000;-webkit-user-select:none;user-select:none}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 784 |
.vwrap video{width:100%;height:100%;max-height:none;aspect-ratio:auto;object-fit:contain}
|
| 785 |
.vwrap:fullscreen,.vwrap:-webkit-full-screen{aspect-ratio:auto;max-height:none;height:100%}
|
| 786 |
.vwrap .seek-zone{top:0;bottom:64px}
|
|
|
|
| 2057 |
if (!ok) return false;
|
| 2058 |
}
|
| 2059 |
}
|
| 2060 |
+
setSettings({ kidsMode: !!on });
|
| 2061 |
return true;
|
| 2062 |
}
|
| 2063 |
function kidsModeFilter(list){
|
|
|
|
| 2806 |
Object.keys(I18N_EXTRA7).forEach(l => { I18N[l] = Object.assign(I18N[l] || {}, I18N_EXTRA7[l]); });
|
| 2807 |
const I18N_EXTRA8 = {"sw": {"dq_paused_resume": "Imesimamishwa — gusa ↻ kuendelea"}, "en": {"dq_paused_resume": "Paused — tap ↻ to resume"}, "ar": {"dq_paused_resume": "متوقف مؤقتاً — اضغط ↻ للمتابعة"}, "fr": {"dq_paused_resume": "En pause — touchez ↻ pour reprendre"}};
|
| 2808 |
Object.keys(I18N_EXTRA8).forEach(l => { I18N[l] = Object.assign(I18N[l] || {}, I18N_EXTRA8[l]); });
|
| 2809 |
+
const I18N_EXTRA10 = {"sw": {}, "en": {}, "ar": {}, "fr": {}};
|
| 2810 |
Object.keys(I18N_EXTRA10).forEach(l => { I18N[l] = Object.assign(I18N[l] || {}, I18N_EXTRA10[l]); });
|
| 2811 |
function T(k, v) { return t(k, v); }
|
| 2812 |
// Maandishi yaliyoandikwa kwenye HTML kupitia data-i18n / data-i18n-ph / data-i18n-title
|
|
|
|
| 3224 |
for (let i = 0; i < count; i++) railsEl.appendChild(skeletonRail());
|
| 3225 |
}
|
| 3226 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3227 |
function renderRails(sections, gridMode = false) {
|
| 3228 |
railsEl.innerHTML = '';
|
| 3229 |
if (isKidsMode()) sections = sections.map(sec => ({ ...sec, items: kidsModeFilter(sec.items) })).filter(sec => sec.items.length);
|
|
|
|
| 3232 |
fadeInScreen(railsEl);
|
| 3233 |
return;
|
| 3234 |
}
|
| 3235 |
+
sections.forEach((sec) => {
|
| 3236 |
const wrap = document.createElement('div');
|
| 3237 |
wrap.className = 'rail';
|
| 3238 |
const scroll = document.createElement('div');
|
|
|
|
| 3241 |
wrap.innerHTML = `<div class="rail-title">${esc(sec.title)}</div>`;
|
| 3242 |
wrap.appendChild(scroll);
|
| 3243 |
railsEl.appendChild(wrap);
|
|
|
|
| 3244 |
});
|
|
|
|
| 3245 |
fadeInScreen(railsEl);
|
| 3246 |
}
|
| 3247 |
|
|
|
|
| 3775 |
if (d.isSeries || d.isParts) { openTranslatedDownloadSheet(d); return; }
|
| 3776 |
const url = urlOf(null, null);
|
| 3777 |
if (!url) { showToast(t('tr_no_dl')); return; }
|
|
|
|
| 3778 |
queueTranslatedDownload(d, url, '');
|
| 3779 |
};
|
| 3780 |
document.getElementById('trShareBtn').onclick = () => shareTranslatedTitle(d);
|
|
|
|
| 3815 |
stage.innerHTML = '<video id="vid" controls autoplay playsinline></video>';
|
| 3816 |
const v = document.getElementById('vid');
|
| 3817 |
attachPlayerEnhancements(v);
|
|
|
|
| 3818 |
renderSpeedChips(v); // speed (gear ⚙) sasa ipo kwenye zilizotafsiriwa pia
|
| 3819 |
if (playlist) setPlayerPlaylist(playlist); // kichupo cha pembeni: vipindi / sehemu
|
| 3820 |
ensureSound(v);
|
| 3821 |
v.addEventListener('ended', () => { const c = window.__pcPlaylist; if (c && typeof c.next === 'function') c.next(); });
|
| 3822 |
// Tangazo la video kwanza (likishindikana/likiruka, filamu inaanza mara moja)
|
| 3823 |
+
v.src = url;
|
| 3824 |
// Route ya player: #/translated/ID/play?se=..&ep=..
|
| 3825 |
try {
|
| 3826 |
const id = currentTranslatedDetail && currentTranslatedDetail.id;
|
|
|
|
| 5947 |
currentBlobUrls = [];
|
| 5948 |
}
|
| 5949 |
function stopPlayer(){
|
|
|
|
| 5950 |
playerEl.classList.remove('mini');
|
| 5951 |
clearUpNext();
|
| 5952 |
if (document.pictureInPictureElement) { document.exitPictureInPicture().catch(()=>{}); }
|
|
|
|
| 5963 |
currentResumeMeta = null;
|
| 5964 |
const pipBtn = document.getElementById('pipBtn'); if (pipBtn) pipBtn.style.display = 'none';
|
| 5965 |
}
|
| 5966 |
+
function openPlayerShell(title){
|
| 5967 |
liveFb = null;
|
|
|
|
|
|
|
| 5968 |
stopPlayer();
|
| 5969 |
ptitle.textContent = title;
|
| 5970 |
playerEl.classList.add('on');
|
| 5971 |
statusMsg(T('stream_searching'));
|
|
|
|
| 5972 |
}
|
| 5973 |
|
| 5974 |
// ════════════════════════════════════════════════════════════════
|
|
|
|
| 6035 |
}
|
| 6036 |
|
| 6037 |
async function playHlsUrl(url, opts = {}) {
|
|
|
|
| 6038 |
const same = !!(opts.authHeader && opts.sameOriginBase && url.startsWith(opts.sameOriginBase));
|
| 6039 |
stage.innerHTML = '<video id="vid" controls autoplay playsinline></video>';
|
| 6040 |
const v = document.getElementById('vid');
|
| 6041 |
attachPlayerEnhancements(v);
|
|
|
|
| 6042 |
ensureSound(v);
|
| 6043 |
if (window.Hls && Hls.isSupported()) {
|
| 6044 |
hls = new Hls({ xhrSetup: xhr => { if (same) xhr.setRequestHeader('Authorization', opts.authHeader); } });
|
|
|
|
| 6086 |
const urls = collectUrls(data);
|
| 6087 |
const media = urls.find(u => /\.m3u8|\.mp4/i.test(u));
|
| 6088 |
if (media) return playHlsUrl(media, {});
|
| 6089 |
+
if (urls[0]) { stage.innerHTML = '<iframe allowfullscreen allow="autoplay; fullscreen" src="' + esc(urls[0]) + '"></iframe>'; return; }
|
| 6090 |
stage.innerHTML = '<pre>' + esc(JSON.stringify(data, null, 2)) + '</pre>';
|
| 6091 |
return;
|
| 6092 |
}
|
|
|
|
| 6474 |
}
|
| 6475 |
|
| 6476 |
async function loadIntoVideo(pr, quality){
|
|
|
|
| 6477 |
const url = (quality && (quality.proxyStreamUrl || quality.streamUrl)) || pr.playUrl;
|
| 6478 |
const type = (pr.streamType || '').toUpperCase();
|
| 6479 |
const gen = ++playGen;
|
|
|
|
| 6491 |
wireUpNext(v);
|
| 6492 |
wireSkipButtons(v);
|
| 6493 |
renderSpeedChips(v);
|
|
|
|
| 6494 |
|
| 6495 |
if (type === 'DASH' && window.shaka && pr.clearKey && !window.isSecureContext) {
|
| 6496 |
pcError(T('err_drm'), false);
|
|
|
|
| 6560 |
currentResumeMeta = resumeMeta || null;
|
| 6561 |
if (!pr) { statusMsg(T('err_no_stream')); return; }
|
| 6562 |
if (!pr.playUrl && pr.iframeUrl) {
|
|
|
|
| 6563 |
stage.innerHTML = '<iframe allowfullscreen allow="autoplay; fullscreen" src="' + esc(pr.iframeUrl) + '"></iframe>';
|
| 6564 |
return;
|
| 6565 |
}
|
|
|
|
| 6764 |
// Hufungua trailer kwenye player ya kawaida ya app (fullscreen, na udhibiti wa kisasa),
|
| 6765 |
// badala ya video ya <video controls> ndani ya ukurasa — sawa na uzoefu wa filamu/vipindi.
|
| 6766 |
function playTrailerUrl(url, title){
|
| 6767 |
+
openPlayerShell(title || 'Trailer');
|
| 6768 |
stage.innerHTML = '<video id="vid" src="' + esc(url) + '" controls autoplay playsinline></video>';
|
| 6769 |
const v = document.getElementById('vid');
|
| 6770 |
attachPlayerEnhancements(v);
|
|
|
|
| 7308 |
async function shortsDownloadCurrent(idx) {
|
| 7309 |
const item = shortsQueue[idx];
|
| 7310 |
if (!item || !item.url) { toastMsg(t('dl_short_loading')); setTimeout(() => (toastEl.textContent = ''), 2000); return; }
|
|
|
|
| 7311 |
try {
|
| 7312 |
const subs = (item.pr && item.pr.subtitles || []).filter(s => s && s.url).map(s => ({ url: s.url, language: s.language, label: s.label }));
|
| 7313 |
const fname = `${shortsMeta.title || item.title} EP${padEp(item.ep)}.mp4`;
|
|
|
|
| 8600 |
// subs: [{label, language, vtt}] — opts: { id, pick, delay } (id = movie ya maktaba ya offline)
|
| 8601 |
function playLocalVideo(url, title, subs, opts){
|
| 8602 |
opts = opts || {};
|
| 8603 |
+
openPlayerShell(title);
|
| 8604 |
offCurId = opts.id || null;
|
| 8605 |
offSubDelay = Number(opts.delay) || 0;
|
| 8606 |
if (offSubScale !== 1) applySubScale();
|
|
|
|
| 9574 |
async function realDlConfirmHandler() {
|
| 9575 |
const items = dlItemsCache.filter(it => dlSelection.has(it.key));
|
| 9576 |
if (!items.length) return;
|
|
|
|
|
|
|
|
|
|
| 9577 |
|
| 9578 |
// Washa ruhusa ya arifa (kama mtumiaji ameiwasha kwenye Mipangilio na bado hajajibu)
|
| 9579 |
if (getSettings().downloadNotifications && typeof Notification !== 'undefined' && Notification.permission === 'default') {
|