|
<!DOCTYPE html> |
|
<html lang="ru"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>WorkTime Bot</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> |
|
body { |
|
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; |
|
background-color: var(--tg-theme-bg-color, #f7f8fc); |
|
color: var(--tg-theme-text-color, #000000); |
|
} |
|
|
|
.header { |
|
background-color: var(--tg-theme-header-bg-color, #0088cc); |
|
color: var(--tg-theme-header-text-color, #ffffff); |
|
} |
|
|
|
.button-primary { |
|
background-color: var(--tg-theme-button-color, #0088cc); |
|
color: var(--tg-theme-button-text-color, #ffffff); |
|
} |
|
|
|
.button-secondary { |
|
background-color: var(--tg-theme-secondary-bg-color, #ebedf0); |
|
color: var(--tg-theme-text-color, #000000); |
|
} |
|
|
|
.card { |
|
background-color: var(--tg-theme-bg-color, #ffffff); |
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); |
|
} |
|
|
|
.progress-bar { |
|
height: 6px; |
|
border-radius: 3px; |
|
background-color: var(--tg-theme-secondary-bg-color, #ebedf0); |
|
} |
|
|
|
.progress-fill { |
|
height: 100%; |
|
border-radius: 3px; |
|
background-color: var(--tg-theme-button-color, #0088cc); |
|
transition: width 0.3s ease; |
|
} |
|
|
|
.pulse { |
|
animation: pulse 2s infinite; |
|
} |
|
|
|
@keyframes pulse { |
|
0% { |
|
box-shadow: 0 0 0 0 rgba(0, 136, 204, 0.7); |
|
} |
|
70% { |
|
box-shadow: 0 0 0 10px rgba(0, 136, 204, 0); |
|
} |
|
100% { |
|
box-shadow: 0 0 0 0 rgba(0, 136, 204, 0); |
|
} |
|
} |
|
|
|
.fade-in { |
|
animation: fadeIn 0.3s ease-in; |
|
} |
|
|
|
@keyframes fadeIn { |
|
from { opacity: 0; transform: translateY(10px); } |
|
to { opacity: 1; transform: translateY(0); } |
|
} |
|
|
|
.telegram-input { |
|
border: 1px solid var(--tg-theme-secondary-bg-color, #ebedf0); |
|
background-color: var(--tg-theme-bg-color, #ffffff); |
|
color: var(--tg-theme-text-color, #000000); |
|
} |
|
|
|
.telegram-hint { |
|
color: var(--tg-theme-hint-color, #707579); |
|
} |
|
</style> |
|
</head> |
|
<body class="min-h-screen"> |
|
<div class="header px-4 py-3 flex items-center"> |
|
<button id="back-button" class="mr-3"> |
|
<i class="fas fa-chevron-left text-white"></i> |
|
</button> |
|
<h1 class="text-lg font-semibold">WorkTime Bot</h1> |
|
</div> |
|
|
|
<div class="container mx-auto px-4 py-3"> |
|
|
|
<div id="main-screen"> |
|
<div class="card rounded-xl p-4 mb-3"> |
|
<div class="flex justify-between items-center mb-3"> |
|
<div> |
|
<h2 class="font-medium">Текущий статус</h2> |
|
<p class="text-sm telegram-hint" id="current-date">Сегодня, 12 июня</p> |
|
</div> |
|
<div class="px-3 py-1 rounded-full bg-blue-100 text-blue-800 text-sm" id="current-status"> |
|
Не начат |
|
</div> |
|
</div> |
|
|
|
<div class="grid grid-cols-2 gap-2 mb-3"> |
|
<button id="start-btn" class="button-primary pulse rounded-lg py-3 px-4 font-medium flex items-center justify-center"> |
|
<i class="fas fa-play mr-2"></i> Старт |
|
</button> |
|
<button id="end-btn" class="button-secondary rounded-lg py-3 px-4 font-medium flex items-center justify-center" disabled> |
|
<i class="fas fa-stop mr-2"></i> Стоп |
|
</button> |
|
</div> |
|
|
|
<div class="mb-3"> |
|
<div class="flex justify-between mb-1"> |
|
<span class="text-sm telegram-hint">Прогресс дня</span> |
|
<span class="text-sm font-medium" id="work-progress">0%</span> |
|
</div> |
|
<div class="progress-bar"> |
|
<div class="progress-fill" id="progress-fill" style="width: 0%"></div> |
|
</div> |
|
</div> |
|
|
|
<div class="grid grid-cols-3 gap-2 text-center"> |
|
<div class="rounded-lg p-2 bg-blue-50"> |
|
<p class="text-xs telegram-hint">Сегодня</p> |
|
<p class="font-bold" id="today-hours">0 ч</p> |
|
</div> |
|
<div class="rounded-lg p-2 bg-blue-50"> |
|
<p class="text-xs telegram-hint">Дней</p> |
|
<p class="font-bold" id="worked-days">0</p> |
|
</div> |
|
<div class="rounded-lg p-2 bg-blue-50"> |
|
<p class="text-xs telegram-hint">Всего</p> |
|
<p class="font-bold" id="total-hours">0 ч</p> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="card rounded-xl p-4 mb-3"> |
|
<div class="flex justify-between items-center mb-3"> |
|
<h2 class="font-medium">Статистика</h2> |
|
<div class="flex items-center"> |
|
<button id="prev-month" class="p-1 rounded-full hover:bg-gray-100"> |
|
<i class="fas fa-chevron-left telegram-hint"></i> |
|
</button> |
|
<span class="mx-2 text-sm font-medium" id="current-month">Июнь 2023</span> |
|
<button id="next-month" class="p-1 rounded-full hover:bg-gray-100"> |
|
<i class="fas fa-chevron-right telegram-hint"></i> |
|
</button> |
|
</div> |
|
</div> |
|
|
|
<div class="overflow-hidden rounded-lg"> |
|
<table class="min-w-full"> |
|
<thead class="bg-gray-100"> |
|
<tr> |
|
<th class="px-3 py-2 text-left text-xs font-medium telegram-hint">Дата</th> |
|
<th class="px-3 py-2 text-left text-xs font-medium telegram-hint">Часы</th> |
|
</tr> |
|
</thead> |
|
<tbody class="divide-y divide-gray-200" id="month-table-body"> |
|
|
|
</tbody> |
|
</table> |
|
</div> |
|
|
|
<div class="mt-3 pt-2 border-t border-gray-200 text-right"> |
|
<p class="text-xs telegram-hint">Итого за месяц:</p> |
|
<p class="text-sm font-medium" id="month-total">0 дней, 0 часов</p> |
|
</div> |
|
</div> |
|
|
|
<div class="card rounded-xl p-4"> |
|
<h2 class="font-medium mb-3">История</h2> |
|
<div class="space-y-2" id="history-list"> |
|
|
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="settings-screen" class="hidden"> |
|
<div class="card rounded-xl p-4 mb-3"> |
|
<h2 class="font-medium mb-3">Настройки</h2> |
|
|
|
<div class="mb-3"> |
|
<label class="block text-sm font-medium mb-1">Рабочих часов в день</label> |
|
<input type="number" id="work-hours-per-day" class="telegram-input w-full rounded-lg px-3 py-2" value="8" min="1" max="24"> |
|
</div> |
|
|
|
<div class="mb-3"> |
|
<label class="block text-sm font-medium mb-1">Уведомления</label> |
|
<div class="flex items-center justify-between"> |
|
<span class="text-sm">Напоминать о перерывах</span> |
|
<label class="relative inline-flex items-center cursor-pointer"> |
|
<input type="checkbox" id="break-reminders" class="sr-only peer"> |
|
<div class="w-9 h-5 bg-gray-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-blue-600"></div> |
|
</label> |
|
</div> |
|
</div> |
|
|
|
<button id="save-settings" class="button-primary w-full rounded-lg py-3 px-4 font-medium"> |
|
Сохранить |
|
</button> |
|
</div> |
|
|
|
<div class="card rounded-xl p-4"> |
|
<h2 class="font-medium mb-3">О боте</h2> |
|
<p class="text-sm mb-2">WorkTime Bot v1.0</p> |
|
<p class="text-sm telegram-hint">Отслеживайте свое рабочее время прямо в Telegram</p> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 flex justify-around py-2"> |
|
<button id="main-tab" class="flex flex-col items-center px-4 py-1 text-blue-600"> |
|
<i class="fas fa-home"></i> |
|
<span class="text-xs mt-1">Главная</span> |
|
</button> |
|
<button id="stats-tab" class="flex flex-col items-center px-4 py-1 text-gray-500"> |
|
<i class="fas fa-chart-bar"></i> |
|
<span class="text-xs mt-1">Статистика</span> |
|
</button> |
|
<button id="settings-tab" class="flex flex-col items-center px-4 py-1 text-gray-500"> |
|
<i class="fas fa-cog"></i> |
|
<span class="text-xs mt-1">Настройки</span> |
|
</button> |
|
</div> |
|
|
|
<script> |
|
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
|
|
if (!localStorage.getItem('workTimeBot')) { |
|
localStorage.setItem('workTimeBot', JSON.stringify({ |
|
currentSession: null, |
|
workDays: {}, |
|
monthlyStats: {}, |
|
settings: { |
|
workHoursPerDay: 8, |
|
breakReminders: true |
|
} |
|
})); |
|
} |
|
|
|
const appData = JSON.parse(localStorage.getItem('workTimeBot')); |
|
|
|
|
|
const startBtn = document.getElementById('start-btn'); |
|
const endBtn = document.getElementById('end-btn'); |
|
const currentStatus = document.getElementById('current-status'); |
|
const todayHours = document.getElementById('today-hours'); |
|
const workedDays = document.getElementById('worked-days'); |
|
const totalHours = document.getElementById('total-hours'); |
|
const progressFill = document.getElementById('progress-fill'); |
|
const workProgress = document.getElementById('work-progress'); |
|
const currentDate = document.getElementById('current-date'); |
|
const currentMonth = document.getElementById('current-month'); |
|
const monthTableBody = document.getElementById('month-table-body'); |
|
const monthTotal = document.getElementById('month-total'); |
|
const historyList = document.getElementById('history-list'); |
|
const prevMonthBtn = document.getElementById('prev-month'); |
|
const nextMonthBtn = document.getElementById('next-month'); |
|
const mainScreen = document.getElementById('main-screen'); |
|
const settingsScreen = document.getElementById('settings-screen'); |
|
const mainTab = document.getElementById('main-tab'); |
|
const settingsTab = document.getElementById('settings-tab'); |
|
const workHoursInput = document.getElementById('work-hours-per-day'); |
|
const breakRemindersToggle = document.getElementById('break-reminders'); |
|
const saveSettingsBtn = document.getElementById('save-settings'); |
|
const backButton = document.getElementById('back-button'); |
|
|
|
|
|
const now = new Date(); |
|
const today = formatDate(now); |
|
currentDate.textContent = `Сегодня, ${formatDate(now, true)}`; |
|
|
|
|
|
let currentMonthView = new Date(now.getFullYear(), now.getMonth(), 1); |
|
updateMonthView(); |
|
|
|
|
|
workHoursInput.value = appData.settings.workHoursPerDay; |
|
breakRemindersToggle.checked = appData.settings.breakReminders; |
|
|
|
|
|
if (appData.currentSession) { |
|
const sessionStart = new Date(appData.currentSession.startTime); |
|
if (formatDate(sessionStart) === today) { |
|
|
|
startBtn.disabled = true; |
|
endBtn.disabled = false; |
|
currentStatus.textContent = 'Работаю'; |
|
startBtn.classList.remove('pulse'); |
|
|
|
|
|
updateTimer(); |
|
const timerInterval = setInterval(updateTimer, 1000); |
|
|
|
endBtn.addEventListener('click', function() { |
|
clearInterval(timerInterval); |
|
endWorkSession(); |
|
}); |
|
} else { |
|
|
|
endWorkSession(appData.currentSession.startTime, new Date(appData.currentSession.startTime).setHours(23, 59, 59, 999)); |
|
} |
|
} |
|
|
|
|
|
startBtn.addEventListener('click', startWorkSession); |
|
|
|
|
|
prevMonthBtn.addEventListener('click', function() { |
|
currentMonthView.setMonth(currentMonthView.getMonth() - 1); |
|
updateMonthView(); |
|
}); |
|
|
|
nextMonthBtn.addEventListener('click', function() { |
|
currentMonthView.setMonth(currentMonthView.getMonth() + 1); |
|
updateMonthView(); |
|
}); |
|
|
|
|
|
settingsTab.addEventListener('click', function() { |
|
mainScreen.classList.add('hidden'); |
|
settingsScreen.classList.remove('hidden'); |
|
updateTabStyles('settings'); |
|
}); |
|
|
|
mainTab.addEventListener('click', function() { |
|
mainScreen.classList.remove('hidden'); |
|
settingsScreen.classList.add('hidden'); |
|
updateTabStyles('main'); |
|
}); |
|
|
|
backButton.addEventListener('click', function() { |
|
|
|
alert('В реальном Telegram боте это закрыло бы веб-приложение'); |
|
}); |
|
|
|
|
|
saveSettingsBtn.addEventListener('click', function() { |
|
appData.settings.workHoursPerDay = parseInt(workHoursInput.value) || 8; |
|
appData.settings.breakReminders = breakRemindersToggle.checked; |
|
localStorage.setItem('workTimeBot', JSON.stringify(appData)); |
|
|
|
|
|
mainScreen.classList.remove('hidden'); |
|
settingsScreen.classList.add('hidden'); |
|
updateTabStyles('main'); |
|
|
|
|
|
showTelegramNotification('Настройки сохранены'); |
|
}); |
|
|
|
|
|
updateStats(); |
|
|
|
|
|
function formatDate(date, short = false) { |
|
if (short) { |
|
return date.toLocaleDateString('ru-RU', { day: 'numeric', month: 'long' }); |
|
} |
|
return date.toLocaleDateString('ru-RU'); |
|
} |
|
|
|
function formatTime(date) { |
|
return date.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }); |
|
} |
|
|
|
function startWorkSession() { |
|
const startTime = new Date(); |
|
|
|
appData.currentSession = { |
|
startTime: startTime.toISOString() |
|
}; |
|
|
|
localStorage.setItem('workTimeBot', JSON.stringify(appData)); |
|
|
|
startBtn.disabled = true; |
|
endBtn.disabled = false; |
|
currentStatus.textContent = 'Работаю'; |
|
startBtn.classList.remove('pulse'); |
|
|
|
|
|
addHistoryEvent('Начало работы', startTime); |
|
|
|
|
|
updateTimer(); |
|
const timerInterval = setInterval(updateTimer, 1000); |
|
|
|
endBtn.addEventListener('click', function() { |
|
clearInterval(timerInterval); |
|
endWorkSession(); |
|
}); |
|
|
|
|
|
showTelegramNotification('Рабочий день начат'); |
|
} |
|
|
|
function endWorkSession(customStartTime, customEndTime) { |
|
const endTime = customEndTime ? new Date(customEndTime) : new Date(); |
|
const startTime = customStartTime ? new Date(customStartTime) : new Date(appData.currentSession.startTime); |
|
|
|
const workDate = formatDate(startTime); |
|
const durationMs = endTime - startTime; |
|
const durationHours = (durationMs / (1000 * 60 * 60)).toFixed(2); |
|
|
|
|
|
if (!appData.workDays[workDate]) { |
|
appData.workDays[workDate] = { |
|
startTime: startTime.toISOString(), |
|
endTime: endTime.toISOString(), |
|
duration: durationHours |
|
}; |
|
|
|
|
|
const monthKey = `${startTime.getFullYear()}-${String(startTime.getMonth() + 1).padStart(2, '0')}`; |
|
if (!appData.monthlyStats[monthKey]) { |
|
appData.monthlyStats[monthKey] = { |
|
days: 0, |
|
hours: 0 |
|
}; |
|
} |
|
|
|
appData.monthlyStats[monthKey].days += 1; |
|
appData.monthlyStats[monthKey].hours += parseFloat(durationHours); |
|
} |
|
|
|
|
|
appData.currentSession = null; |
|
localStorage.setItem('workTimeBot', JSON.stringify(appData)); |
|
|
|
startBtn.disabled = false; |
|
endBtn.disabled = true; |
|
currentStatus.textContent = 'Не начат'; |
|
startBtn.classList.add('pulse'); |
|
|
|
|
|
progressFill.style.width = '0%'; |
|
workProgress.textContent = '0%'; |
|
todayHours.textContent = '0 ч'; |
|
|
|
|
|
addHistoryEvent('Конец работы', endTime, durationHours); |
|
|
|
|
|
updateStats(); |
|
updateMonthView(); |
|
|
|
|
|
showTelegramNotification(`Рабочий день завершен: ${durationHours} ч`); |
|
} |
|
|
|
function updateTimer() { |
|
const startTime = new Date(appData.currentSession.startTime); |
|
const now = new Date(); |
|
const durationMs = now - startTime; |
|
const durationHours = (durationMs / (1000 * 60 * 60)).toFixed(2); |
|
|
|
|
|
todayHours.textContent = `${durationHours} ч`; |
|
|
|
|
|
const workHoursPerDay = appData.settings.workHoursPerDay || 8; |
|
const progress = Math.min((durationMs / (workHoursPerDay * 60 * 60 * 1000)) * 100, 100); |
|
progressFill.style.width = `${progress}%`; |
|
workProgress.textContent = `${Math.round(progress)}%`; |
|
} |
|
|
|
function updateStats() { |
|
|
|
let totalDays = 0; |
|
let totalHours = 0; |
|
|
|
for (const month in appData.monthlyStats) { |
|
totalDays += appData.monthlyStats[month].days; |
|
totalHours += appData.monthlyStats[month].hours; |
|
} |
|
|
|
workedDays.textContent = totalDays; |
|
totalHours.textContent = `${totalHours.toFixed(1)} ч`; |
|
} |
|
|
|
function updateMonthView() { |
|
const monthName = currentMonthView.toLocaleDateString('ru-RU', { month: 'long', year: 'numeric' }); |
|
currentMonth.textContent = monthName.charAt(0).toUpperCase() + monthName.slice(1); |
|
|
|
const monthKey = `${currentMonthView.getFullYear()}-${String(currentMonthView.getMonth() + 1).padStart(2, '0')}`; |
|
const monthStats = appData.monthlyStats[monthKey] || { days: 0, hours: 0 }; |
|
|
|
|
|
monthTableBody.innerHTML = ''; |
|
|
|
|
|
const monthWorkDays = []; |
|
for (const date in appData.workDays) { |
|
const workDay = appData.workDays[date]; |
|
const workDate = new Date(workDay.startTime); |
|
|
|
if (workDate.getFullYear() === currentMonthView.getFullYear() && |
|
workDate.getMonth() === currentMonthView.getMonth()) { |
|
monthWorkDays.push({ |
|
date: workDate, |
|
startTime: new Date(workDay.startTime), |
|
endTime: new Date(workDay.endTime), |
|
duration: workDay.duration |
|
}); |
|
} |
|
} |
|
|
|
|
|
monthWorkDays.sort((a, b) => b.date - a.date); |
|
|
|
|
|
monthWorkDays.forEach(day => { |
|
const row = document.createElement('tr'); |
|
row.className = 'fade-in'; |
|
|
|
row.innerHTML = ` |
|
<td class="px-3 py-2 text-sm">${formatDate(day.date)}</td> |
|
<td class="px-3 py-2 text-sm font-medium">${day.duration} ч</td> |
|
`; |
|
|
|
monthTableBody.appendChild(row); |
|
}); |
|
|
|
|
|
if (monthWorkDays.length === 0) { |
|
const row = document.createElement('tr'); |
|
row.innerHTML = ` |
|
<td colspan="2" class="px-3 py-4 text-center text-sm telegram-hint">Нет данных за этот месяц</td> |
|
`; |
|
monthTableBody.appendChild(row); |
|
} |
|
|
|
|
|
monthTotal.textContent = `${monthStats.days} дней, ${monthStats.hours.toFixed(1)} часов`; |
|
} |
|
|
|
function addHistoryEvent(event, time, duration = null) { |
|
const eventElement = document.createElement('div'); |
|
eventElement.className = 'fade-in p-3 rounded-lg bg-gray-100'; |
|
|
|
let eventText = ` |
|
<div class="flex justify-between items-center"> |
|
<div> |
|
<p class="font-medium">${event}</p> |
|
<p class="text-xs telegram-hint">${formatTime(time)}</p> |
|
</div> |
|
`; |
|
|
|
if (duration) { |
|
eventText += ` |
|
<span class="bg-blue-100 text-blue-800 text-xs font-medium px-2 py-0.5 rounded-full"> |
|
${duration} ч |
|
</span> |
|
`; |
|
} |
|
|
|
eventText += `</div>`; |
|
eventElement.innerHTML = eventText; |
|
|
|
|
|
if (historyList.firstChild) { |
|
historyList.insertBefore(eventElement, historyList.firstChild); |
|
} else { |
|
historyList.appendChild(eventElement); |
|
} |
|
|
|
|
|
if (historyList.children.length > 10) { |
|
historyList.removeChild(historyList.lastChild); |
|
} |
|
} |
|
|
|
function updateTabStyles(activeTab) { |
|
const tabs = ['main', 'stats', 'settings']; |
|
tabs.forEach(tab => { |
|
const tabElement = document.getElementById(`${tab}-tab`); |
|
if (tab === activeTab) { |
|
tabElement.classList.remove('text-gray-500'); |
|
tabElement.classList.add('text-blue-600'); |
|
} else { |
|
tabElement.classList.remove('text-blue-600'); |
|
tabElement.classList.add('text-gray-500'); |
|
} |
|
}); |
|
} |
|
|
|
function showTelegramNotification(message) { |
|
|
|
console.log('Telegram notification:', message); |
|
|
|
|
|
const notification = document.createElement('div'); |
|
notification.className = 'fixed top-4 left-1/2 transform -translate-x-1/2 bg-gray-800 text-white px-4 py-2 rounded-lg shadow-lg text-sm fade-in'; |
|
notification.textContent = message; |
|
document.body.appendChild(notification); |
|
|
|
setTimeout(() => { |
|
notification.classList.add('opacity-0', 'transition-opacity', 'duration-300'); |
|
setTimeout(() => notification.remove(), 300); |
|
}, 3000); |
|
} |
|
|
|
|
|
function loadHistory() { |
|
historyList.innerHTML = ''; |
|
|
|
|
|
const events = []; |
|
|
|
for (const date in appData.workDays) { |
|
const workDay = appData.workDays[date]; |
|
events.push({ |
|
type: 'start', |
|
time: new Date(workDay.startTime), |
|
duration: null |
|
}); |
|
|
|
events.push({ |
|
type: 'end', |
|
time: new Date(workDay.endTime), |
|
duration: workDay.duration |
|
}); |
|
} |
|
|
|
|
|
events.sort((a, b) => b.time - a.time); |
|
|
|
|
|
events.slice(0, 10).forEach(event => { |
|
addHistoryEvent( |
|
event.type === 'start' ? 'Начало работы' : 'Конец работы', |
|
event.time, |
|
event.duration |
|
); |
|
}); |
|
} |
|
|
|
loadHistory(); |
|
updateTabStyles('main'); |
|
}); |
|
</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=AliDu14/work-time" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
</html> |