Pest Nocturne — WSU EM019 study suite (freemium BTCPay paywall)

This commit is contained in:
drjones
2026-09-01 01:37:39 -07:00
commit f9242710eb
6 changed files with 2620 additions and 0 deletions

93
inject.py Normal file
View 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 &amp; 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 &mdash; a study suite for WSU EM019 &middot; <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")