🔐 Access Required

Enter PIN to continue

The overlay markup stays per-site (each site keeps its own colours), and this file finds it by id. `data-gate-key` names the localStorage slot, so each site remembers its own unlock. Optional: data-gate-input / data-gate-button / data-gate-error / data-gate-overlay to match different markup without editing this file. =========================================================================== */ (function () { 'use strict'; var self = document.currentScript; if (!self) return; var attr = function (name, fallback) { var v = self.getAttribute(name); return v === null ? fallback : v; }; /* ---- the canonical PIN: DDMMYYHH -------------------------------------- */ function standardPin(now) { var pz = function (n) { return n < 10 ? '0' + n : '' + n; }; return pz(now.getDate()) + pz(now.getMonth() + 1) + String(now.getFullYear()).slice(-2) + pz(now.getHours()); } var KEY = attr('data-gate-key', 'site_pin_8'); var ov = document.getElementById(attr('data-gate-overlay', 'pin-overlay')) || document.getElementById('gate'); var input = document.getElementById(attr('data-gate-input', 'pin-input')) || document.getElementById('gate-input'); var button = document.getElementById(attr('data-gate-button', 'pin-submit')) || document.getElementById('gate-btn'); var err = document.getElementById(attr('data-gate-error', 'pin-error')) || document.getElementById('gate-err'); if (!ov) return; // nothing to gate on this page var pin = standardPin(new Date()); function unlock() { ov.style.display = 'none'; ov.classList.add('hidden'); document.body.classList.remove('gated'); } function store(v) { try { localStorage.setItem(KEY, v); } catch (e) {} } function recall() { try { return localStorage.getItem(KEY); } catch (e) { return null; } } // Already unlocked this hour? Then stay unlocked. if (recall() === pin) { unlock(); } else { document.body.classList.add('gated'); } function submit() { if (input && input.value.trim() === pin) { store(pin); unlock(); } else { if (err) err.textContent = 'Invalid PIN'; if (input) { input.value = ''; input.focus(); } } } if (button) button.addEventListener('click', submit); if (input) { // accept one press of Enter as well as a click input.addEventListener('keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); submit(); } }); if (recall() !== pin) input.focus(); } /* ---- source deterrents ------------------------------------------------ Blocks the casual "view source / inspect" route. Trivially bypassed by anyone who disables JavaScript or uses a proxy; it is a speed bump. */ function deterrents() { document.addEventListener('contextmenu', function (e) { e.preventDefault(); return false; }); document.addEventListener('keydown', function (e) { var k = (e.key || '').toUpperCase(); if (k === 'F12' || (e.ctrlKey && e.shiftKey && ['I', 'J', 'C', 'K'].indexOf(k) >= 0) || (e.ctrlKey && k === 'U')) { e.preventDefault(); return false; } }, true); // let people select text inside form fields, but not the page at large var inField = function (e) { return !!(e.target && e.target.closest && e.target.closest('input,textarea,select')); }; document.addEventListener('selectstart', function (e) { if (!inField(e)) e.preventDefault(); }); document.addEventListener('copy', function (e) { if (!inField(e)) e.preventDefault(); }); } deterrents(); })();
Operations
    Recipe