/* { "p": "lurker-analysis", "op": "template" } */ // P5.js source const p5Source = "/content/7e37766541506810ba6399c4b2735121f508bd9209df43dd200bf2316b014594i0"; // Function to load the P5.js script function loadP5Script() { return new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = p5Source; script.onload = () => resolve(); script.onerror = () => reject(new Error(`Failed to load P5 from ${p5Source}`)); document.head.appendChild(script); }); } // Parse parameters from calling script function getLurkerConfig() { const scriptTag = document.querySelector('script[entity]'); if (!scriptTag) { return { entityNumber: "000", lurkerInscriptionId: "", behavior: "No behavior specified", blockHeight: "000000" }; } // Get values directly from attributes return { entityNumber: scriptTag.getAttribute('entity') || "000", lurkerInscriptionId: scriptTag.getAttribute('inscriptionId') || "", behavior: scriptTag.getAttribute('behavior') || "No behavior specified", blockHeight: scriptTag.getAttribute('blockHeight') || "000000" }; } // Setup the page function setupPage() { // Setup HTML structure document.body.style.margin = '0'; document.body.style.padding = '0'; document.body.style.background = '#000614'; document.body.style.width = '100vw'; document.body.style.height = '100vh'; document.body.style.display = 'flex'; document.body.style.justifyContent = 'center'; document.body.style.alignItems = 'center'; document.body.style.overflow = 'hidden'; // Create canvas wrapper const wrapper = document.createElement('div'); wrapper.id = 'canvas-wrapper'; wrapper.style.position = 'relative'; wrapper.style.display = 'flex'; wrapper.style.justifyContent = 'center'; wrapper.style.alignItems = 'center'; wrapper.style.transformOrigin = 'center'; document.body.appendChild(wrapper); // Add styles const style = document.createElement('style'); style.textContent = ` canvas { width: 800px; height: 800px; } @media (max-width: 800px), (max-height: 800px) { #canvas-wrapper { transform: scale(var(--scale-factor)); } } `; document.head.appendChild(style); } // Main P5.js sketch function startVisualization(config) { const REPORT_DATA = { title: `LURKER ANALYSIS: ENTITY #${config.entityNumber}`, scrollingText: `ANALYZING ENTITY #${config.entityNumber}... UNUSUAL BEHAVIOR PATTERNS DETECTED...`, reportText: config.behavior, inscriptionId: config.lurkerInscriptionId, blockHeight: config.blockHeight, lurkerSrc: `/content/${config.lurkerInscriptionId}` }; let lurkerImage; let frameCounter = 0; // Calculate scale factor based on window size function calculateScale() { const scaleX = (window.innerWidth - 40) / 800; const scaleY = (window.innerHeight - 40) / 800; const scale = Math.min(scaleX, scaleY, 1); // Don't scale up beyond 1 document.documentElement.style.setProperty('--scale-factor', scale); } // Add resize listener window.addEventListener('resize', calculateScale); // Initial calculation calculateScale(); window.preload = function() { lurkerImage = loadImage(REPORT_DATA.lurkerSrc); } window.shouldShow = function() { let cycle = frameCounter % 20; return (cycle < 5) || (cycle >= 7 && cycle < 19); } window.setup = function() { let canvas = createCanvas(800, 800); // Keep fixed size canvas.parent('canvas-wrapper'); textFont('monospace'); } window.draw = function() { frameCounter++; background('#000614'); // Grid stroke(128, 128, 128, 12); for (let i = 0; i < width; i += 20) { line(i, 0, i, height); line(0, i, width, i); } // Main frame drawWindow(50, 50, width - 100, height - 100, REPORT_DATA.title); // Lurker Analysis box drawWindow(70, 100, 300, 200, 'LURKER ANALYSIS'); if (lurkerImage && shouldShow()) { let imgAspect = lurkerImage.width / lurkerImage.height; let boxWidth = 280; let boxHeight = 170; let drawWidth, drawHeight; if (boxWidth / boxHeight > imgAspect) { drawHeight = boxHeight; drawWidth = boxHeight * imgAspect; } else { drawWidth = boxWidth; drawHeight = boxWidth / imgAspect; } let x = 80 + (boxWidth - drawWidth) / 2; let y = 120 + (boxHeight - drawHeight) / 2; image(lurkerImage, x, y, drawWidth, drawHeight); } // Entity Behavior box drawWindow(430, 100, 300, 200, 'ENTITY BEHAVIOR'); fill('#d6500d'); textSize(11); text(REPORT_DATA.reportText, 440, 140, 280, 180); // Clocks and Dials drawCircularInstruments(250, 420, 345, 115); // Info display (less thick text) fill(214, 80, 13, 200); textSize(10); textStyle(NORMAL); text('LURKER ANALYSIS:', 70, 330); text('INSCRIPTION ID:', 70, 345); text(REPORT_DATA.inscriptionId, 70, 360); text('CURRENT BLOCK HEIGHT:', 70, 375); text(REPORT_DATA.blockHeight, 70, 390); // Data feed with scrolling text if (shouldShow()) { drawWindow(70, height - 180, width - 140, 100, 'LIVE DATA FEED'); fill(214, 80, 13, 200); textSize(11); textStyle(NORMAL); let boxWidth = width - 140; let textLength = REPORT_DATA.scrollingText.length * 8; let totalScrollLength = textLength; let offset = (frameCounter * 0.5) % totalScrollLength; let startX = 380 - offset; if (startX < 80) { startX += textLength; } else if (startX > width - 70) { startX -= textLength; } if (startX + textLength < 80) { startX = 80; } else if (startX > width - 70) { startX = width - 70 - textLength; } text(REPORT_DATA.scrollingText, startX, height - 140, boxWidth, 80); // EQ Visualizer stroke('#d6500d'); for (let i = 0; i < width - 140; i += 3) { let h = noise(frameCount * 0.05 + i * 0.1) * 20; line(80 + i, height - 110, 80 + i, height - 110 - h); } } // Scan line stroke('#d6500d'); line(0, frameCount % height, width, frameCount % height); // Noise overlay noStroke(); fill(214, 80, 13, 75); for (let i = 0; i < width; i++) { for (let j = 0; j < height; j++) { if (random(1) > 0.992) { rect(i, j, 1, 1); } } } } function drawWindow(x, y, w, h, title) { stroke('#d6500d'); strokeWeight(1); noFill(); rect(x, y, w, h); fill(214, 80, 13, 200); noStroke(); textSize(12); textStyle(NORMAL); text(title, x + 10, y + 20); let cornerSize = 3; line(x, y, x + cornerSize, y); line(x, y, x, y + cornerSize); line(x + w, y, x + w - cornerSize, y); line(x + w, y, x + w, y + cornerSize); line(x, y + h, x + cornerSize, y + h); line(x, y + h, x, y + h - cornerSize); line(x + w, y + h, x + w - cornerSize, y + h); line(x + w, y + h, x + w, y + h - cornerSize); } function drawCircularInstruments(x, y, w, h) { let centerX = x + w / 2; let centerY = y + h / 2; let spacing = 192; let dialSize = 69; let clockSize = 57.5; drawDial(centerX - spacing / 2, centerY, dialSize, frameCounter * 0.05); drawDial(centerX + spacing / 2, centerY, dialSize, frameCounter * 0.03); drawClock(centerX, centerY, clockSize); } function drawDial(x, y, size, angleOffset) { stroke('#d6500d'); strokeWeight(2); noFill(); ellipse(x, y, size, size); for (let i = 0; i < 12; i++) { let angle = TWO_PI * i / 12; let px = x + cos(angle) * (size / 2 - (size * 0.1667)); let py = y + sin(angle) * (size / 2 - (size * 0.1667)); point(px, py); } let angle = angleOffset; let needleX = x + cos(angle) * (size / 2 - (size * 0.3333)); let needleY = y + sin(angle) * (size / 2 - (size * 0.3333)); strokeWeight(3); line(x, y, needleX, needleY); } function drawClock(x, y, size) { stroke('#d6500d'); strokeWeight(2); noFill(); ellipse(x, y, size, size); for (let i = 0; i < 12; i++) { let angle = TWO_PI * i / 12; let outerX = x + cos(angle) * (size / 2); let outerY = y + sin(angle) * (size / 2); let innerX = x + cos(angle) * (size / 2 - (size * 0.2)); let innerY = y + sin(angle) * (size / 2 - (size * 0.2)); line(innerX, innerY, outerX, outerY); } let hours = (frameCounter / 360) % 12; let hourAngle = TWO_PI * hours / 12 - HALF_PI; let hourX = x + cos(hourAngle) * (size / 2 - (size * 0.35)); let hourY = y + sin(hourAngle) * (size / 2 - (size * 0.35)); strokeWeight(3); line(x, y, hourX, hourY); let minutes = frameCounter / 60 % 60; let minuteAngle = TWO_PI * minutes / 60 - HALF_PI; let minuteX = x + cos(minuteAngle) * (size / 2 - (size * 0.175)); let minuteY = y + sin(minuteAngle) * (size / 2 - (size * 0.175)); strokeWeight(2); line(x, y, minuteX, minuteY); } } // Initialize everything when the page loads window.onload = async function() { try { // Setup page structure first setupPage(); // Get the lurker configuration const config = getLurkerConfig(); // Load P5.js await loadP5Script(); // Start the visualization with the config startVisualization(config); } catch (error) { console.error("Error initializing lurker analysis:", error); document.body.innerHTML = `

ERROR LOADING LURKER ANALYSIS

${error.message}

`; } }