Seraph-Array/Seraphim
0
1 2// Constants for timer3const START_DATE = new Date('December 6, 2025 18:00:00 CST');4const END_DATE = new Date('December 28, 2025 23:59:59 CST');5 6document.addEventListener('DOMContentLoaded', () => {7 // Initialize timer8 function updateCountdown() {9 const now = new Date();10 const totalDuration = END_DATE - START_DATE;11 const elapsed = now - START_DATE;12 const remaining = END_DATE - now;13 14 // Calculate progress percentage15 let progress = Math.min(Math.max((elapsed / totalDuration) * 100, 0), 100);16 document.getElementById('progress-bar').style.width = `${progress}%`;17 18 // Update countdown timer19 if (remaining > 0) {20 const days = Math.floor(remaining / (1000 * 60 * 60 * 24));21 const hours = Math.floor((remaining % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));22 const minutes = Math.floor((remaining % (1000 * 60 * 60)) / (1000 * 60));23 const seconds = Math.floor((remaining % (1000 * 60)) / 1000);24 25 document.getElementById('countdown-timer').textContent = 26 `${days}d ${hours}h ${minutes}m ${seconds}s`;27 } else {28 document.getElementById('countdown-timer').textContent = 'EVENT COMPLETED';29 document.getElementById('progress-bar').classList.remove('bg-green-400');30 document.getElementById('progress-bar').classList.add('bg-orange-400');31 }32 }33 34 // Update timer immediately and every second35 updateCountdown();36 setInterval(updateCountdown, 1000);37 38 // Create mouse glow element39const glow = document.createElement('div');40 glow.classList.add('cursor-glow');41 document.body.appendChild(glow);42 43 // Track mouse movement for glow44 document.addEventListener('mousemove', (e) => {45 glow.style.left = `${e.clientX}px`;46 glow.style.top = `${e.clientY}px`;47 });48 49// Disable copy/paste and right click50 document.addEventListener('copy', (e) => {51 e.preventDefault();52 });53 54 document.addEventListener('paste', (e) => {55 e.preventDefault();56 addTerminalMessage("> PASTE PROTECTION ACTIVE: Operation denied");57 });58 59 document.addEventListener('contextmenu', (e) => {60 if (e.target.tagName === 'IMG') {61 e.preventDefault();62 addTerminalMessage("> IMAGE PROTECTION ACTIVE: Operation denied");63 }64 });65 66 const terminal = document.getElementById('terminal-output');67 68// Simple default progress; you can wire this up later69let progress = 0;70 71// Optional: only use this if you later add an element with id="completion-time"72const completionTimeElement = document.getElementById('completion-time') || null;73 74function updateCompletionTime() {75 if (!completionTimeElement) return;76 if (progress <= 0) return;77 78 const now = new Date();79 const targetDate = now; // placeholder; replace with real target later80 81 const remainingMs = targetDate - now;82 const hours = Math.floor(remainingMs / (1000 * 60 * 60));83 const minutes = Math.floor((remainingMs % (1000 * 60 * 60)) / (1000 * 60));84 const seconds = Math.floor((remainingMs % (1000 * 60)) / 1000);85 86 completionTimeElement.textContent =87 `${hours.toString().padStart(2, '0')}:` +88 `${minutes.toString().padStart(2, '0')}:` +89 `${seconds.toString().padStart(2, '0')}`;90}91 92 function updateCompletionTime() {93 if (progress <= 0) return;94 95 const now = new Date();96 const totalDuration = targetDate - startDate;97 const remainingMs = targetDate - now;98// Calculate hours, minutes, seconds99 const hours = Math.floor(remainingMs / (1000 * 60 * 60));100 const minutes = Math.floor((remainingMs % (1000 * 60 * 60)) / (1000 * 60));101 const seconds = Math.floor((remainingMs % (1000 * 60)) / 1000);102 103 // Format as HH:MM:SS104 completionTimeElement.textContent = 105 `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;106 }107 // Sector button handlers108 const sectorButtons = document.querySelectorAll('.sector-btn');109 // Make sure word-search component is loaded110 if (!customElements.get('word-search')) {111 const script = document.createElement('script');112 script.src = 'components/word-search.js';113 document.body.appendChild(script);114 }115 116 // Create image modal117 const imageModal = document.createElement('div');118 imageModal.classList.add('fixed', 'inset-0', 'z-50', 'bg-black', 'bg-opacity-90', 'flex', 'items-center', 'justify-center', 'hidden');119 imageModal.innerHTML = `120 <div class="relative max-w-4xl w-full">121 <img id="modal-image" class="w-full" src="" alt="Full sector image">122 <button id="close-modal" class="absolute top-4 right-4 text-white text-2xl">✕</button>123 <a id="download-btn" class="absolute bottom-4 right-4 bg-green-500 text-black px-4 py-2 rounded hover:bg-green-400 transition" download>Download</a>124 </div>125 `;126 document.body.appendChild(imageModal);127 128 // Handle modal close129 imageModal.querySelector('#close-modal').addEventListener('click', () => {130 imageModal.classList.add('hidden');131 });132 sectorButtons.forEach(btn => {133 btn.addEventListener('click', () => {134 const sector = btn.dataset.sector;135 const fullImg = btn.dataset.fullImg;136 if (!fullImg) return;137 138 const modalImg = imageModal.querySelector('#modal-image');139 const downloadBtn = imageModal.querySelector('#download-btn');140 141 modalImg.src = fullImg;142 downloadBtn.href = fullImg;143 downloadBtn.setAttribute('download', `sector-${sector}-fragment.jpg`);144 145 imageModal.classList.remove('hidden');146 addTerminalMessage(`> Displaying full fragment for sector ${sector}`);147 });148});149 150// If loading stored progress, add a message151 const storedProgress = localStorage.getItem('decryptionProgress');152 if (storedProgress) {153 progress = parseFloat(storedProgress);154 addTerminalMessage("> Sectors 1 & 2 - Not Found");155 addTerminalMessage("> Sectors 3 & 4 - Not Found");156 addTerminalMessage("> Sectors 5 & 6 - Not Found");157} else {158 // Add first random message immediately on fresh load159 if (!storedProgress) {160 const randomMessage = messages[Math.floor(Math.random() * messages.length)];161 addTerminalMessage(randomMessage);162 }163}164 // Persist current progress immediately165 localStorage.setItem('decryptionProgress', progress.toString());166 // Add random terminal messages167 const messageInterval = setInterval(() => {168 if (progress < 100) {169const randomMessage = messages[Math.floor(Math.random() * messages.length)];170 addTerminalMessage(randomMessage);171 } else {172 clearInterval(messageInterval);173 }174 }, 5000); // Messages every 5 seconds175 176// Update progress bar color when reaching target (only if you add a #progress-bar later)177if (progress >= 100) {178 const progressBar = document.getElementById('progress-bar');179 if (progressBar) {180 progressBar.classList.remove('bg-green-500');181 progressBar.classList.add('bg-orange-500');182 }183}184 185// Generate random decryption key186 function generateRandomKey(length = 24) {187 const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;:,.<>?';188 let result = '';189 for (let i = 0; i < length; i++) {190 result += chars.charAt(Math.floor(Math.random() * chars.length));191 }192 return result;193 }194 195 function updateKeyDisplay() {196 const keyDisplay = document.getElementById('key-display');197 if (!keyDisplay) return; // quietly do nothing if the element isn't on this page198 199 const newKey = generateRandomKey();200 201 let i = 0;202 const interval = setInterval(() => {203 if (i <= newKey.length) {204 keyDisplay.textContent = newKey.substring(0, i);205 i++;206 } else {207 clearInterval(interval);208 }209 }, 50);210}211 212 213 // Initialize key display and update periodically214 updateKeyDisplay();215 setInterval(updateKeyDisplay, 10000); // Change key every 10 seconds216function addTerminalMessage(message) {217const div = document.createElement('div');218 div.textContent = message;219 terminal.appendChild(div);220 terminal.scrollTop = terminal.scrollHeight;221 }222 // Clear localStorage when decryption is complete223 if (progress >= 100) {224 localStorage.removeItem('decryptionTargetDate');225 localStorage.removeItem('decryptionStartDate');226 localStorage.removeItem('decryptionProgress');227 }228 229 // Interactive space background230const spaceBg = document.getElementById('space-bg');231 document.addEventListener('mousemove', (e) => {232 const x = e.clientX / window.innerWidth * 20 - 10;233 const y = e.clientY / window.innerHeight * 20 - 10;234 spaceBg.style.backgroundPosition = `${50 + x}% ${50 + y}%`;235 spaceBg.style.filter = `brightness(${0.9 + Math.random() * 0.2})`;236 });237});