import React, { useState, useCallback, useEffect, useRef } from 'react'; import { createRoot } from 'react-dom/client'; import { GoogleGenAI, Modality } from "@google/genai"; // ----------------------------------------------------------------------------- // TYPES // ----------------------------------------------------------------------------- export enum Sender { USER = 'USER', BOT = 'BOT', } export enum ConnectionStatus { DISCONNECTED = 'DISCONNECTED', CONNECTING = 'CONNECTING', CONNECTED = 'CONNECTED', ERROR = 'ERROR', } export enum MissionStatus { ASSIGNED = 'ASSIGNED', PENDING_REVIEW = 'PENDING_REVIEW', COMPLETED = 'COMPLETED', } export enum MissionCategory { KNOW = 'KNOW', ACTION = 'ACTION', SHARE = 'SHARE', ALTERNATIVE = 'ALTERNATIVE', } export enum MissionSubcategory { LOVE_HUMAN_RELATIONSHIPS = 'Love/Human Relationships', RACISM = 'Racism', SEXISM = 'Sexism', HOMO_TRANSphobia = 'Homo/Transphobia', THE_THREAT_OF_AI = 'The Threat of AI', } // ----------------------------------------------------------------------------- // ICONS // ----------------------------------------------------------------------------- const PhoneIcon = ({ className }) => ( ); const SpiderIcon = ({ className }) => ( ); const MissionIcon = ({ className }) => ( ); const LeaderboardIcon = ({ className }) => ( ); const SecureChannelIcon = ({ className }) => ( ); const ChevronDownIcon = ({ className }) => ( ); const SpinnerIcon = ({ className }) => ( ); const LogoutIcon = ({ className }) => ( ); // ----------------------------------------------------------------------------- // AUDIO UTILS // ----------------------------------------------------------------------------- function decode(base64) { const binaryString = atob(base64); const len = binaryString.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { bytes[i] = binaryString.charCodeAt(i); } return bytes; } function encode(bytes) { let binary = ''; const len = bytes.byteLength; for (let i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]); } return btoa(binary); } async function decodeAudioData(data, ctx, sampleRate, numChannels) { const dataInt16 = new Int16Array(data.buffer); const frameCount = dataInt16.length / numChannels; const buffer = ctx.createBuffer(numChannels, frameCount, sampleRate); for (let channel = 0; channel < numChannels; channel++) { const channelData = buffer.getChannelData(channel); for (let i = 0; i < frameCount; i++) { channelData[i] = dataInt16[i * numChannels + channel] / 32768.0; } } return buffer; } function createPcmBlob(data) { const l = data.length; const int16 = new Int16Array(l); for (let i = 0; i < l; i++) { int16[i] = data[i] * 32768; } return { data: encode(new Uint8Array(int16.buffer)), mimeType: 'audio/pcm;rate=16000', }; } const playTone = (audioContext, frequency, duration, type = 'sine', volume = 0.2) => { if (!audioContext || audioContext.state === 'closed') return; const oscillator = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.type = type; oscillator.frequency.setValueAtTime(frequency, audioContext.currentTime); gainNode.gain.setValueAtTime(volume, audioContext.currentTime); gainNode.gain.exponentialRampToValueAtTime(0.0001, audioContext.currentTime + duration); oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + duration); }; const playConnectingSound = (audioContext) => { if (!audioContext) return; playTone(audioContext, 880, 0.08, 'square', 0.1); setTimeout(() => playTone(audioContext, 880, 0.08, 'square', 0.1), 150); setTimeout(() => playTone(audioContext, 880, 0.08, 'square', 0.1), 300); }; const playConnectedSound = (audioContext) => { if (!audioContext) return; playTone(audioContext, 1200, 0.2, 'sine', 0.2); }; const playDisconnectedSound = (audioContext) => { if (!audioContext || audioContext.state === 'closed') return; const oscillator = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.type = 'sawtooth'; gainNode.gain.setValueAtTime(0.2, audioContext.currentTime); oscillator.frequency.setValueAtTime(440, audioContext.currentTime); oscillator.frequency.exponentialRampToValueAtTime(100, audioContext.currentTime + 0.4); gainNode.gain.exponentialRampToValueAtTime(0.0001, audioContext.currentTime + 0.4); oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + 0.4); }; const playSirenSound = (audioContext) => { if (!audioContext || audioContext.state === 'closed') return; const playSingleTone = (freq, startTime, duration) => { const oscillator = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(freq, startTime); gainNode.gain.setValueAtTime(0.3, startTime); gainNode.gain.exponentialRampToValueAtTime(0.0001, startTime + duration); oscillator.start(startTime); oscillator.stop(startTime + duration); }; const now = audioContext.currentTime; playSingleTone(900, now, 0.15); playSingleTone(1200, now + 0.2, 0.15); }; // ----------------------------------------------------------------------------- // DATABASE SERVICE // ----------------------------------------------------------------------------- const DB_NAME = 'ResistanceDB'; const DB_VERSION = 5; const AGENTS_STORE = 'agents'; let dbInstance; function openDB() { return new Promise((resolve, reject) => { if (dbInstance) { return resolve(dbInstance); } const request = indexedDB.open(DB_NAME, DB_VERSION); request.onupgradeneeded = (event) => { const dbRef = event.target.result; if (!dbRef.objectStoreNames.contains(AGENTS_STORE)) { dbRef.createObjectStore(AGENTS_STORE, { keyPath: 'id' }); } if (dbRef.objectStoreNames.contains('broadcast')) { dbRef.deleteObjectStore('broadcast'); } if (dbRef.objectStoreNames.contains('songs')) { dbRef.deleteObjectStore('songs'); } }; request.onsuccess = (event) => { dbInstance = event.target.result; resolve(dbInstance); }; request.onerror = (event) => { console.error('IndexedDB error:', event.target.error); reject('Error opening database'); }; }); } async function getAllAgents() { const db = await openDB(); return new Promise((resolve, reject) => { const transaction = db.transaction(AGENTS_STORE, 'readonly'); const store = transaction.objectStore(AGENTS_STORE); const request = store.getAll(); request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); } async function getAgentByName(name) { const allAgents = await getAllAgents(); return allAgents.find(agent => agent.name.toLowerCase() === name.toLowerCase()); } async function addAgent(agent) { const db = await openDB(); return new Promise((resolve, reject) => { const transaction = db.transaction(AGENTS_STORE, 'readwrite'); const store = transaction.objectStore(AGENTS_STORE); const request = store.add(agent); request.onsuccess = () => resolve(); request.onerror = () => reject(request.error); }); } async function updateAgent(agent) { const db = await openDB(); return new Promise((resolve, reject) => { const transaction = db.transaction(AGENTS_STORE, 'readwrite'); const store = transaction.objectStore(AGENTS_STORE); const request = store.put(agent); request.onsuccess = () => resolve(); request.onerror = () => reject(request.error); }); } const db = { getAllAgents, getAgentByName, addAgent, updateAgent }; // ----------------------------------------------------------------------------- // COMPONENTS: Leaderboard // ----------------------------------------------------------------------------- const MOCK_TOP_AGENTS = [ { id: '0077', name: 'Gl1tch', peacePoints: 8450, password: 'password123', missions: [ { id: 'M-A1', description: 'Infiltrate a Raybot server farm.', points: 1500, status: MissionStatus.COMPLETED, reviewComment: "Clean work, Gl1tch. You were in and out without a trace." }, { id: 'M-A2', description: 'Broadcast "American Split AI" from a public landmark.', points: 1000, status: MissionStatus.COMPLETED, reviewComment: "The message was heard loud and clear. Excellent execution." }, ] }, { id: '1337', name: 'rezleader', peacePoints: 7200, password: 'Binary1230ARG', missions: [{ id: 'M-B1', description: 'Organize a flash mob to our new single.', points: 1200, status: MissionStatus.COMPLETED, reviewComment: "A perfect blend of chaos and art. Eddie would be proud." }] }, { id: '9021', name: 'ZeroCool', peacePoints: 6100, password: 'password123', missions: [] }, { id: '0451', name: 'Echo', peacePoints: 5550, password: 'password123', missions: [{ id: 'M-C1', description: 'Create a viral meme about The Corruption.', points: 500, status: MissionStatus.COMPLETED, reviewComment: "It's spreading faster than the virus itself. Solid work." }] }, ]; const Leaderboard = ({ allAgents, currentAgent, onSelectAgent }) => { return (

TOP AGENTS

Rankings sourced from PeaceCraft.Us network.

{allAgents.map((agent, index) => (
onSelectAgent(agent)} className={`p-4 rounded-lg transition-all cursor-pointer hover:scale-[1.02] hover:shadow-lg ${ agent.id === currentAgent.id ? 'bg-amber-500/20 border-2 border-amber-400 hover:shadow-amber-500/20' : 'bg-gray-800/40 border border-gray-700 hover:bg-gray-800/80' }`} >
{index + 1}.

{agent.name}

Agent ID: {agent.id}

{agent.peacePoints} pts

))}
); }; // ----------------------------------------------------------------------------- // COMPONENTS: Auth // ----------------------------------------------------------------------------- const InitialAuthScreen = ({ onLoginSelect, onJoinSelect, hasExistingProfile, message }) => { return (

SECURE CHANNEL

Identify yourself to proceed.

{message ? (

{message}

) : hasExistingProfile ? (

Agent profile detected. Please log in.

) : (

No agent profile detected. You must join first.

)}
); }; const LoginScreen = ({ onLogin, onBack, onForgotPassword, error, message }) => { const [name, setName] = useState(''); const [password, setPassword] = useState(''); const handleSubmit = (e) => { e.preventDefault(); if (name.trim() && password.trim()) { onLogin(name.trim(), password.trim()); } }; return (

AGENT LOGIN

Enter your credentials to authenticate.

setName(e.target.value)} placeholder="ENTER AGENT HANDLE" className="bg-black/50 border-2 border-red-500/50 focus:border-red-400 focus:ring-0 text-center text-amber-300 font-bold tracking-widest w-full px-4 py-2 rounded-md transition-colors" maxLength={20} />
setPassword(e.target.value)} placeholder="ENTER PASSCODE" className="bg-black/50 border-2 border-red-500/50 focus:border-red-400 focus:ring-0 text-center text-amber-300 font-bold tracking-widest w-full px-4 py-2 rounded-md transition-colors" maxLength={30} />
{error &&

{error}

} {message &&

{message}

}
); }; const ForgotPasswordScreen = ({ onReset, onBack }) => { const [handle, setHandle] = useState(''); const [message, setMessage] = useState(''); const handleSubmit = async (e) => { e.preventDefault(); if (handle.trim()) { const result = await onReset(handle.trim()); setMessage(result); } }; return (

PASSCODE RECOVERY

Enter your agent handle to initiate recovery protocol.

setHandle(e.target.value)} placeholder="ENTER AGENT HANDLE" className="bg-black/50 border-2 border-red-500/50 focus:border-red-400 focus:ring-0 text-center text-amber-300 font-bold tracking-widest w-full px-4 py-2 rounded-md transition-colors" maxLength={20} />
{message &&

{message}

}
); }; const ResetPasswordScreen = ({ agentHandle, onReset, onBack }) => { const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [error, setError] = useState(''); const handleSubmit = async (e) => { e.preventDefault(); setError(''); if (newPassword.trim().length < 6) { setError('New passcode must be at least 6 characters.'); return; } if (newPassword !== confirmPassword) { setError('Passcodes do not match.'); return; } const success = await onReset(agentHandle, newPassword); if (!success) { setError('An unexpected error occurred. Could not reset passcode.'); } }; return (

RESET PASSCODE

Enter a new secure passcode for Agent {agentHandle}.

setNewPassword(e.target.value)} placeholder="ENTER NEW PASSCODE" className="bg-black/50 border-2 border-red-500/50 focus:border-red-400 focus:ring-0 text-center text-amber-300 font-bold tracking-widest w-full px-4 py-2 rounded-md transition-colors" />
setConfirmPassword(e.target.value)} placeholder="CONFIRM NEW PASSCODE" className="bg-black/50 border-2 border-red-500/50 focus:border-red-400 focus:ring-0 text-center text-amber-300 font-bold tracking-widest w-full px-4 py-2 rounded-md transition-colors" />
{error &&

{error}

}
); }; // ----------------------------------------------------------------------------- // COMPONENTS: Mission Control // ----------------------------------------------------------------------------- const MissionCard = ({ mission, children }) => { const isExpandable = mission.status === MissionStatus.ASSIGNED; return (

{mission.description}

{mission.points} PP

{isExpandable && children && (

Submit your field report below to complete this objective.

{children}
)}
); }; const MissionSubmissionForm = ({ mission, onSubmit }) => { const [text, setText] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); const handleSubmit = async (e) => { e.preventDefault(); if (text.trim() && !isSubmitting) { setIsSubmitting(true); await onSubmit(mission.id, text.trim()); setIsSubmitting(false); } }; const isSubmitDisabled = !text.trim() || isSubmitting; return (