ppok / index.html
Kucjt's picture
"https://api.proxyscrape.com/v2/?request=getproxies&protocol=http&timeout=10000&country=all", "https://api.proxyscrape.com/v2/?request=getproxies&protocol=https&timeout=10000&country=all", "https://api.proxyscrape.com/v2/?request=getproxies&protocol=socks4&timeout=10000&country=all", "https://api.proxyscrape.com/v2/?request=getproxies&protocol=socks5&timeout=10000&country=all", "https://www.proxy-list.download/api/v1/get?type=http", "https://www.proxy-list.download/api/v1/get?type=https", "https://www.proxy-list.download/api/v1/get?type=socks4", "https://www.proxy-list.download/api/v1/get?type=socks5", "https://openproxy.space/list/http", "https://openproxy.space/list/socks4", "https://openproxy.space/list/socks5", "https://proxylist.geonode.com/api/proxy-list?limit=500&page=1&sort_by=lastChecked&sort_type=desc", "https://raw.githubusercontent.com/almroot/proxylist/master/list.txt", "https://raw.githubusercontent.com/Anonym0usWork1221/Free-Proxies/main/proxy_files/http_proxies.txt", "https://raw.githubusercontent.com/Anonym0usWork1221/Free-Proxies/main/proxy_files/socks4_proxies.txt", "https://raw.githubusercontent.com/Anonym0usWork1221/Free-Proxies/main/proxy_files/socks5_proxies.txt", "https://www.us-proxy.org/", "https://free-proxy-list.net/", "https://www.sslproxies.org/", "https://www.socks-proxy.net/", "https://www.proxy-list.download/api/v1/get?type=elite", "https://raw.githubusercontent.com/clarketm/proxy-list/master/proxy-list-raw.txt", "https://raw.githubusercontent.com/TheSpeedX/PROXY-List/master/http.txt", "https://raw.githubusercontent.com/TheSpeedX/PROXY-List/master/socks4.txt", "https://raw.githubusercontent.com/TheSpeedX/PROXY-List/master/socks5.txt", "https://raw.githubusercontent.com/ShiftyTR/Proxy-List/master/http.txt", "https://raw.githubusercontent.com/ShiftyTR/Proxy-List/master/socks4.txt", "https://raw.githubusercontent.com/ShiftyTR/Proxy-List/master/socks5.txt", "https://www.proxy-list.download/api/v1/get?type=transparent", "https://proxyspider.com/api/proxies.json?limit=1000", "https://proxy-daily.com/api/proxy?limit=100", "https://raw.githubusercontent.com/mertguvencli/http-proxy-list/main/proxy-list/data.txt", "https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-http.txt", "https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-socks4.txt", "https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-socks5.txt", "https://www.proxyscan.io/download?type=http", "https://www.proxyscan.io/download?type=socks4", "https://www.proxyscan.io/download?type=socks5", "https://raw.githubusercontent.com/hookzof/socks5_list/master/proxy.txt", "https://www.freeproxychecker.com/result/http_proxies.txt", "https://www.freeproxychecker.com/result/socks4_proxies.txt" ] # Endpoints for proxy testing TEST_URLS = [ "http://httpbin.org/ip", "http://api.ipify.org/", "http://icanhazip.com/", ] it should really be working - Follow Up Deployment
27a58da verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ProxyScraper Pro - Free Proxy Fetcher</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.gradient-bg {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.proxy-card {
transition: all 0.3s ease;
}
.proxy-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0,0,0,0.1);
}
.progress-bar {
height: 5px;
background-color: #e0e0e0;
border-radius: 2px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);
transition: width 0.3s ease;
}
#proxyList {
max-height: 400px;
overflow-y: auto;
}
/* Custom scrollbar */
#proxyList::-webkit-scrollbar {
width: 6px;
}
#proxyList::-webkit-scrollbar-track {
background: #f1f1f1;
}
#proxyList::-webkit-scrollbar-thumb {
background: #888;
border-radius: 3px;
}
#proxyList::-webkit-scrollbar-thumb:hover {
background: #555;
}
</style>
</head>
<body class="bg-gray-100">
<header class="gradient-bg text-white shadow-lg">
<div class="container mx-auto px-4 py-6">
<div class="flex flex-col md:flex-row justify-between items-center">
<div class="flex items-center mb-4 md:mb-0">
<i class="fas fa-shield-alt text-3xl mr-3"></i>
<h1 class="text-2xl md:text-3xl font-bold">ProxyScraper Pro</h1>
</div>
<div class="flex items-center space-x-4">
<div class="hidden md:flex items-center space-x-2">
<i class="fas fa-sync-alt"></i>
<span>Auto-update every <span id="updateInterval">30</span> min</span>
</div>
<button id="settingsBtn" class="p-2 rounded-full hover:bg-white hover:bg-opacity-20 transition">
<i class="fas fa-cog"></i>
</button>
</div>
</div>
</div>
</header>
<main class="container mx-auto px-4 py-8">
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Control Panel -->
<div class="lg:col-span-1">
<div class="bg-white rounded-lg shadow-md p-6 sticky top-6">
<h2 class="text-xl font-semibold mb-4 flex items-center">
<i class="fas fa-sliders-h mr-2 text-blue-500"></i> Control Panel
</h2>
<div class="mb-6">
<label class="block text-gray-700 mb-2">Proxy Sources</label>
<div class="flex items-center mb-2">
<input type="checkbox" id="githubCheck" class="mr-2" checked>
<label for="githubCheck">GitHub Repositories</label>
</div>
<div class="flex items-center mb-2">
<input type="checkbox" id="customCheck" class="mr-2">
<label for="customCheck">Custom URLs</label>
</div>
<div id="customUrlsContainer" class="hidden mt-2">
<textarea id="customUrls" class="w-full p-2 border rounded" rows="3" placeholder="Enter custom proxy URLs (one per line)"></textarea>
</div>
</div>
<div class="mb-6">
<label class="block text-gray-700 mb-2">Proxy Types</label>
<div class="grid grid-cols-2 gap-2">
<div class="flex items-center">
<input type="checkbox" id="httpCheck" class="mr-2" checked>
<label for="httpCheck">HTTP</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="httpsCheck" class="mr-2" checked>
<label for="httpsCheck">HTTPS</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="socks4Check" class="mr-2" checked>
<label for="socks4Check">SOCKS4</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="socks5Check" class="mr-2" checked>
<label for="socks5Check">SOCKS5</label>
</div>
</div>
</div>
<div class="mb-6">
<label for="timeout" class="block text-gray-700 mb-2">Timeout (seconds)</label>
<input type="number" id="timeout" min="1" max="30" value="5" class="w-full p-2 border rounded">
</div>
<div class="mb-6">
<label for="limit" class="block text-gray-700 mb-2">Proxy Limit</label>
<input type="number" id="limit" min="1" max="10000" value="500" class="w-full p-2 border rounded">
</div>
<button id="fetchBtn" class="w-full bg-blue-500 hover:bg-blue-600 text-white py-3 px-4 rounded-lg font-medium transition flex items-center justify-center">
<i class="fas fa-bolt mr-2"></i> Fetch Proxies
</button>
<div id="progressContainer" class="mt-4 hidden">
<div class="flex justify-between text-sm text-gray-600 mb-1">
<span>Progress</span>
<span id="progressText">0%</span>
</div>
<div class="progress-bar">
<div id="progressFill" class="progress-fill" style="width: 0%"></div>
</div>
</div>
</div>
</div>
<!-- Results Section -->
<div class="lg:col-span-2">
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-semibold flex items-center">
<i class="fas fa-list-ul mr-2 text-green-500"></i> Results
</h2>
<div class="flex space-x-2">
<button id="exportBtn" class="bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded-lg text-sm transition flex items-center disabled:opacity-50" disabled>
<i class="fas fa-file-export mr-1"></i> Export
</button>
<button id="copyBtn" class="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-lg text-sm transition flex items-center disabled:opacity-50" disabled>
<i class="fas fa-copy mr-1"></i> Copy
</button>
<button id="clearBtn" class="bg-gray-500 hover:bg-gray-600 text-white py-2 px-4 rounded-lg text-sm transition flex items-center">
<i class="fas fa-trash-alt mr-1"></i> Clear
</button>
</div>
</div>
<div class="flex justify-between items-center mb-4">
<div class="flex space-x-4">
<div class="text-center">
<div class="text-2xl font-bold text-blue-500" id="totalProxies">0</div>
<div class="text-xs text-gray-500">Total</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-green-500" id="workingProxies">0</div>
<div class="text-xs text-gray-500">Working</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-red-500" id="failedProxies">0</div>
<div class="text-xs text-gray-500">Failed</div>
</div>
</div>
<div class="text-sm text-gray-500">
Last updated: <span id="lastUpdated">Never</span>
</div>
</div>
<div class="border rounded-lg overflow-hidden">
<div id="proxyList" class="divide-y divide-gray-200">
<div class="p-4 text-center text-gray-500">
No proxies fetched yet. Click "Fetch Proxies" to start.
</div>
</div>
</div>
</div>
<!-- Stats Section -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h2 class="text-xl font-semibold mb-4 flex items-center">
<i class="fas fa-chart-pie mr-2 text-purple-500"></i> Proxy Types
</h2>
<div id="typeChart" class="h-48 flex items-center justify-center">
<div class="text-gray-400">No data available</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h2 class="text-xl font-semibold mb-4 flex items-center">
<i class="fas fa-globe mr-2 text-orange-500"></i> Countries
</h2>
<div id="countryChart" class="h-48 flex items-center justify-center">
<div class="text-gray-400">No data available</div>
</div>
</div>
</div>
</div>
</div>
</main>
<!-- Settings Modal -->
<div id="settingsModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
<div class="bg-white rounded-lg shadow-xl p-6 w-full max-w-md">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-semibold">Settings</h3>
<button id="closeSettings" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div class="mb-4">
<label for="autoUpdate" class="block text-gray-700 mb-2">Auto-update Interval (minutes)</label>
<input type="number" id="autoUpdate" min="5" max="240" value="30" class="w-full p-2 border rounded">
</div>
<div class="mb-4">
<label class="block text-gray-700 mb-2">Notification</label>
<div class="flex items-center">
<input type="checkbox" id="enableNotifications" class="mr-2">
<label for="enableNotifications">Enable desktop notifications</label>
</div>
</div>
<div class="mb-4">
<label class="block text-gray-700 mb-2">Dark Mode</label>
<div class="flex items-center">
<input type="checkbox" id="darkMode" class="mr-2">
<label for="darkMode">Enable dark mode</label>
</div>
</div>
<div class="flex justify-end space-x-3 mt-6">
<button id="cancelSettings" class="px-4 py-2 border rounded-lg text-gray-700 hover:bg-gray-100 transition">
Cancel
</button>
<button id="saveSettings" class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition">
Save
</button>
</div>
</div>
</div>
<footer class="bg-gray-800 text-white py-6 mt-12">
<div class="container mx-auto px-4">
<div class="flex flex-col md:flex-row justify-between items-center">
<div class="mb-4 md:mb-0">
<p>&copy; 2023 ProxyScraper Pro. All rights reserved.</p>
</div>
<div class="flex space-x-4">
<a href="#" class="hover:text-blue-300 transition">Privacy Policy</a>
<a href="#" class="hover:text-blue-300 transition">Terms of Service</a>
<a href="#" class="hover:text-blue-300 transition">GitHub</a>
</div>
</div>
</div>
</footer>
<script>
// DOM Elements
const fetchBtn = document.getElementById('fetchBtn');
const exportBtn = document.getElementById('exportBtn');
const copyBtn = document.getElementById('copyBtn');
const clearBtn = document.getElementById('clearBtn');
const settingsBtn = document.getElementById('settingsBtn');
const closeSettings = document.getElementById('closeSettings');
const cancelSettings = document.getElementById('cancelSettings');
const saveSettings = document.getElementById('saveSettings');
const settingsModal = document.getElementById('settingsModal');
const customCheck = document.getElementById('customCheck');
const customUrlsContainer = document.getElementById('customUrlsContainer');
const proxyList = document.getElementById('proxyList');
const progressContainer = document.getElementById('progressContainer');
const progressFill = document.getElementById('progressFill');
const progressText = document.getElementById('progressText');
const totalProxies = document.getElementById('totalProxies');
const workingProxies = document.getElementById('workingProxies');
const failedProxies = document.getElementById('failedProxies');
const lastUpdated = document.getElementById('lastUpdated');
const updateInterval = document.getElementById('updateInterval');
// State
let proxies = [];
let workingProxyCount = 0;
let failedProxyCount = 0;
let autoUpdateTimer = null;
// Event Listeners
fetchBtn.addEventListener('click', fetchProxies);
exportBtn.addEventListener('click', exportProxies);
copyBtn.addEventListener('click', copyProxies);
clearBtn.addEventListener('click', clearProxies);
settingsBtn.addEventListener('click', () => settingsModal.classList.remove('hidden'));
closeSettings.addEventListener('click', () => settingsModal.classList.add('hidden'));
cancelSettings.addEventListener('click', () => settingsModal.classList.add('hidden'));
saveSettings.addEventListener('click', saveSettingsHandler);
customCheck.addEventListener('change', toggleCustomUrls);
// Functions
function toggleCustomUrls() {
customUrlsContainer.classList.toggle('hidden', !customCheck.checked);
}
// Proxy endpoints
const PROXY_ENDPOINTS = [
"https://api.proxyscrape.com/v2/?request=getproxies&protocol=http&timeout=10000&country=all",
"https://api.proxyscrape.com/v2/?request=getproxies&protocol=https&timeout=10000&country=all",
"https://api.proxyscrape.com/v2/?request=getproxies&protocol=socks4&timeout=10000&country=all",
"https://api.proxyscrape.com/v2/?request=getproxies&protocol=socks5&timeout=10000&country=all",
"https://www.proxy-list.download/api/v1/get?type=http",
"https://www.proxy-list.download/api/v1/get?type=https",
"https://www.proxy-list.download/api/v1/get?type=socks4",
"https://www.proxy-list.download/api/v1/get?type=socks5",
"https://openproxy.space/list/http",
"https://openproxy.space/list/socks4",
"https://openproxy.space/list/socks5",
"https://proxylist.geonode.com/api/proxy-list?limit=500&page=1&sort_by=lastChecked&sort_type=desc",
"https://raw.githubusercontent.com/almroot/proxylist/master/list.txt",
"https://raw.githubusercontent.com/Anonym0usWork1221/Free-Proxies/main/proxy_files/http_proxies.txt",
"https://raw.githubusercontent.com/Anonym0usWork1221/Free-Proxies/main/proxy_files/socks4_proxies.txt",
"https://raw.githubusercontent.com/Anonym0usWork1221/Free-Proxies/main/proxy_files/socks5_proxies.txt",
"https://raw.githubusercontent.com/clarketm/proxy-list/master/proxy-list-raw.txt",
"https://raw.githubusercontent.com/TheSpeedX/PROXY-List/master/http.txt",
"https://raw.githubusercontent.com/TheSpeedX/PROXY-List/master/socks4.txt",
"https://raw.githubusercontent.com/TheSpeedX/PROXY-List/master/socks5.txt",
"https://raw.githubusercontent.com/ShiftyTR/Proxy-List/master/http.txt",
"https://raw.githubusercontent.com/ShiftyTR/Proxy-List/master/socks4.txt",
"https://raw.githubusercontent.com/ShiftyTR/Proxy-List/master/socks5.txt",
"https://raw.githubusercontent.com/mertguvencli/http-proxy-list/main/proxy-list/data.txt",
"https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-http.txt",
"https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-socks4.txt",
"https://raw.githubusercontent.com/jetkai/proxy-list/main/online-proxies/txt/proxies-socks5.txt",
"https://raw.githubusercontent.com/hookzof/socks5_list/master/proxy.txt"
];
// Test URLs for validation
const TEST_URLS = [
"http://httpbin.org/ip",
"http://api.ipify.org/",
"http://icanhazip.com/"
];
async function fetchProxies() {
// Reset state
proxies = [];
workingProxyCount = 0;
failedProxyCount = 0;
updateCounters();
// Show loading state
fetchBtn.disabled = true;
fetchBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Fetching...';
progressContainer.classList.remove('hidden');
const proxyTypes = [];
if (document.getElementById('httpCheck').checked) proxyTypes.push('http');
if (document.getElementById('httpsCheck').checked) proxyTypes.push('https');
if (document.getElementById('socks4Check').checked) proxyTypes.push('socks4');
if (document.getElementById('socks5Check').checked) proxyTypes.push('socks5');
const limit = parseInt(document.getElementById('limit').value);
const timeout = parseInt(document.getElementById('timeout').value);
try {
// Fetch from all endpoints in parallel
const responses = await Promise.allSettled(
PROXY_ENDPOINTS.map(url => fetch(url).then(res => res.text()))
);
// Process responses
let rawProxies = [];
responses.forEach(response => {
if (response.status === 'fulfilled') {
const proxiesFromEndpoint = response.value
.split('\n')
.map(p => p.trim())
.filter(p => p && p.includes(':'));
rawProxies = [...rawProxies, ...proxiesFromEndpoint];
}
});
// Deduplicate
const uniqueProxies = [...new Set(rawProxies)];
// Shuffle and limit
const shuffledProxies = uniqueProxies
.sort(() => 0.5 - Math.random())
.slice(0, limit);
// Validate proxies
await validateProxies(shuffledProxies, timeout);
} catch (error) {
console.error('Error fetching proxies:', error);
alert('Error fetching proxies. Check console for details.');
} finally {
fetchBtn.disabled = false;
fetchBtn.innerHTML = '<i class="fas fa-bolt mr-2"></i> Fetch Proxies';
exportBtn.disabled = workingProxyCount === 0;
copyBtn.disabled = workingProxyCount === 0;
lastUpdated.textContent = new Date().toLocaleString();
if (!autoUpdateTimer) {
startAutoUpdate();
}
}
}
async function validateProxies(proxyList, timeout) {
const batchSize = 20;
const testUrl = TEST_URLS[Math.floor(Math.random() * TEST_URLS.length)];
for (let i = 0; i < proxyList.length; i += batchSize) {
const batch = proxyList.slice(i, i + batchSize);
const batchPromises = batch.map(proxy => testProxy(proxy, testUrl, timeout));
const results = await Promise.allSettled(batchPromises);
results.forEach((result, index) => {
const proxy = batch[index];
if (result.status === 'fulfilled' && result.value) {
proxies.push({
proxy,
type: result.value.type || 'unknown',
country: result.value.country || 'unknown',
isWorking: true,
latency: result.value.latency
});
workingProxyCount++;
} else {
proxies.push({
proxy,
type: 'unknown',
country: 'unknown',
isWorking: false,
latency: null
});
failedProxyCount++;
}
});
updateCounters();
displayProxies();
updateProgress((i / proxyList.length) * 100);
}
updateProgress(100);
}
async function testProxy(proxy, testUrl, timeout) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout * 1000);
try {
const startTime = Date.now();
const response = await fetch(testUrl, {
signal: controller.signal,
headers: { 'Accept': 'application/json' }
});
if (!response.ok) throw new Error('Invalid response');
const latency = Date.now() - startTime;
const data = await response.json();
return {
type: 'http', // Simplified for demo - would detect actual type
country: 'unknown', // Could implement geo lookup
latency
};
} catch (error) {
throw error;
} finally {
clearTimeout(timeoutId);
}
}
function updateProgress(percent) {
progressFill.style.width = `${percent}%`;
progressText.textContent = `${Math.round(percent)}%`;
}
function updateCounters() {
totalProxies.textContent = proxies.length;
workingProxies.textContent = workingProxyCount;
failedProxies.textContent = failedProxyCount;
}
function displayProxies() {
if (proxies.length === 0) {
proxyList.innerHTML = '<div class="p-4 text-center text-gray-500">No proxies fetched yet. Click "Fetch Proxies" to start.</div>';
return;
}
proxyList.innerHTML = '';
// Sort by working first, then by latency
const sortedProxies = [...proxies].sort((a, b) => {
if (a.isWorking !== b.isWorking) return b.isWorking - a.isWorking;
if (a.isWorking && b.isWorking) return (a.latency || 0) - (b.latency || 0);
return 0;
});
sortedProxies.forEach(proxy => {
const proxyElement = document.createElement('div');
proxyElement.className = 'p-3 flex items-center justify-between proxy-card';
const statusClass = proxy.isWorking ? 'bg-green-500' : 'bg-red-500';
const statusText = proxy.isWorking ? 'Working' : 'Failed';
proxyElement.innerHTML = `
<div class="flex items-center space-x-3">
<div class="w-3 h-3 rounded-full ${statusClass}"></div>
<div class="font-mono">${proxy.proxy}</div>
<span class="px-2 py-1 text-xs rounded-full bg-gray-100">${proxy.type}</span>
<span class="px-2 py-1 text-xs rounded-full bg-gray-100">${proxy.country}</span>
</div>
<div class="text-sm text-gray-500">
${proxy.isWorking ? `${proxy.latency}ms` : statusText}
</div>
`;
proxyList.appendChild(proxyElement);
});
}
function exportProxies() {
if (proxies.length === 0) return;
const workingProxies = proxies.filter(p => p.isWorking).map(p => p.proxy);
if (workingProxies.length === 0) {
alert('No working proxies to export!');
return;
}
const blob = new Blob([workingProxies.join('\n')], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `proxies_${new Date().toISOString().slice(0, 10)}.txt`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
function copyProxies() {
if (proxies.length === 0) return;
const workingProxies = proxies.filter(p => p.isWorking).map(p => p.proxy);
if (workingProxies.length === 0) {
alert('No working proxies to copy!');
return;
}
navigator.clipboard.writeText(workingProxies.join('\n'))
.then(() => {
const originalText = copyBtn.innerHTML;
copyBtn.innerHTML = '<i class="fas fa-check mr-1"></i> Copied!';
setTimeout(() => {
copyBtn.innerHTML = originalText;
}, 2000);
})
.catch(err => {
console.error('Failed to copy: ', err);
});
}
function clearProxies() {
proxies = [];
workingProxyCount = 0;
failedProxyCount = 0;
updateCounters();
proxyList.innerHTML = '<div class="p-4 text-center text-gray-500">No proxies fetched yet. Click "Fetch Proxies" to start.</div>';
exportBtn.disabled = true;
copyBtn.disabled = true;
lastUpdated.textContent = 'Never';
// Clear auto-update timer
if (autoUpdateTimer) {
clearInterval(autoUpdateTimer);
autoUpdateTimer = null;
}
}
function saveSettingsHandler() {
const interval = parseInt(document.getElementById('autoUpdate').value);
updateInterval.textContent = interval;
// Restart auto-update with new interval
if (autoUpdateTimer) {
clearInterval(autoUpdateTimer);
startAutoUpdate();
}
// In a real app, you would save other settings to localStorage
settingsModal.classList.add('hidden');
}
function startAutoUpdate() {
const interval = parseInt(document.getElementById('autoUpdate').value) * 60 * 1000;
autoUpdateTimer = setInterval(fetchProxies, interval);
}
// Initialize
toggleCustomUrls();
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Kucjt/ppok" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>