Pest Nocturne — WSU EM019 study suite (freemium BTCPay paywall)
This commit is contained in:
93
inject.py
Normal file
93
inject.py
Normal file
@@ -0,0 +1,93 @@
|
||||
import io
|
||||
|
||||
p = "index.html"
|
||||
s = open(p).read()
|
||||
|
||||
PAYWALL = r'''
|
||||
<!-- ══════════════ PEST NOCTURNE — PREMIUM GATE (injected) ══════════════ -->
|
||||
<style>
|
||||
#pn-paywall{position:fixed;inset:0;z-index:99999;display:none;align-items:center;justify-content:center;
|
||||
background:rgba(5,8,16,.86);backdrop-filter:blur(6px);padding:20px;font-family:Karla,system-ui,sans-serif}
|
||||
#pn-paywall.on{display:flex}
|
||||
.pn-card{max-width:460px;width:100%;background:var(--surface,#141A30);border:1px solid var(--line,#2C3455);
|
||||
border-radius:16px;padding:34px 30px;text-align:center;box-shadow:0 30px 80px -30px rgba(0,0,0,.9)}
|
||||
.pn-card .pn-lock{font-size:44px;line-height:1;margin-bottom:10px}
|
||||
.pn-card h2{margin:0 0 10px;font-family:Fraunces,serif;font-size:1.6rem;color:var(--text,#EDE7D6)}
|
||||
.pn-card p{margin:0 0 22px;color:var(--text-dim,#A3A99C);font-size:.95rem;line-height:1.5}
|
||||
.pn-price{font-size:2rem;font-weight:700;color:var(--brass,#E3A53F);margin-bottom:4px}
|
||||
.pn-price small{font-size:.8rem;color:var(--text-faint,#6E7688);font-weight:400}
|
||||
#pn-unlock{display:block;width:100%;padding:14px;border:none;border-radius:10px;cursor:pointer;
|
||||
background:linear-gradient(135deg,var(--brass,#E3A53F),var(--brass-deep,#B87F26));color:#1a1206;
|
||||
font-weight:700;font-size:1.02rem;margin-bottom:12px}
|
||||
#pn-unlock:hover{filter:brightness(1.06)}
|
||||
#pn-close{background:none;border:none;color:var(--text-faint,#6E7688);cursor:pointer;font-size:.85rem;text-decoration:underline}
|
||||
.pn-note{margin-top:16px;font-size:.72rem;color:var(--text-faint,#6E7688)}
|
||||
</style>
|
||||
<div id="pn-paywall" role="dialog" aria-modal="true">
|
||||
<div class="pn-card">
|
||||
<div class="pn-lock">🔒</div>
|
||||
<h2>Unlock the full suite</h2>
|
||||
<p>Flashcards & the practice exam are premium. Unlock the complete
|
||||
EM019 study set — all 13 chapters, every flashcard, and the scored
|
||||
practice exam with the official answer key.</p>
|
||||
<div class="pn-price">$5 <small>pay in Bitcoin</small></div>
|
||||
<button id="pn-unlock" type="button">Unlock full access →</button>
|
||||
<button id="pn-close" type="button">Continue free preview</button>
|
||||
<div class="pn-note">Instant unlock after payment. No account needed.</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function(){
|
||||
var PREMIUM=['exam','cards'];
|
||||
var unlocked=false;
|
||||
try{ unlocked = localStorage.getItem('pn_unlocked')==='1'; }catch(e){}
|
||||
function paywallEl(){ return document.getElementById('pn-paywall'); }
|
||||
function show(){ var p=paywallEl(); if(p) p.classList.add('on'); }
|
||||
function hide(){ var p=paywallEl(); if(p) p.classList.remove('on'); }
|
||||
function setUnlocked(){ unlocked=true; try{localStorage.setItem('pn_unlocked','1')}catch(e){} hide(); }
|
||||
function poll(){
|
||||
if(unlocked) return;
|
||||
var oid=null; try{ oid=localStorage.getItem('pn_order'); }catch(e){}
|
||||
if(!oid) return;
|
||||
fetch('/api/status?order='+encodeURIComponent(oid))
|
||||
.then(function(r){return r.json()})
|
||||
.then(function(j){ if(j&&j.paid){ setUnlocked(); } else { setTimeout(poll,3000); } })
|
||||
.catch(function(){ setTimeout(poll,5000); });
|
||||
}
|
||||
function startUnlock(){
|
||||
fetch('/unlock',{method:'POST'})
|
||||
.then(function(r){return r.json()})
|
||||
.then(function(j){
|
||||
if(!j || !j.checkout_url){ return; }
|
||||
try{ localStorage.setItem('pn_order', j.order_id); }catch(e){}
|
||||
window.open(j.checkout_url,'_blank');
|
||||
poll();
|
||||
})
|
||||
.catch(function(){});
|
||||
}
|
||||
if(typeof window.go==='function'){
|
||||
var orig=window.go;
|
||||
window.go=function(v){
|
||||
if(PREMIUM.indexOf(v)>=0 && !unlocked){ show(); return; }
|
||||
orig(v);
|
||||
};
|
||||
}
|
||||
document.addEventListener('click',function(e){
|
||||
if(e.target.closest('#pn-unlock')){ startUnlock(); }
|
||||
else if(e.target.closest('#pn-close')){ hide(); }
|
||||
});
|
||||
poll();
|
||||
})();
|
||||
</script>
|
||||
'''
|
||||
|
||||
# The file has no </body> — it's an HTML fragment ending in </script>. Append at EOF.
|
||||
BMAC = r'''
|
||||
<div style="text-align:center;padding:26px 14px 30px;font-family:Karla,system-ui,sans-serif;color:var(--text-faint,#6E7688);font-size:.78rem;line-height:1.6">
|
||||
Pest Nocturne — a study suite for WSU EM019 · <a href="https://buymeacoffee.com/r26xrthzttg" target="_blank" rel="noopener" style="color:var(--verdigris,#54BFA9)">Buy me a coffee</a>
|
||||
</div>
|
||||
'''
|
||||
s = s.rstrip() + '\n' + PAYWALL + '\n' + BMAC + '\n'
|
||||
|
||||
open(p, 'w').write(s)
|
||||
print(f"injected paywall + BMAC footer; new size {len(s)} bytes")
|
||||
Reference in New Issue
Block a user