<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html b:version='2' class='v2' expr:dir='data:blog.languageDirection' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'>
<head>
<meta content='width=device-width, initial-scale=1, viewport-fit=cover' name='viewport'/>
<meta content='notranslate' name='google'/>
<title><data:blog.pageTitle/></title>
<b:include data='blog' name='all-head-content'/>
<meta content='#07070b' name='theme-color'/>
<meta content='yes' name='mobile-web-app-capable'/>
<link href='https://fonts.googleapis.com' rel='preconnect'/>
<link crossorigin='crossorigin' href='https://fonts.gstatic.com' rel='preconnect'/>
<link href='https://fonts.googleapis.com/css2?family=Hind+Siliguri:wght@400;500;600;700&family=Playfair+Display:wght@700;800&display=swap' rel='stylesheet'/>
<script src='https://www.gstatic.com/firebasejs/10.12.2/firebase-app-compat.js'>/* firebase */</script>
<script src='https://www.gstatic.com/firebasejs/10.12.2/firebase-auth-compat.js'>/* firebase */</script>
<script src='https://www.gstatic.com/firebasejs/10.12.2/firebase-firestore-compat.js'>/* firebase */</script>
<b:skin><![CDATA[
:root{--bg:#07070b;--card:#12121a;--card2:#181822;--tx:#f4f0e6;--mut:#9a95a8;--ac:#f0c45c;--ac2:#c58a22;--ln:rgba(240,196,92,.22);--ok:#22c55e;--bad:#ef4444;--r:16px;--sh:0 14px 40px rgba(0,0,0,.55)}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{background:var(--bg);color:var(--tx);font-family:'Hind Siliguri',system-ui,-apple-system,'Segoe UI',sans-serif;line-height:1.6;overflow-x:hidden;min-height:100vh}
body::before{content:'';position:fixed;inset:0;z-index:-1;background:radial-gradient(600px 400px at 10% -5%,rgba(240,196,92,.16),transparent 70%),radial-gradient(700px 500px at 100% 10%,rgba(139,92,246,.14),transparent 70%),radial-gradient(500px 400px at 50% 110%,rgba(236,72,153,.10),transparent 70%)}
a{color:inherit;text-decoration:none}
img,video{max-width:100%;display:block}
button,input,select,textarea{font:inherit;color:inherit}
input,select,textarea{font-size:16px}
#navbar,#navbar-iframe,.Navbar{display:none!important}
.wrap{max-width:1280px;margin:0 auto;padding:0 14px}
.serif{font-family:'Playfair Display','Hind Siliguri',serif}
.mut{color:var(--mut)}.sm{font-size:.82rem}
/* header */
.hd{position:sticky;top:0;z-index:50;background:rgba(7,7,11,.78);backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);border-bottom:1px solid var(--ln)}
.hd .wrap{display:flex;align-items:center;gap:10px;height:62px}
.brand{font-family:'Playfair Display',serif;font-weight:800;font-size:1.35rem;letter-spacing:3px;background:linear-gradient(135deg,#fff3c4,var(--ac),var(--ac2));-webkit-background-clip:text;background-clip:text;color:transparent;display:flex;align-items:center;gap:8px;white-space:nowrap}
.brand img{height:34px;-webkit-text-fill-color:initial}
.brand i{font-style:normal;-webkit-text-fill-color:var(--ac);font-size:1rem}
.sp{flex:1}
.ib{position:relative;min-width:42px;height:42px;padding:0 12px;border-radius:99px;border:1px solid var(--ln);background:var(--card);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:6px;font-size:.95rem;transition:.2s;white-space:nowrap}
.ib:hover{border-color:var(--ac);box-shadow:0 0 0 3px rgba(240,196,92,.12)}
.ib b{color:var(--ac)}
.dot{position:absolute;top:-3px;right:-3px;min-width:18px;height:18px;border-radius:99px;background:var(--bad);color:#fff;font-size:.7rem;font-weight:700;display:flex;align-items:center;justify-content:center;padding:0 4px}
.btn{border:0;cursor:pointer;padding:12px 22px;border-radius:99px;font-weight:700;color:#1b1406;background:linear-gradient(135deg,#fbe9a8,var(--ac),var(--ac2));box-shadow:0 8px 22px rgba(197,138,34,.35);transition:.2s;white-space:nowrap}
.btn:hover{filter:brightness(1.07);transform:translateY(-1px)}
.btn:active{transform:scale(.98)}
.btn.gh{background:var(--card2);color:var(--tx);border:1px solid var(--ln);box-shadow:none}
.btn.wa{background:#25d366;color:#fff;box-shadow:none}
.btn.sm2{padding:8px 16px;font-size:.85rem}
.btn[disabled]{opacity:.5;cursor:not-allowed;transform:none}
/* hero */
.hero{margin:18px 0 8px;border-radius:24px;padding:28px 22px;position:relative;overflow:hidden;border:1px solid var(--ln);background:linear-gradient(120deg,rgba(240,196,92,.14),rgba(139,92,246,.10) 55%,rgba(236,72,153,.10))}
.hero::after{content:'';position:absolute;right:-60px;top:-60px;width:220px;height:220px;border-radius:50%;background:radial-gradient(circle,rgba(240,196,92,.35),transparent 70%);filter:blur(6px)}
.hero h1{font-family:'Playfair Display','Hind Siliguri',serif;font-size:1.7rem;line-height:1.25;margin-bottom:6px}
.hero h1 span{background:linear-gradient(135deg,#fff3c4,var(--ac),var(--ac2));-webkit-background-clip:text;background-clip:text;color:transparent}
.hero p{color:var(--mut);max-width:560px}
@media(min-width:760px){.hero{padding:42px 40px}.hero h1{font-size:2.5rem}}
.ann{margin-top:12px;display:inline-block;padding:5px 14px;border-radius:99px;background:rgba(0,0,0,.35);border:1px solid var(--ln);font-size:.85rem;color:var(--ac)}
/* toolbar */
.bar{display:flex;align-items:center;gap:10px;margin:18px 0 12px;flex-wrap:wrap}
.bar h2{font-family:'Playfair Display','Hind Siliguri',serif;font-size:1.3rem}
.bar h2::after{content:'';display:block;width:46px;height:2px;margin-top:6px;background:linear-gradient(90deg,var(--ac),transparent)}
.srch{margin-left:auto;display:flex;align-items:center;background:var(--card);border:1px solid var(--ln);border-radius:99px;padding:0 14px;flex:1;max-width:360px;min-width:180px}
.srch input{background:none;border:0;outline:0;padding:10px 8px;width:100%}
/* grid */
.grid{display:grid;gap:12px;grid-template-columns:repeat(2,1fr)}
@media(min-width:640px){.grid{grid-template-columns:repeat(3,1fr);gap:16px}}
@media(min-width:960px){.grid{grid-template-columns:repeat(4,1fr)}}
@media(min-width:1240px){.grid{grid-template-columns:repeat(5,1fr)}}
.vc{display:block;cursor:pointer;transition:transform .25s}
@media(hover:hover){.vc:hover{transform:translateY(-5px)}}
.th{position:relative;border-radius:var(--r);overflow:hidden;background:linear-gradient(135deg,#252532,#101018);border:1px solid var(--ln);box-shadow:var(--sh);aspect-ratio:16/9;transition:.25s}
.vc.pt .th{aspect-ratio:9/14}
@media(hover:hover){.vc:hover .th{border-color:var(--ac);box-shadow:0 16px 40px rgba(0,0,0,.6),0 0 24px rgba(240,196,92,.18)}}
.th .ph{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:2.4rem;opacity:.45}
.th img,.th video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .5s}
@media(hover:hover){.vc:hover .th img,.vc:hover .th video{transform:scale(1.07)}}
.pl{position:absolute;left:50%;top:50%;width:46px;height:46px;margin:-23px 0 0 -23px;border-radius:50%;background:rgba(0,0,0,.5);backdrop-filter:blur(4px);border:1.5px solid var(--ac);color:var(--ac);display:flex;align-items:center;justify-content:center;padding-left:3px;transition:.25s}
@media(hover:hover){.vc:hover .pl{background:var(--ac);color:#1b1406;transform:scale(1.12)}}
.bd{position:absolute;top:9px;left:9px;font-size:.7rem;font-weight:700;padding:3px 10px;border-radius:99px;letter-spacing:.3px}
.bd.f{background:rgba(22,163,74,.92);color:#fff}
.bd.p{background:linear-gradient(135deg,#fbe9a8,var(--ac2));color:#1b1406}
.vn{position:absolute;top:9px;right:9px;font-size:.68rem;padding:2px 8px;border-radius:7px;background:rgba(0,0,0,.65);color:#fff}
.cap{position:absolute;left:0;right:0;bottom:0;padding:34px 10px 9px;background:linear-gradient(transparent,rgba(0,0,0,.92))}
.cap h3{font-size:.9rem;font-weight:600;line-height:1.35;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.cap small{color:rgba(255,255,255,.7);font-size:.72rem}
.sk{background:linear-gradient(90deg,#14141c 25%,#1e1e2a 50%,#14141c 75%);background-size:200% 100%;animation:sh 1.3s infinite;border-radius:var(--r);aspect-ratio:16/9}
@keyframes sh{to{background-position:-200% 0}}
.empty{grid-column:1/-1;text-align:center;color:var(--mut);padding:50px 0}
/* ads */
.ad{margin:14px 0;text-align:center;overflow:hidden;max-width:100%}
.ad small{display:block;font-size:.66rem;color:var(--mut);margin-bottom:3px}
.ad.feed{grid-column:1/-1;margin:2px 0}
.stk{position:fixed;left:0;right:0;bottom:0;z-index:45;background:var(--card);border-top:1px solid var(--ln);text-align:center;max-height:120px;overflow:hidden}
.stk button{position:absolute;right:4px;top:3px;width:26px;height:26px;border-radius:50%;border:0;background:rgba(0,0,0,.55);color:#fff;cursor:pointer;z-index:2}
/* footer */
.ft{border-top:1px solid var(--ln);margin-top:40px;padding:26px 0 90px;text-align:center;color:var(--mut);font-size:.88rem}
.ft .so{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-bottom:12px}
.ft .so a{padding:8px 16px;border-radius:99px;background:var(--card);border:1px solid var(--ln);color:var(--tx)}
/* overlay / modal */
.mo{position:fixed;inset:0;z-index:100;background:rgba(0,0,0,.78);backdrop-filter:blur(4px);display:flex;padding:14px;overflow-y:auto;overscroll-behavior:contain}
.box{position:relative;margin:auto;width:100%;max-width:440px;background:linear-gradient(180deg,var(--card2),var(--card));border:1px solid var(--ln);border-radius:20px;padding:22px;box-shadow:var(--sh);animation:pop .25s}
.box.big{max-width:560px}
@keyframes pop{from{transform:scale(.95);opacity:0}to{transform:none;opacity:1}}
.box h3{font-family:'Playfair Display','Hind Siliguri',serif;color:var(--ac);margin-bottom:8px;padding-right:40px}
.x{position:absolute;right:12px;top:12px;width:36px;height:36px;border-radius:50%;border:0;background:rgba(255,255,255,.08);cursor:pointer;z-index:3}
.box label{display:block;margin-top:12px;font-size:.82rem;color:var(--mut)}
.box input,.box select,.box textarea{width:100%;margin-top:4px;padding:12px;border-radius:12px;border:1px solid rgba(255,255,255,.12);background:rgba(0,0,0,.35);outline:0}
.box input:focus,.box select:focus,.box textarea:focus{border-color:var(--ac)}
.box .btn{width:100%;margin-top:14px}
.tabs{display:flex;gap:6px;margin:10px 0;background:rgba(0,0,0,.3);padding:4px;border-radius:99px}
.tabs button{flex:1;border:0;padding:9px 6px;border-radius:99px;background:none;cursor:pointer;font-size:.88rem;color:var(--mut)}
.tabs button.on{background:linear-gradient(135deg,#fbe9a8,var(--ac2));color:#1b1406;font-weight:700}
.bal{padding:16px;border-radius:16px;background:linear-gradient(135deg,rgba(240,196,92,.2),rgba(139,92,246,.15));border:1px solid var(--ln);text-align:center;margin:8px 0}
.bal b{display:block;font-size:2rem;color:var(--ac)}
.num{display:flex;align-items:center;gap:8px;margin-top:8px;padding:10px 12px;border-radius:12px;border:1px dashed var(--ln);background:rgba(0,0,0,.3)}
.num span{flex:1;font-weight:700}
.num button{border:0;background:var(--ac);color:#1b1406;border-radius:8px;padding:6px 12px;font-weight:700;cursor:pointer;font-size:.8rem}
.li{padding:10px 12px;border-radius:12px;background:rgba(0,0,0,.28);border:1px solid rgba(255,255,255,.06);margin-top:8px;font-size:.9rem}
.li .t{display:flex;justify-content:space-between;gap:8px}
.st{font-size:.72rem;padding:2px 9px;border-radius:99px;font-weight:700}
.st.pending{background:#f59e0b;color:#1b1406}.st.approved,.st.paid,.st.bought{background:var(--ok);color:#fff}.st.rejected{background:var(--bad);color:#fff}
/* player page */
.pg{position:fixed;inset:0;z-index:80;background:var(--bg);overflow-y:auto;overscroll-behavior:contain}
.pg .top{position:sticky;top:0;z-index:5;display:flex;align-items:center;gap:10px;padding:10px 14px;background:rgba(7,7,11,.85);backdrop-filter:blur(14px);border-bottom:1px solid var(--ln)}
.pg .top b{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pw{max-width:980px;margin:0 auto;padding:16px 14px 80px}
.stage{position:relative;margin:0 auto;aspect-ratio:16/9;background:#000;border:1px solid var(--ln);border-radius:20px;overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,.7),0 0 40px rgba(240,196,92,.08)}
.stage.pt{aspect-ratio:9/16;max-width:min(420px,calc((100svh - 140px) * .5625))}
.stage iframe,.stage video{position:absolute;inset:0;width:100%;height:100%;border:0;background:#000}
.stage>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.ov{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;text-align:center;padding:16px;background:rgba(6,6,10,.78);backdrop-filter:blur(8px);overflow-y:auto}
.ov>:first-child{margin-top:auto}.ov>:last-child{margin-bottom:auto}
.ov .ic{font-size:2.6rem}
.ov .btn{min-width:190px}
.cnt{font-size:2rem;font-weight:800;color:var(--ac);font-family:'Playfair Display',serif}
.ptitle{font-size:1.4rem;margin:16px 0 6px;font-family:'Playfair Display','Hind Siliguri',serif}
.meta{display:flex;gap:8px 14px;flex-wrap:wrap;color:var(--mut);font-size:.88rem}
.shr{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0}
.shr a,.shr button{padding:8px 16px;border-radius:99px;border:0;cursor:pointer;color:#fff;font-size:.85rem;font-weight:600}
.spin{width:42px;height:42px;border:4px solid rgba(255,255,255,.2);border-top-color:var(--ac);border-radius:50%;animation:sp .8s linear infinite}
@keyframes sp{to{transform:rotate(360deg)}}
/* chat */
.fab{position:fixed;right:14px;bottom:18px;z-index:60;width:56px;height:56px;border-radius:50%;border:0;cursor:pointer;font-size:1.5rem;background:linear-gradient(135deg,#fbe9a8,var(--ac),var(--ac2));color:#1b1406;box-shadow:0 10px 28px rgba(197,138,34,.5)}
.fab .dot{top:0;right:0}
.chat{position:fixed;right:12px;bottom:84px;z-index:95;width:min(370px,calc(100vw - 24px));height:min(520px,calc(100svh - 110px));display:flex;flex-direction:column;background:var(--card);border:1px solid var(--ln);border-radius:20px;box-shadow:var(--sh);overflow:hidden;animation:pop .2s}
.chat .h{padding:12px 14px;background:linear-gradient(135deg,rgba(240,196,92,.25),rgba(139,92,246,.18));display:flex;justify-content:space-between;align-items:center;font-weight:700}
.chat .h button{border:0;background:rgba(255,255,255,.1);width:30px;height:30px;border-radius:50%;cursor:pointer}
.chat .ms{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px}
.m{max-width:80%;padding:8px 12px;border-radius:14px;font-size:.92rem;word-break:break-word}
.m.u{align-self:flex-end;background:linear-gradient(135deg,#fbe9a8,var(--ac2));color:#1b1406;border-bottom-right-radius:4px}
.m.a{align-self:flex-start;background:var(--card2);border:1px solid var(--ln);border-bottom-left-radius:4px}
.chat form{display:flex;gap:6px;padding:10px;border-top:1px solid var(--ln)}
.chat input{flex:1;min-width:0;padding:10px 14px;border-radius:99px;border:1px solid var(--ln);background:var(--bg);outline:0}
.chat form button{border:0;border-radius:99px;padding:0 16px;background:var(--ac);color:#1b1406;font-weight:700;cursor:pointer}
.toast{position:fixed;left:50%;bottom:90px;transform:translateX(-50%);z-index:300;background:#14141c;color:var(--ac);border:1px solid var(--ln);padding:10px 20px;border-radius:99px;box-shadow:var(--sh);max-width:92vw;text-align:center;animation:pop .2s}
.setup{max-width:560px;margin:80px auto;padding:24px;border:1px dashed var(--ln);border-radius:18px;text-align:center}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
]]></b:skin>
</head>
<body>
<header class='hd'>
<div class='wrap'>
<a class='brand' href='#' id='brand'><i>▶</i> VIDORA</a>
<span class='sp'/>
<button class='ib' id='bnote' type='button' aria-label='Notifications'>🔔</button>
<button class='ib' id='bwal' type='button' style='display:none'>💰 <b id='balv'>৳০</b></button>
<button class='btn sm2' id='blog' type='button'>লগইন</button>
</div>
</header>
<main>
<div class='wrap'>
<section class='hero'>
<h1 id='hT'>সেরা ভিডিও, <span>এক জায়গায়</span></h1>
<p id='hP'>নতুন নতুন ভিডিও প্রতিদিন। ফ্রি দেখুন বা পেইড ভিডিও আনলক করুন।</p>
<div class='ann' id='ann' style='display:none'/>
</section>
<div id='adtop'/>
<div class='bar'>
<h2>🎬 সব ভিডিও</h2>
<label class='srch'>🔍<input id='q' type='search' placeholder='ভিডিও খুঁজুন...'/></label>
</div>
<div class='grid' id='grid'><div class='sk'/><div class='sk'/><div class='sk'/><div class='sk'/></div>
<div id='adbot'/>
</div>
</main>
<footer class='ft'><div class='wrap'><div class='so' id='so'/><div id='fcopy'/></div></footer>
<button class='fab' id='fab' type='button' aria-label='Live chat'>💬<span class='dot' id='fdot' style='display:none'>1</span></button>
<div id='root'/>
<!-- Blogger-এর জন্য দরকারি (লুকানো) -->
<div style='display:none'>
<b:section class='main' id='main' showaddelement='no'>
<b:widget id='Blog1' locked='true' title='Blog Posts' type='Blog' version='2' visible='true'>
<b:widget-settings>
<b:widget-setting name='showDateHeader'>false</b:widget-setting>
<b:widget-setting name='showShareButtons'>false</b:widget-setting>
<b:widget-setting name='showCommentLink'>false</b:widget-setting>
<b:widget-setting name='showAuthor'>false</b:widget-setting>
<b:widget-setting name='style.unittype'>TextAndImage</b:widget-setting>
<b:widget-setting name='showAuthorProfile'>false</b:widget-setting>
<b:widget-setting name='style.layout'>1x1</b:widget-setting>
<b:widget-setting name='showLabels'>false</b:widget-setting>
<b:widget-setting name='showLocation'>false</b:widget-setting>
<b:widget-setting name='showTimestamp'>false</b:widget-setting>
<b:widget-setting name='postsPerAd'>0</b:widget-setting>
<b:widget-setting name='showBacklinks'>false</b:widget-setting>
<b:widget-setting name='showInlineAds'>false</b:widget-setting>
<b:widget-setting name='showReactions'>false</b:widget-setting>
</b:widget-settings>
<b:includable id='main' var='top'>
<b:loop values='data:posts' var='post'>
<article><h2><data:post.title/></h2></article>
</b:loop>
</b:includable>
</b:widget>
</b:section>
</div>
<script>
//<![CDATA[
(function(){
'use strict';
/* ============ Firebase কনফিগ (Firebase Console > Project settings > Web app থেকে) ============ */
var FBCFG = {
apiKey: '',
authDomain: '',
projectId: '',
appId: ''
};
/* ================================================================================================ */
var D = document;
var $ = function(s, r){ return (r || D).querySelector(s); };
var esc = function(s){ return String(s == null ? '' : s).replace(/[&<>"']/g, function(c){ return {'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]; }); };
var BN = '০১২৩৪৫৬৭৮৯';
function bn(n){ return String(n).replace(/\d/g, function(d){ return BN.charAt(+d); }); }
function money(n){ return '৳' + bn(Math.round((+n || 0) * 100) / 100); }
function toast(m){ var t = D.createElement('div'); t.className = 'toast'; t.textContent = m; D.body.appendChild(t); setTimeout(function(){ t.remove(); }, 2800); }
function copy(txt){
if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(txt).then(function(){ toast('কপি হয়েছে ✓'); }); return; }
var i = D.createElement('textarea'); i.value = txt; D.body.appendChild(i); i.select();
try { D.execCommand('copy'); toast('কপি হয়েছে ✓'); } catch(e) {} i.remove();
}
function fdate(ts){ try { var d = ts && ts.toDate ? ts.toDate() : new Date(); return d.toLocaleString('bn-BD', {day:'numeric', month:'short', hour:'numeric', minute:'2-digit'}); } catch(e) { return ''; } }
if (!FBCFG.apiKey || !FBCFG.projectId) {
$('main .wrap').innerHTML = '<div class="setup"><h2>⚙️ Firebase সেটআপ বাকি</h2><p class="mut" style="margin-top:8px">থিমের কোডে FBCFG অংশে আপনার Firebase কনফিগ বসান।</p></div>';
return;
}
firebase.initializeApp(FBCFG);
var auth = firebase.auth(), db = firebase.firestore(), FV = firebase.firestore.FieldValue;
var S = { user: null, prof: null, set: {}, videos: [], byId: {}, notes: [], notesAll: [], notesMe: [], chatOpen: false };
var unsubs = [];
/* ---------- ভিডিও লিংক বিশ্লেষণ ---------- */
function parseVideo(u){
u = String(u || '').trim(); var m;
if (/drive\.google\.com/.test(u) && ((m = u.match(/\/d\/([\w-]+)/)) || (m = u.match(/[?&]id=([\w-]+)/))))
return { p:'drive', embed:'https://drive.google.com/file/d/' + m[1] + '/preview', thumb:'https://drive.google.com/thumbnail?id=' + m[1] + '&sz=w640' };
if (/facebook\.com|fb\.watch|fb\.com/.test(u))
return { p:'facebook', embed:'https://www.facebook.com/plugins/video.php?href=' + encodeURIComponent(u) + '&show_text=false&t=0', thumb:'' };
if (/tera|1024tera|freeterabox|4funbox|mirrobox|nephobox|momerybox/i.test(u) && ((m = u.match(/\/s\/1?([\w-]+)/)) || (m = u.match(/surl=([\w-]+)/))))
return { p:'terabox', embed:'https://www.terabox.com/sharing/embed?surl=' + m[1] + '&autoplay=true&mute=false', thumb:'' };
if (/\.(mp4|webm|mov|m3u8)(\?|#|$)/i.test(u)) return { p:'direct', embed:u, thumb:'' };
return { p:'other', embed:u, thumb:'' };
}
var PICON = { drive:'📁', facebook:'📘', terabox:'📦', direct:'🎞', other:'🎬' };
/* ---------- বিজ্ঞাপন ---------- */
var seenSrc = {};
function adEl(pos){
var a = S.set.ads || {};
if (!a.enabled || !a[pos]) return null;
var d = D.createElement('div'); d.className = 'ad'; d.innerHTML = '<small>বিজ্ঞাপন</small><div class="in"></div>';
var inn = $('.in', d); inn.innerHTML = a[pos];
Array.prototype.slice.call(inn.querySelectorAll('script')).forEach(function(o){
var n = D.createElement('script');
Array.prototype.slice.call(o.attributes).forEach(function(at){ n.setAttribute(at.name, at.value); });
n.text = o.text; o.parentNode.replaceChild(n, o);
});
return d;
}
function putAd(id, pos){ var h = $(id); if (!h) return; h.innerHTML = ''; var e = adEl(pos); if (e) h.appendChild(e); }
/* ---------- মডাল ---------- */
function modal(html, big){
var m = D.createElement('div'); m.className = 'mo';
m.innerHTML = '<div class="box' + (big ? ' big' : '') + '"><button class="x" type="button" aria-label="Close">✕</button>' + html + '</div>';
m.addEventListener('click', function(e){ if (e.target === m || e.target.closest('.x')) m.remove(); });
$('#root').appendChild(m);
return m;
}
/* ---------- সেটিংস ও ভিডিও লোড ---------- */
function applySettings(){
var s = S.set;
var br = $('#brand');
br.innerHTML = s.logo ? '<img src="' + esc(s.logo) + '" alt="">' : '<i>▶</i> ' + esc(s.siteName || 'VIDORA');
if (s.siteName) D.title = s.siteName;
if (s.heroTitle) $('#hT').textContent = s.heroTitle;
if (s.heroText) $('#hP').textContent = s.heroText;
if (s.announce) { var a = $('#ann'); a.textContent = '📢 ' + s.announce; a.style.display = ''; }
var links = [['Facebook', s.facebook], ['Telegram', s.telegram], ['YouTube', s.youtube], ['WhatsApp', s.whatsapp ? 'https://wa.me/' + String(s.whatsapp).replace(/\D/g, '') : '']].filter(function(x){ return x[1]; });
$('#so').innerHTML = links.map(function(x){ return '<a href="' + esc(x[1]) + '" target="_blank" rel="noopener">' + x[0] + '</a>'; }).join('');
$('#fcopy').textContent = '© ' + new Date().getFullYear() + ' ' + (s.siteName || 'VIDORA');
putAd('#adtop', 'top'); putAd('#adbot', 'bottom');
var old = $('.stk'); if (old) old.remove();
var st = adEl('sticky');
if (st) { var w = D.createElement('div'); w.className = 'stk'; w.appendChild(st); var b = D.createElement('button'); b.type = 'button'; b.textContent = '✕'; b.onclick = function(){ w.remove(); }; w.appendChild(b); D.body.appendChild(w); }
}
function thumbHtml(v){
var t = v.thumb || v.thumbAuto, h = '<div class="ph">' + (PICON[v.platform] || '🎬') + '</div>';
if (t) return h + '<img loading="lazy" decoding="async" referrerpolicy="no-referrer" src="' + esc(t) + '" alt="" onerror="this.style.display=\'none\'">';
if (!v.paid && v.platform === 'direct' && v.url) return h + '<video muted playsinline preload="metadata" src="' + esc(v.url) + '#t=0.8"></video>';
return h;
}
function card(v){
return '<a class="vc' + (v.ratio === '9/16' ? ' pt' : '') + '" href="#v=' + esc(v.id) + '"><div class="th">' + thumbHtml(v) + '<span class="pl">▶</span>' +
(v.paid ? '<span class="bd p">🔒 ' + money(v.price) + '</span>' : '<span class="bd f">FREE</span>') +
(v.views ? '<span class="vn">👁 ' + bn(v.views) + '</span>' : '') +
'<div class="cap"><h3>' + esc(v.title) + '</h3></div></div></a>';
}
function renderGrid(){
var q = ($('#q').value || '').trim().toLowerCase(), g = $('#grid');
var list = S.videos.filter(function(v){ return !q || String(v.title).toLowerCase().indexOf(q) > -1; });
if (!list.length) { g.innerHTML = '<div class="empty">😕 কোনো ভিডিও পাওয়া যায়নি</div>'; return; }
g.innerHTML = list.map(card).join('');
var every = +((S.set.ads || {}).feedEvery) || 6;
Array.prototype.slice.call(g.querySelectorAll('.vc')).forEach(function(c, i){
if ((i + 1) % every === 0) { var a = adEl('feed'); if (a) { a.className += ' feed'; c.parentNode.insertBefore(a, c.nextSibling); } }
});
}
function loadAll(){
db.doc('settings/site').get().then(function(s){ S.set = s.exists ? s.data() : {}; }).catch(function(){ S.set = {}; }).then(function(){
applySettings();
return db.collection('videos').orderBy('createdAt', 'desc').limit(300).get();
}).then(function(qs){
S.videos = []; S.byId = {};
qs.forEach(function(d){ var v = d.data(); v.id = d.id; if (!v.hidden && v.platform !== 'youtube') { S.videos.push(v); S.byId[v.id] = v; } });
renderGrid(); route();
}).catch(function(){ $('#grid').innerHTML = '<div class="empty">ভিডিও লোড করা যায়নি</div>'; });
}
$('#q').addEventListener('input', renderGrid);
/* ---------- লগইন ---------- */
function errMsg(e){
var c = (e && e.code) || '';
if (/wrong-password|invalid-credential|user-not-found/.test(c)) return 'ইমেইল বা পাসওয়ার্ড ভুল';
if (/email-already/.test(c)) return 'এই ইমেইল আগে থেকেই আছে';
if (/weak-password/.test(c)) return 'পাসওয়ার্ড কমপক্ষে ৬ অক্ষর দিন';
if (/invalid-email/.test(c)) return 'ইমেইল ঠিক নয়';
if (/popup/.test(c)) return 'পপআপ বন্ধ হয়েছে, আবার চেষ্টা করুন';
return 'সমস্যা হয়েছে: ' + (c || 'আবার চেষ্টা করুন');
}
function authModal(){
var mode = 'in';
var m = modal('<h3>🔐 অ্যাকাউন্ট</h3><div class="tabs"><button class="on" data-m="in" type="button">লগইন</button><button data-m="up" type="button">নতুন অ্যাকাউন্ট</button></div>' +
'<div id="anm" style="display:none"><label>নাম<input id="an" autocomplete="name"></label></div>' +
'<label>ইমেইল<input id="ae" type="email" autocomplete="email"></label><label>পাসওয়ার্ড<input id="ap" type="password" autocomplete="current-password"></label>' +
'<button class="btn" id="ago" type="button">লগইন করুন</button><button class="btn gh" id="agg" type="button">🌐 Google দিয়ে চালিয়ে যান</button>');
Array.prototype.forEach.call(m.querySelectorAll('.tabs button'), function(b){
b.onclick = function(){ mode = b.getAttribute('data-m'); Array.prototype.forEach.call(m.querySelectorAll('.tabs button'), function(x){ x.classList.toggle('on', x === b); });
$('#anm', m).style.display = mode === 'up' ? '' : 'none'; $('#ago', m).textContent = mode === 'up' ? 'অ্যাকাউন্ট খুলুন' : 'লগইন করুন'; };
});
$('#ago', m).onclick = function(){
var e = $('#ae', m).value.trim(), p = $('#ap', m).value;
if (!e || !p) { toast('ইমেইল ও পাসওয়ার্ড দিন'); return; }
var pr = mode === 'up'
? auth.createUserWithEmailAndPassword(e, p).then(function(c){ return c.user.updateProfile({ displayName: $('#an', m).value.trim() }); })
: auth.signInWithEmailAndPassword(e, p);
pr.then(function(){ m.remove(); }).catch(function(er){ toast(errMsg(er)); });
};
$('#agg', m).onclick = function(){ auth.signInWithPopup(new firebase.auth.GoogleAuthProvider()).then(function(){ m.remove(); }).catch(function(er){ toast(errMsg(er)); }); };
}
$('#blog').onclick = authModal;
function clearSubs(){ unsubs.forEach(function(u){ try { u(); } catch(e) {} }); unsubs = []; }
auth.onAuthStateChanged(function(u){
clearSubs(); S.user = u; S.prof = null; S.notesMe = [];
$('#blog').style.display = u ? 'none' : ''; $('#bwal').style.display = u ? '' : 'none';
if (u) {
var ref = db.doc('users/' + u.uid);
ref.get().then(function(s){
if (!s.exists) return ref.set({ email: u.email || '', name: u.displayName || '', balance: 0, createdAt: FV.serverTimestamp() });
}).catch(function(){}).then(function(){
unsubs.push(ref.onSnapshot(function(s){ S.prof = s.exists ? s.data() : { balance: 0 }; $('#balv').textContent = money(S.prof.balance); }, function(){}));
});
unsubs.push(db.collection('notifications').where('to', '==', u.uid).onSnapshot(function(qs){ S.notesMe = qs.docs.map(function(d){ return d.data(); }); mergeNotes(); }, function(){}));
watchChat();
} else { $('#balv').textContent = money(0); mergeNotes(); }
if (D.getElementById('pgv')) route(true);
});
/* ---------- নোটিফিকেশন ---------- */
db.collection('notifications').where('to', '==', 'all').onSnapshot(function(qs){ S.notesAll = qs.docs.map(function(d){ return d.data(); }); mergeNotes(); }, function(){});
function mergeNotes(){
S.notes = S.notesAll.concat(S.notesMe).sort(function(a, b){ return (b.at ? b.at.seconds : 0) - (a.at ? a.at.seconds : 0); });
var seen = 0; try { seen = +localStorage.getItem('vn_seen') || 0; } catch(e) {}
var n = S.notes.filter(function(x){ return x.at && x.at.seconds * 1000 > seen; }).length;
var b = $('#bnote'), d = $('.dot', b); if (d) d.remove();
if (n) b.insertAdjacentHTML('beforeend', '<span class="dot">' + bn(n) + '</span>');
}
$('#bnote').onclick = function(){
modal('<h3>🔔 নোটিফিকেশন</h3>' + (S.notes.length ? S.notes.slice(0, 30).map(function(n){
return '<div class="li"><div class="t"><b>' + esc(n.title) + '</b><span class="mut sm">' + fdate(n.at) + '</span></div><div class="mut">' + esc(n.body) + '</div></div>'; }).join('') : '<p class="mut">কোনো নোটিফিকেশন নেই</p>'));
try { localStorage.setItem('vn_seen', String(Date.now())); } catch(e) {}
mergeNotes();
};
/* ---------- ওয়ালেট ---------- */
function walletModal(tab){
if (!S.user) { authModal(); return; }
var P = S.set.payment || {}, minD = +P.minDeposit || 10, minW = +P.minWithdraw || 50;
var m = modal('<h3>💰 আমার ওয়ালেট</h3><div class="bal"><span class="mut sm">বর্তমান ব্যালেন্স</span><b id="wb">' + money(S.prof && S.prof.balance) + '</b></div>' +
'<div class="tabs"><button data-t="dep" type="button">ডিপোজিট</button><button data-t="wd" type="button">উইথড্র</button><button data-t="his" type="button">হিস্ট্রি</button></div><div id="wbody"></div>' +
'<button class="btn gh" id="wout" type="button">লগআউট</button>', true);
var live = setInterval(function(){ if (!m.isConnected) { clearInterval(live); return; } var e = $('#wb', m); if (e) e.textContent = money(S.prof && S.prof.balance); }, 800);
function show(t){
Array.prototype.forEach.call(m.querySelectorAll('.tabs button'), function(b){ b.classList.toggle('on', b.getAttribute('data-t') === t); });
var w = $('#wbody', m);
if (t === 'dep') {
w.innerHTML = '<p class="mut sm">নিচের নম্বরে Send Money করে Transaction ID দিন। অ্যাডমিন যাচাই করলে ব্যালেন্সে টাকা যোগ হবে।</p>' +
(P.bkash ? '<div class="num"><b>bKash</b><span>' + esc(P.bkash) + '</span><button data-c="' + esc(P.bkash) + '" type="button">কপি</button></div>' : '') +
(P.nagad ? '<div class="num"><b>Nagad</b><span>' + esc(P.nagad) + '</span><button data-c="' + esc(P.nagad) + '" type="button">কপি</button></div>' : '') +
'<label>মাধ্যম<select id="dm"><option>bKash</option><option>Nagad</option></select></label>' +
'<label>টাকার পরিমাণ (ন্যূনতম ' + money(minD) + ')<input id="da" type="number" inputmode="decimal"></label>' +
'<label>Transaction ID<input id="dt" autocomplete="off"></label><button class="btn" id="dgo" type="button">ডিপোজিট রিকোয়েস্ট পাঠান</button>';
$('#dgo', m).onclick = function(){
var a = parseFloat($('#da', m).value), t = $('#dt', m).value.trim();
if (!(a >= minD)) { toast('ন্যূনতম ' + money(minD)); return; }
if (!t) { toast('Transaction ID দিন'); return; }
db.collection('deposits').add({ uid: S.user.uid, email: S.user.email || '', method: $('#dm', m).value, trx: t, amount: a, status: 'pending', at: FV.serverTimestamp() })
.then(function(){ toast('রিকোয়েস্ট গেছে ✓ অ্যাডমিন যাচাই করবেন'); show('his'); }).catch(function(){ toast('পাঠানো যায়নি'); });
};
} else if (t === 'wd') {
w.innerHTML = '<p class="mut sm">রিকোয়েস্ট দিলে টাকা ব্যালেন্স থেকে কেটে নেওয়া হবে, অ্যাডমিন পাঠিয়ে দেবেন। বাতিল হলে ফেরত পাবেন।</p>' +
'<label>মাধ্যম<select id="wm"><option>bKash</option><option>Nagad</option></select></label>' +
'<label>আপনার নম্বর<input id="wn" inputmode="tel" placeholder="01XXXXXXXXX"></label>' +
'<label>টাকার পরিমাণ (ন্যূনতম ' + money(minW) + ')<input id="wa" type="number" inputmode="decimal"></label><button class="btn" id="wgo" type="button">উইথড্র রিকোয়েস্ট পাঠান</button>';
$('#wgo', m).onclick = function(){
var a = parseFloat($('#wa', m).value), n = $('#wn', m).value.trim(), bal = (S.prof && S.prof.balance) || 0;
if (!(a >= minW)) { toast('ন্যূনতম ' + money(minW)); return; }
if (a > bal) { toast('ব্যালেন্স কম'); return; }
if (!/^\d{11}$/.test(n.replace(/\D/g, ''))) { toast('সঠিক নম্বর দিন'); return; }
var b = db.batch();
b.update(db.doc('users/' + S.user.uid), { balance: FV.increment(-a) });
b.set(db.collection('withdrawals').doc(), { uid: S.user.uid, email: S.user.email || '', method: $('#wm', m).value, number: n, amount: a, status: 'pending', at: FV.serverTimestamp() });
b.commit().then(function(){ toast('উইথড্র রিকোয়েস্ট গেছে ✓'); show('his'); }).catch(function(){ toast('পাঠানো যায়নি'); });
};
} else {
w.innerHTML = '<p class="mut">লোড হচ্ছে...</p>';
var uid = S.user.uid;
Promise.all([db.collection('deposits').where('uid', '==', uid).get(), db.collection('withdrawals').where('uid', '==', uid).get(), db.collection('purchases').where('uid', '==', uid).get()]).then(function(r){
var rows = [];
r[0].forEach(function(d){ var x = d.data(); rows.push({ at: x.at, h: '⬇️ ডিপোজিট ' + money(x.amount) + ' (' + esc(x.method) + ')', st: x.status }); });
r[1].forEach(function(d){ var x = d.data(); rows.push({ at: x.at, h: '⬆️ উইথড্র ' + money(x.amount) + ' (' + esc(x.method) + ')', st: x.status }); });
r[2].forEach(function(d){ var x = d.data(); rows.push({ at: x.at, h: '🎬 ' + esc(x.title || 'ভিডিও') + ' — ' + money(x.price), st: 'bought' }); });
rows.sort(function(a, b){ return (b.at ? b.at.seconds : 0) - (a.at ? a.at.seconds : 0); });
var L = { pending: 'অপেক্ষমাণ', approved: 'সফল', paid: 'পাঠানো হয়েছে', rejected: 'বাতিল', bought: 'কেনা' };
w.innerHTML = rows.length ? rows.slice(0, 40).map(function(x){ return '<div class="li"><div class="t"><span>' + x.h + '</span><span class="st ' + x.st + '">' + L[x.st] + '</span></div><div class="mut sm">' + fdate(x.at) + '</div></div>'; }).join('') : '<p class="mut" style="margin-top:8px">কোনো লেনদেন নেই</p>';
}).catch(function(){ w.innerHTML = '<p class="mut">হিস্ট্রি লোড হয়নি</p>'; });
}
}
m.addEventListener('click', function(e){
var t = e.target.closest('.tabs button'); if (t) show(t.getAttribute('data-t'));
var c = e.target.closest('[data-c]'); if (c) copy(c.getAttribute('data-c'));
});
$('#wout', m).onclick = function(){ auth.signOut(); m.remove(); };
show(tab || 'dep');
}
$('#bwal').onclick = function(){ walletModal('dep'); };
/* ---------- ভিডিও প্লেয়ার পেজ ---------- */
var gateDone = {}, curId = '';
function route(force){
var m = location.hash.match(/^#v=([\w-]+)/);
if (!m) { var o = D.getElementById('pgv'); if (o) o.remove(); curId = ''; D.body.style.overflow = ''; return; }
if (!force && curId === m[1] && D.getElementById('pgv')) return;
openVideo(m[1]);
}
window.addEventListener('hashchange', function(){ route(); });
function openVideo(id){
curId = id;
var old = D.getElementById('pgv'); if (old) old.remove();
D.body.style.overflow = 'hidden';
var pg = D.createElement('div'); pg.className = 'pg'; pg.id = 'pgv';
pg.innerHTML = '<div class="top"><button class="ib" id="pback" type="button">← ফিরুন</button><b id="ptt"></b></div><div class="pw"><div class="stage" id="stg"><div class="ov"><div class="spin"></div></div></div><div id="pinfo"></div></div>';
$('#root').appendChild(pg);
$('#pback', pg).onclick = function(){ if (history.length > 1 && /#v=/.test(location.hash)) { history.back(); setTimeout(function(){ if (/#v=/.test(location.hash)) location.hash = ''; }, 150); } else location.hash = ''; };
var vp = S.byId[id] ? Promise.resolve(S.byId[id]) : db.doc('videos/' + id).get().then(function(s){ if (!s.exists) return null; var v = s.data(); v.id = s.id; return v; });
vp.then(function(v){
if (!v || v.hidden || v.platform === 'youtube') { $('#stg', pg).innerHTML = '<div class="ov"><div class="ic">😕</div><p>ভিডিওটি পাওয়া যায়নি</p></div>'; return; }
renderPlayer(pg, v);
}).catch(function(){ $('#stg', pg).innerHTML = '<div class="ov"><p>লোড করা যায়নি</p></div>'; });
}
function renderPlayer(pg, v){
var stg = $('#stg', pg), pt = v.ratio === '9/16';
if (pt) stg.className = 'stage pt';
$('#ptt', pg).textContent = v.title;
var u = encodeURIComponent(location.origin + '/#v=' + v.id), t = encodeURIComponent(v.title);
$('#pinfo', pg).innerHTML = '<h1 class="ptitle">' + esc(v.title) + '</h1><div class="meta"><span>' + (v.paid ? '🔒 পেইড ' + money(v.price) : '🆓 ফ্রি') + '</span><span>' + (PICON[v.platform] || '') + ' ' + esc(v.platform || '') + '</span>' + (v.views ? '<span>👁 ' + bn(v.views) + ' ভিউ</span>' : '') + '</div>' +
(v.desc ? '<p class="mut" style="margin-top:10px;white-space:pre-line">' + esc(v.desc) + '</p>' : '') +
'<div id="padp"></div><div class="shr"><b>শেয়ার:</b><a style="background:#1877f2" target="_blank" rel="noopener" href="https://www.facebook.com/sharer/sharer.php?u=' + u + '">Facebook</a><a style="background:#25d366" target="_blank" rel="noopener" href="https://wa.me/?text=' + t + '%20' + u + '">WhatsApp</a><a style="background:#229ed9" target="_blank" rel="noopener" href="https://t.me/share/url?url=' + u + '&text=' + t + '">Telegram</a><button style="background:#2a2a36" id="pcp" type="button">Copy Link</button></div><div id="padb"></div>';
$('#pcp', pg).onclick = function(){ copy(location.origin + '/#v=' + v.id); };
putAd('#padp', 'player'); putAd('#padb', 'bottom');
var bg = v.thumb || v.thumbAuto;
function lockedView(){
var P = S.set.payment || {};
stg.innerHTML = (bg ? '<img referrerpolicy="no-referrer" src="' + esc(bg) + '" alt="" style="filter:blur(6px) brightness(.5)">' : '') +
'<div class="ov"><div class="ic">🔒</div><b class="serif" style="color:var(--ac);letter-spacing:2px">পেইড ভিডিও</b><div class="cnt">' + money(v.price) + '</div>' +
(S.user ? '<p class="mut sm">আপনার ব্যালেন্স: ' + money(S.prof && S.prof.balance) + '</p><button class="btn" id="buy" type="button">🔓 ' + money(v.price) + ' দিয়ে আনলক করুন</button><button class="btn gh" id="addm" type="button">💰 ব্যালেন্স যোগ করুন</button>'
: '<p class="mut sm">আনলক করতে লগইন করুন</p><button class="btn" id="lg" type="button">লগইন / অ্যাকাউন্ট</button>') + '</div>';
var b = $('#buy', stg), l = $('#lg', stg), a = $('#addm', stg);
if (l) l.onclick = authModal;
if (a) a.onclick = function(){ walletModal('dep'); };
if (b) b.onclick = function(){
var bal = (S.prof && S.prof.balance) || 0;
if (bal < v.price) { toast('ব্যালেন্স কম, আগে ডিপোজিট করুন'); walletModal('dep'); return; }
if (!confirm(money(v.price) + ' কেটে ভিডিও আনলক করবেন?')) return;
b.disabled = true;
var bt = db.batch();
bt.update(db.doc('users/' + S.user.uid), { balance: FV.increment(-v.price) });
bt.set(db.doc('purchases/' + S.user.uid + '_' + v.id), { uid: S.user.uid, vid: v.id, title: v.title, price: v.price, at: FV.serverTimestamp() });
bt.commit().then(function(){ toast('আনলক হয়েছে ✓ 🎉'); gateView(); }).catch(function(){ b.disabled = false; toast('কেনা যায়নি, আবার চেষ্টা করুন'); });
};
}
function gateView(){
var V = S.set.verify || {};
if (V.enabled === false || !V.url || gateDone[v.id]) { play(); return; }
var secs = +V.seconds || 5;
stg.innerHTML = (bg ? '<img referrerpolicy="no-referrer" src="' + esc(bg) + '" alt="" style="filter:brightness(.45)">' : '') +
'<div class="ov"><div class="ic">🛡️</div><b class="serif" style="font-size:1.15rem">' + esc(V.title || 'ভিডিও চালু করতে ভেরিফাই করুন') + '</b>' +
'<p class="mut sm">বাটনে ক্লিক করলে স্পন্সর পেজ খুলবে, ' + bn(secs) + ' সেকেন্ড পর ভিডিও চালু হবে।</p><button class="btn" id="vf" type="button">✅ ' + esc(V.label || 'ভেরিফাই করুন') + '</button></div>';
$('#vf', stg).onclick = function(){
try { window.open(V.url, '_blank', 'noopener'); } catch(e) {}
var left = secs;
stg.innerHTML = (bg ? '<img referrerpolicy="no-referrer" src="' + esc(bg) + '" alt="" style="filter:brightness(.4)">' : '') +
'<div class="ov"><div class="cnt" id="cd">' + bn(left) + '</div><p class="mut">অপেক্ষা করুন...</p></div>';
var iv = setInterval(function(){
if (!stg.isConnected) { clearInterval(iv); return; }
left--;
if (left > 0) { var c = $('#cd', stg); if (c) c.textContent = bn(left); return; }
clearInterval(iv); gateDone[v.id] = 1;
stg.innerHTML = (bg ? '<img referrerpolicy="no-referrer" src="' + esc(bg) + '" alt="" style="filter:brightness(.5)">' : '') + '<div class="ov"><div class="ic">✅</div><p>ভেরিফাই সম্পন্ন</p><button class="btn" id="go" type="button">▶ ভিডিও চালান</button></div>';
$('#go', stg).onclick = play;
}, 1000);
};
}
function embedHtml(url){
var i = parseVideo(url);
if (i.p === 'direct') return '<video src="' + esc(i.embed) + '" controls autoplay playsinline controlsList="nodownload"></video>';
return '<iframe src="' + esc(i.embed) + '" allow="autoplay; fullscreen; picture-in-picture; encrypted-media" allowfullscreen referrerpolicy="no-referrer-when-downgrade"></iframe>';
}
function play(){
stg.innerHTML = '<div class="ov"><div class="spin"></div></div>';
var up = v.paid ? db.doc('videos/' + v.id + '/private/src').get().then(function(s){ return s.exists ? s.data().url : ''; }) : Promise.resolve(v.url);
up.then(function(url){
if (!url) { stg.innerHTML = '<div class="ov"><div class="ic">⚠️</div><p>ভিডিও লিংক পাওয়া যায়নি</p></div>'; return; }
stg.innerHTML = embedHtml(url);
if (!stg.dataset.v) { stg.dataset.v = '1'; db.doc('videos/' + v.id).update({ views: FV.increment(1) }).catch(function(){}); }
}).catch(function(){ lockedView(); toast('আনলক করা নেই'); });
}
if (!v.paid) { gateView(); return; }
if (!S.user) { lockedView(); return; }
db.doc('purchases/' + S.user.uid + '_' + v.id).get().then(function(s){ if (s.exists) gateView(); else lockedView(); }).catch(function(){ lockedView(); });
}
/* ---------- লাইভ চ্যাট ---------- */
var chatUnsub = null, chatBox = null;
function watchChat(){
if (!S.user) return;
unsubs.push(db.doc('chats/' + S.user.uid).onSnapshot(function(s){
var d = s.exists && s.data().unreadUser && !S.chatOpen;
$('#fdot').style.display = d ? '' : 'none';
}, function(){}));
}
function openChat(){
if (!S.user) { authModal(); return; }
if (chatBox) { closeChat(); return; }
S.chatOpen = true; $('#fdot').style.display = 'none';
var c = D.createElement('div'); c.className = 'chat';
c.innerHTML = '<div class="h"><span>💬 লাইভ চ্যাট</span><button type="button" id="cx">✕</button></div><div class="ms" id="cms"><div class="m a">হ্যালো! কীভাবে সাহায্য করতে পারি?</div></div><form id="cf"><input id="ci" placeholder="মেসেজ লিখুন..." autocomplete="off"><button type="submit">পাঠান</button></form>';
D.body.appendChild(c); chatBox = c;
$('#cx', c).onclick = closeChat;
var uid = S.user.uid, ref = db.doc('chats/' + uid);
ref.set({ unreadUser: false }, { merge: true }).catch(function(){});
chatUnsub = ref.collection('msgs').orderBy('at').onSnapshot(function(qs){
var h = '<div class="m a">হ্যালো! কীভাবে সাহায্য করতে পারি?</div>';
qs.forEach(function(d){ var x = d.data(); h += '<div class="m ' + (x.from === 'user' ? 'u' : 'a') + '">' + esc(x.text) + '</div>'; });
var ms = $('#cms', c); if (!ms) return; ms.innerHTML = h; ms.scrollTop = ms.scrollHeight;
ref.set({ unreadUser: false }, { merge: true }).catch(function(){});
}, function(){});
$('#cf', c).onsubmit = function(e){
e.preventDefault();
var i = $('#ci', c), t = i.value.trim(); if (!t) return; i.value = '';
ref.set({ name: S.user.displayName || (S.prof && S.prof.name) || '', email: S.user.email || '', last: t, lastAt: FV.serverTimestamp(), unreadAdmin: true }, { merge: true })
.then(function(){ return ref.collection('msgs').add({ from: 'user', text: t, at: FV.serverTimestamp() }); }).catch(function(){ toast('পাঠানো যায়নি'); });
};
}
function closeChat(){
S.chatOpen = false;
if (chatUnsub) { chatUnsub(); chatUnsub = null; }
if (chatBox) { chatBox.remove(); chatBox = null; }
}
$('#fab').onclick = openChat;
loadAll();
})();
//]]>
</script>
</body>
</html>
