Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>FaceSleuth Pro</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script> | |
| <style> | |
| .gradient-bg { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| } | |
| .glass-effect { | |
| background: rgba(255, 255, 255, 0.1); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid rgba(255, 255, 255, 0.2); | |
| } | |
| .upload-area { | |
| border: 2px dashed rgba(255, 255, 255, 0.3); | |
| transition: all 0.3s ease; | |
| } | |
| .upload-area:hover { | |
| border-color: rgba(255, 255, 255, 0.5); | |
| background: rgba(255, 255, 255, 0.05); | |
| } | |
| .pulse-animation { | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { transform: scale(1); } | |
| 50% { transform: scale(1.05); } | |
| 100% { transform: scale(1); } | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .animate-fade-in { | |
| animation: fadeIn 0.5s ease-out forwards; | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen text-white gradient-bg"> | |
| <div id="vanta-bg" class="absolute inset-0 z-0"></div> | |
| <!-- Navigation --> | |
| <nav class="relative z-10 glass-effect p-4"> | |
| <div class="container mx-auto flex justify-between items-center"> | |
| <div class="flex items-center space-x-2"> | |
| <i data-feather="search" class="w-6 h-6"></i> | |
| <h1 class="text-xl font-bold">FaceSleuth Pro</h1> | |
| </div> | |
| <div class="flex space-x-4"> | |
| <a href="#" class="hover:text-gray-200 transition">Home</a> | |
| <a href="#" class="hover:text-gray-200 transition">About</a> | |
| <a href="#" class="hover:text-gray-200 transition">Contact</a> | |
| </div> | |
| </div> | |
| </nav> | |
| <!-- Main Content --> | |
| <main class="relative z-10 container mx-auto px-4 py-16"> | |
| <div class="max-w-4xl mx-auto text-center"> | |
| <h2 class="text-5xl font-bold mb-6">Uncover Digital Identities with AI-Powered Face Search</h2> | |
| <p class="text-xl mb-12 opacity-90">Upload a face photo and let our advanced algorithms search the web for matching identities and information.</p> | |
| <!-- Upload Section --> | |
| <div class="glass-effect rounded-2xl p-8 mb-12"> | |
| <div id="uploadArea" class="upload-area rounded-xl p-12 text-center cursor-pointer mb-6"> | |
| <i data-feather="upload-cloud" class="w-16 h-16 mx-auto mb-4 opacity-70"></i> | |
| <h3 class="text-2xl font-semibold mb-2">Drop Face Image Here</h3> | |
| <p class="opacity-80 mb-4">or click to browse your files</p> | |
| <p class="text-sm opacity-60">Supports JPG, PNG, WEBP • Max 5MB</p> | |
| <input type="file" id="fileInput" class="hidden" accept="image/*"> | |
| </div> | |
| <!-- Preview Section --> | |
| <div id="previewSection" class="hidden"> | |
| <div class="flex flex-col md:flex-row items-center justify-center space-y-6 md:space-y-0 md:space-x-8"> | |
| <div class="text-center"> | |
| <h4 class="font-semibold mb-4">Uploaded Image</h4> | |
| <img id="imagePreview" class="w-48 h-48 object-cover rounded-lg shadow-lg mx-auto"> | |
| </div> | |
| <div class="flex items-center"> | |
| <i data-feather="arrow-right" class="w-8 h-8 opacity-60"></i> | |
| </div> | |
| <div class="text-center"> | |
| <h4 class="font-semibold mb-4">Search Results</h4> | |
| <div id="resultsPlaceholder" class="w-48 h-48 glass-effect rounded-lg flex items-center justify-center"> | |
| <i data-feather="search" class="w-12 h-12 opacity-40"></i> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Action Button --> | |
| <button id="searchBtn" class="hidden mt-8 bg-white text-purple-600 px-8 py-4 rounded-full font-semibold hover:bg-gray-100 transition-all duration-300 transform hover:scale-105 pulse-animation"> | |
| <div class="flex items-center justify-center space-x-2"> | |
| <i data-feather="search" class="w-5 h-5"></i> | |
| <span>Start Reverse Search</span> | |
| </div> | |
| </button> | |
| <!-- Search Results Section --> | |
| <div id="resultsSection" class="hidden mt-8"> | |
| <div class="text-left mb-4"> | |
| <h4 class="text-lg font-semibold mb-2">Found Matches</h4> | |
| <p class="text-sm opacity-70">Showing 3 potential matches found across social media and public databases</p> | |
| </div> | |
| <div id="resultsGrid" class="grid grid-cols-1 md:grid-cols-3 gap-4"> | |
| <!-- Results will be dynamically inserted here --> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Features --> | |
| <div class="grid md:grid-cols-3 gap-8 mb-16"> | |
| <div class="glass-effect p-6 rounded-xl text-center"> | |
| <i data-feather="shield" class="w-12 h-12 mx-auto mb-4 opacity-70"></i> | |
| <h4 class="text-lg font-semibold mb-2">Secure & Private</h4> | |
| <p class="opacity-80">Your searches are encrypted and never stored on our servers</p> | |
| </div> | |
| <div class="glass-effect p-6 rounded-xl text-center"> | |
| <i data-feather="zap" class="w-12 h-12 mx-auto mb-4 opacity-70"></i> | |
| <h4 class="text-lg font-semibold mb-2">Lightning Fast</h4> | |
| <p class="opacity-80">Get results in seconds with our optimized search algorithms</p> | |
| </div> | |
| <div class="glass-effect p-6 rounded-xl text-center"> | |
| <i data-feather="globe" class="w-12 h-12 mx-auto mb-4 opacity-70"></i> | |
| <h4 class="text-lg font-semibold mb-2">Global Database</h4> | |
| <p class="opacity-80">Search across millions of web pages and social media platforms</p> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <!-- Footer --> | |
| <footer class="relative z-10 glass-effect py-8"> | |
| <div class="container mx-auto px-4 text-center"> | |
| <p class="opacity-80">© 2024 FaceSleuth Pro. Digital identity investigation made simple.</p> | |
| </div> | |
| </footer> | |
| <script> | |
| // Initialize Vanta.js | |
| VANTA.GLOBE({ | |
| el: "#vanta-bg", | |
| mouseControls: true, | |
| touchControls: true, | |
| gyroControls: false, | |
| minHeight: 200.00, | |
| minWidth: 200.00, | |
| scale: 1.00, | |
| scaleMobile: 1.00, | |
| color: 0xffffff, | |
| backgroundColor: 0x667eea | |
| }); | |
| // File upload functionality | |
| const uploadArea = document.getElementById('uploadArea'); | |
| const fileInput = document.getElementById('fileInput'); | |
| const previewSection = document.getElementById('previewSection'); | |
| const imagePreview = document.getElementById('imagePreview'); | |
| const searchBtn = document.getElementById('searchBtn'); | |
| const resultsPlaceholder = document.getElementById('resultsPlaceholder'); | |
| uploadArea.addEventListener('click', (e) => { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| fileInput.click(); | |
| }); | |
| uploadArea.addEventListener('dragover', (e) => { | |
| e.preventDefault(); | |
| uploadArea.classList.add('border-white', 'bg-white', 'bg-opacity-10'); | |
| }); | |
| uploadArea.addEventListener('dragleave', () => { | |
| uploadArea.classList.remove('border-white', 'bg-white', 'bg-opacity-10'); | |
| }); | |
| uploadArea.addEventListener('drop', (e) => { | |
| e.preventDefault(); | |
| uploadArea.classList.remove('border-white', 'bg-white', 'bg-opacity-10'); | |
| const file = e.dataTransfer.files[0]; | |
| handleFile(file); | |
| }); | |
| fileInput.addEventListener('change', (e) => { | |
| const file = e.target.files[0]; | |
| if (file) { | |
| handleFile(file); | |
| } | |
| }); | |
| function handleFile(file) { | |
| if (file && file.type.startsWith('image/')) { | |
| const reader = new FileReader(); | |
| reader.onload = (e) => { | |
| imagePreview.src = e.target.result; | |
| previewSection.classList.remove('hidden'); | |
| searchBtn.classList.remove('hidden'); | |
| uploadArea.classList.add('hidden'); | |
| }; | |
| reader.readAsDataURL(file); | |
| } else { | |
| alert('Please select a valid image file (JPG, PNG, WEBP)'); | |
| } | |
| } | |
| // Generate random results data | |
| function generateSearchResults() { | |
| const sources = [ | |
| { name: 'LinkedIn', icon: 'linkedin' }, | |
| { name: 'Facebook', icon: 'facebook' }, | |
| { name: 'Twitter/X', icon: 'twitter' }, | |
| { name: 'Instagram', icon: 'instagram' }, | |
| { name: 'News Article', icon: 'file-text' }, | |
| { name: 'Company Website', icon: 'globe' } | |
| ]; | |
| const results = []; | |
| const usedIndices = new Set(); | |
| for (let i = 0; i < 3; i++) { | |
| let randomIndex; | |
| do { | |
| randomIndex = Math.floor(Math.random() * sources.length); | |
| } while (usedIndices.has(randomIndex)); | |
| usedIndices.add(randomIndex); | |
| const confidence = Math.floor(Math.random() * (98 - 65) + 65); | |
| const seed = Math.floor(Math.random() * 900) + 1; | |
| results.push({ | |
| source: sources[randomIndex], | |
| confidence: confidence, | |
| imageUrl: `https://static.photos/people/320x240/${seed}`, | |
| url: `https://example.com/profile/${seed}`, | |
| name: `Match ${i + 1}`, | |
| foundOn: new Date(Date.now() - Math.floor(Math.random() * 10000000000)).toLocaleDateString() | |
| }); | |
| } | |
| return results.sort((a, b) => b.confidence - a.confidence); | |
| } | |
| // Render search results | |
| function renderResults(results) { | |
| const resultsGrid = document.getElementById('resultsGrid'); | |
| resultsGrid.innerHTML = ''; | |
| results.forEach((result, index) => { | |
| const card = document.createElement('div'); | |
| card.className = 'glass-effect rounded-xl overflow-hidden hover:bg-white hover:bg-opacity-20 transition-all duration-300 cursor-pointer group animate-fade-in'; | |
| card.style.animationDelay = `${index * 0.2}s`; | |
| card.innerHTML = ` | |
| <div class="relative"> | |
| <img src="${result.imageUrl}" alt="Match" class="w-full h-40 object-cover"> | |
| <div class="absolute top-2 right-2 bg-black bg-opacity-70 text-white px-2 py-1 rounded-full text-xs font-bold flex items-center"> | |
| <i data-feather="activity" class="w-3 h-3 mr-1"></i> | |
| ${result.confidence}% | |
| </div> | |
| </div> | |
| <div class="p-4"> | |
| <div class="flex items-center justify-between mb-2"> | |
| <span class="text-xs font-semibold opacity-70 uppercase tracking-wide">${result.source.name}</span> | |
| <i data-feather="${result.source.icon}" class="w-4 h-4 opacity-60"></i> | |
| </div> | |
| <h5 class="font-semibold text-sm mb-1 group-hover:text-gray-200">Potential Match</h5> | |
| <p class="text-xs opacity-60 mb-2">Found on ${result.foundOn}</p> | |
| <a href="${result.url}" target="_blank" class="text-xs text-blue-300 hover:text-blue-200 flex items-center mt-2 opacity-80 hover:opacity-100 transition"> | |
| View Source <i data-feather="external-link" class="w-3 h-3 ml-1"></i> | |
| </a> | |
| </div> | |
| `; | |
| resultsGrid.appendChild(card); | |
| }); | |
| feather.replace(); | |
| } | |
| searchBtn.addEventListener('click', async () => { | |
| const originalBtnContent = '<div class="flex items-center justify-center space-x-2"><i data-feather="search" class="w-5 h-5"></i><span>Start Reverse Search</span></div>'; | |
| searchBtn.innerHTML = '<div class="flex items-center justify-center space-x-2"><div class="animate-spin rounded-full h-5 w-5 border-b-2 border-purple-600"></div><span>Searching databases...</span></div>'; | |
| searchBtn.disabled = true; | |
| const resultsSection = document.getElementById('resultsSection'); | |
| resultsSection.classList.add('hidden'); | |
| // Simulate API call with progress steps | |
| const steps = ['Scanning social networks...', 'Checking public records...', 'Analyzing patterns...', 'Finalizing results...']; | |
| let stepIndex = 0; | |
| const progressInterval = setInterval(() => { | |
| if (stepIndex < steps.length) { | |
| searchBtn.innerHTML = `<div class="flex items-center justify-center space-x-2"><div class="animate-spin rounded-full h-5 w-5 border-b-2 border-purple-600"></div><span>${steps[stepIndex]}</span></div>`; | |
| stepIndex++; | |
| } | |
| }, 600); | |
| setTimeout(() => { | |
| clearInterval(progressInterval); | |
| const results = generateSearchResults(); | |
| // Update placeholder to show success | |
| resultsPlaceholder.innerHTML = ` | |
| <div class="text-center p-4"> | |
| <i data-feather="check-circle" class="w-12 h-12 text-green-400 mx-auto mb-3"></i> | |
| <p class="text-sm font-semibold">${results.length} matches found</p> | |
| <p class="text-xs opacity-60 mt-2">Analysis complete</p> | |
| </div> | |
| `; | |
| // Show detailed results | |
| renderResults(results); | |
| resultsSection.classList.remove('hidden'); | |
| resultsSection.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); | |
| searchBtn.innerHTML = '<div class="flex items-center justify-center space-x-2"><i data-feather="refresh-cw" class="w-5 h-5"></i><span>Search Again</span></div>'; | |
| searchBtn.disabled = false; | |
| feather.replace(); | |
| }, 2800); | |
| }); | |
| // Initialize feather icons | |
| feather.replace(); | |
| </script> | |
| </body> | |
| </html> | |