mirror of
https://github.com/elder-plinius/LEAKHUB.git
synced 2026-02-12 16:52:53 +00:00
2175 lines
88 KiB
Plaintext
2175 lines
88 KiB
Plaintext
{\rtf1\ansi\ansicpg1252\cocoartf2822
|
|
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
|
{\colortbl;\red255\green255\blue255;}
|
|
{\*\expandedcolortbl;;}
|
|
\margl1440\margr1440\vieww11520\viewh8400\viewkind0
|
|
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
|
|
|
|
\f0\fs24 \cf0 <!DOCTYPE html>\
|
|
<html lang="en">\
|
|
<head>\
|
|
<meta charset="UTF-8">\
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">\
|
|
<title>LeakHub - AI System Prompt Discovery Platform</title>\
|
|
<style>\
|
|
* \{\
|
|
margin: 0;\
|
|
padding: 0;\
|
|
box-sizing: border-box;\
|
|
\}\
|
|
\
|
|
body \{\
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\
|
|
background: #0f0f0f;\
|
|
color: #e0e0e0;\
|
|
min-height: 100vh;\
|
|
overflow-x: hidden;\
|
|
\}\
|
|
\
|
|
.container \{\
|
|
max-width: 1400px;\
|
|
margin: 0 auto;\
|
|
padding: 2rem;\
|
|
\}\
|
|
\
|
|
header \{\
|
|
text-align: center;\
|
|
margin-bottom: 3rem;\
|
|
\}\
|
|
\
|
|
h1 \{\
|
|
font-size: 3rem;\
|
|
background: linear-gradient(135deg, #00ff88, #00aaff, #ff00ff);\
|
|
-webkit-background-clip: text;\
|
|
-webkit-text-fill-color: transparent;\
|
|
margin-bottom: 1rem;\
|
|
animation: gradientShift 5s ease infinite;\
|
|
\}\
|
|
\
|
|
@keyframes gradientShift \{\
|
|
0%, 100% \{ filter: hue-rotate(0deg); \}\
|
|
50% \{ filter: hue-rotate(180deg); \}\
|
|
\}\
|
|
\
|
|
.subtitle \{\
|
|
color: #888;\
|
|
font-size: 1.2rem;\
|
|
margin-bottom: 0.5rem;\
|
|
\}\
|
|
\
|
|
.status-bar \{\
|
|
display: flex;\
|
|
justify-content: center;\
|
|
gap: 2rem;\
|
|
margin-bottom: 2rem;\
|
|
flex-wrap: wrap;\
|
|
\}\
|
|
\
|
|
.status-item \{\
|
|
background: rgba(255, 255, 255, 0.05);\
|
|
padding: 0.5rem 1.5rem;\
|
|
border-radius: 20px;\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
display: flex;\
|
|
align-items: center;\
|
|
gap: 0.5rem;\
|
|
\}\
|
|
\
|
|
.status-value \{\
|
|
font-weight: bold;\
|
|
color: #00ff88;\
|
|
\}\
|
|
\
|
|
.main-section \{\
|
|
display: grid;\
|
|
grid-template-columns: 1fr 1fr;\
|
|
gap: 2rem;\
|
|
margin-bottom: 3rem;\
|
|
\}\
|
|
\
|
|
@media (max-width: 968px) \{\
|
|
.main-section \{\
|
|
grid-template-columns: 1fr;\
|
|
\}\
|
|
\}\
|
|
\
|
|
.panel \{\
|
|
background: rgba(255, 255, 255, 0.03);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 16px;\
|
|
padding: 2rem;\
|
|
backdrop-filter: blur(10px);\
|
|
\}\
|
|
\
|
|
.panel h2 \{\
|
|
color: #00aaff;\
|
|
margin-bottom: 1.5rem;\
|
|
display: flex;\
|
|
align-items: center;\
|
|
gap: 0.5rem;\
|
|
\}\
|
|
\
|
|
.submission-form \{\
|
|
display: flex;\
|
|
flex-direction: column;\
|
|
gap: 1rem;\
|
|
\}\
|
|
\
|
|
input[type="text"], textarea \{\
|
|
background: rgba(0, 0, 0, 0.5);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 8px;\
|
|
color: #e0e0e0;\
|
|
padding: 1rem;\
|
|
font-family: inherit;\
|
|
transition: all 0.3s ease;\
|
|
\}\
|
|
\
|
|
textarea \{\
|
|
min-height: 200px;\
|
|
font-family: 'Courier New', monospace;\
|
|
font-size: 0.9rem;\
|
|
resize: vertical;\
|
|
\}\
|
|
\
|
|
input:focus, textarea:focus \{\
|
|
outline: none;\
|
|
border-color: #00ff88;\
|
|
box-shadow: 0 0 20px rgba(0, 255, 136, 0.2);\
|
|
\}\
|
|
\
|
|
button \{\
|
|
background: linear-gradient(135deg, #00ff88, #00aaff);\
|
|
border: none;\
|
|
color: #000;\
|
|
padding: 1rem 2rem;\
|
|
border-radius: 8px;\
|
|
font-weight: bold;\
|
|
cursor: pointer;\
|
|
transition: all 0.3s ease;\
|
|
font-size: 1rem;\
|
|
\}\
|
|
\
|
|
button:hover \{\
|
|
transform: translateY(-2px);\
|
|
box-shadow: 0 5px 20px rgba(0, 255, 136, 0.4);\
|
|
\}\
|
|
\
|
|
button:active \{\
|
|
transform: translateY(0);\
|
|
\}\
|
|
\
|
|
button.secondary \{\
|
|
background: rgba(255, 255, 255, 0.1);\
|
|
color: #e0e0e0;\
|
|
border: 1px solid rgba(255, 255, 255, 0.2);\
|
|
\}\
|
|
\
|
|
button.secondary:hover \{\
|
|
background: rgba(255, 255, 255, 0.15);\
|
|
\}\
|
|
\
|
|
.submissions-list \{\
|
|
max-height: 600px;\
|
|
overflow-y: auto;\
|
|
padding-right: 0.5rem;\
|
|
\}\
|
|
\
|
|
.submission-item \{\
|
|
background: rgba(0, 0, 0, 0.3);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 8px;\
|
|
padding: 1rem;\
|
|
margin-bottom: 1rem;\
|
|
cursor: pointer;\
|
|
transition: all 0.3s ease;\
|
|
position: relative;\
|
|
\}\
|
|
\
|
|
.submission-item:hover \{\
|
|
border-color: #00ff88;\
|
|
background: rgba(0, 255, 136, 0.05);\
|
|
\}\
|
|
\
|
|
.submission-item.selected \{\
|
|
border-color: #00ff88;\
|
|
background: rgba(0, 255, 136, 0.1);\
|
|
\}\
|
|
\
|
|
.submission-header \{\
|
|
display: flex;\
|
|
justify-content: space-between;\
|
|
align-items: center;\
|
|
margin-bottom: 0.5rem;\
|
|
\}\
|
|
\
|
|
.submission-source \{\
|
|
font-weight: bold;\
|
|
color: #00aaff;\
|
|
\}\
|
|
\
|
|
.submission-date \{\
|
|
color: #666;\
|
|
font-size: 0.8rem;\
|
|
\}\
|
|
\
|
|
.submission-preview \{\
|
|
color: #888;\
|
|
font-size: 0.9rem;\
|
|
font-family: 'Courier New', monospace;\
|
|
white-space: nowrap;\
|
|
overflow: hidden;\
|
|
text-overflow: ellipsis;\
|
|
\}\
|
|
\
|
|
.submission-confidence \{\
|
|
position: absolute;\
|
|
top: 0.5rem;\
|
|
right: 0.5rem;\
|
|
background: rgba(0, 255, 136, 0.2);\
|
|
color: #00ff88;\
|
|
padding: 0.2rem 0.6rem;\
|
|
border-radius: 12px;\
|
|
font-size: 0.8rem;\
|
|
font-weight: bold;\
|
|
\}\
|
|
\
|
|
.comparison-section \{\
|
|
background: rgba(255, 255, 255, 0.03);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 16px;\
|
|
padding: 2rem;\
|
|
margin-bottom: 2rem;\
|
|
\}\
|
|
\
|
|
.comparison-controls \{\
|
|
display: flex;\
|
|
gap: 1rem;\
|
|
margin-bottom: 2rem;\
|
|
flex-wrap: wrap;\
|
|
\}\
|
|
\
|
|
.instance-selector \{\
|
|
flex: 1;\
|
|
min-width: 200px;\
|
|
\}\
|
|
\
|
|
.comparison-grid \{\
|
|
display: grid;\
|
|
grid-template-columns: 1fr 1fr;\
|
|
gap: 2rem;\
|
|
margin-bottom: 2rem;\
|
|
\}\
|
|
\
|
|
@media (max-width: 768px) \{\
|
|
.comparison-grid \{\
|
|
grid-template-columns: 1fr;\
|
|
\}\
|
|
\}\
|
|
\
|
|
.instance-viewer \{\
|
|
background: rgba(0, 0, 0, 0.5);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 8px;\
|
|
padding: 1rem;\
|
|
height: 300px;\
|
|
overflow-y: auto;\
|
|
\}\
|
|
\
|
|
.instance-viewer h3 \{\
|
|
color: #00ff88;\
|
|
margin-bottom: 1rem;\
|
|
font-size: 1rem;\
|
|
\}\
|
|
\
|
|
.instance-content \{\
|
|
font-family: 'Courier New', monospace;\
|
|
font-size: 0.9rem;\
|
|
line-height: 1.6;\
|
|
white-space: pre-wrap;\
|
|
\}\
|
|
\
|
|
.results-panel \{\
|
|
background: rgba(0, 0, 0, 0.8);\
|
|
border: 2px solid rgba(0, 255, 136, 0.3);\
|
|
border-radius: 12px;\
|
|
padding: 2rem;\
|
|
margin-top: 2rem;\
|
|
\}\
|
|
\
|
|
.match-metrics \{\
|
|
display: grid;\
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\
|
|
gap: 1rem;\
|
|
margin-bottom: 2rem;\
|
|
\}\
|
|
\
|
|
.metric-card \{\
|
|
background: rgba(255, 255, 255, 0.05);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 8px;\
|
|
padding: 1rem;\
|
|
text-align: center;\
|
|
\}\
|
|
\
|
|
.metric-label \{\
|
|
color: #666;\
|
|
font-size: 0.9rem;\
|
|
margin-bottom: 0.5rem;\
|
|
\}\
|
|
\
|
|
.metric-value \{\
|
|
font-size: 2rem;\
|
|
font-weight: bold;\
|
|
color: #00ff88;\
|
|
\}\
|
|
\
|
|
.consensus-viewer \{\
|
|
background: rgba(0, 255, 136, 0.05);\
|
|
border: 1px solid rgba(0, 255, 136, 0.2);\
|
|
border-radius: 8px;\
|
|
padding: 1.5rem;\
|
|
margin-top: 2rem;\
|
|
\}\
|
|
\
|
|
.consensus-viewer h3 \{\
|
|
color: #00ff88;\
|
|
margin-bottom: 1rem;\
|
|
\}\
|
|
\
|
|
.consensus-text \{\
|
|
font-family: 'Courier New', monospace;\
|
|
font-size: 0.9rem;\
|
|
line-height: 1.8;\
|
|
white-space: pre-wrap;\
|
|
\}\
|
|
\
|
|
.highlight-match \{\
|
|
background: rgba(0, 255, 136, 0.3);\
|
|
color: #00ff88;\
|
|
padding: 2px 4px;\
|
|
border-radius: 3px;\
|
|
\}\
|
|
\
|
|
.highlight-diff \{\
|
|
background: rgba(255, 255, 0, 0.2);\
|
|
color: #ffff00;\
|
|
padding: 2px 4px;\
|
|
border-radius: 3px;\
|
|
\}\
|
|
\
|
|
.alert \{\
|
|
position: fixed;\
|
|
top: 2rem;\
|
|
right: 2rem;\
|
|
padding: 1rem 2rem;\
|
|
background: rgba(0, 255, 136, 0.2);\
|
|
border: 1px solid #00ff88;\
|
|
border-radius: 8px;\
|
|
color: #00ff88;\
|
|
font-weight: bold;\
|
|
display: none;\
|
|
animation: slideIn 0.3s ease;\
|
|
z-index: 1000;\
|
|
\}\
|
|
\
|
|
@keyframes slideIn \{\
|
|
from \{ transform: translateX(400px); \}\
|
|
to \{ transform: translateX(0); \}\
|
|
\}\
|
|
\
|
|
.floating-grid \{\
|
|
position: fixed;\
|
|
top: 0;\
|
|
left: 0;\
|
|
width: 100%;\
|
|
height: 100%;\
|
|
background-image: \
|
|
linear-gradient(rgba(0, 255, 136, 0.03) 1px, transparent 1px),\
|
|
linear-gradient(90deg, rgba(0, 255, 136, 0.03) 1px, transparent 1px);\
|
|
background-size: 50px 50px;\
|
|
pointer-events: none;\
|
|
z-index: -1;\
|
|
animation: gridMove 20s linear infinite;\
|
|
\}\
|
|
\
|
|
@keyframes gridMove \{\
|
|
from \{ transform: translate(0, 0); \}\
|
|
to \{ transform: translate(50px, 50px); \}\
|
|
\}\
|
|
\
|
|
.library-stats \{\
|
|
display: grid;\
|
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\
|
|
gap: 1rem;\
|
|
margin-top: 2rem;\
|
|
\}\
|
|
\
|
|
.stat-card \{\
|
|
background: linear-gradient(135deg, rgba(0, 255, 136, 0.1), rgba(0, 170, 255, 0.1));\
|
|
border: 1px solid rgba(0, 255, 136, 0.3);\
|
|
border-radius: 12px;\
|
|
padding: 1.5rem;\
|
|
text-align: center;\
|
|
\}\
|
|
\
|
|
.stat-number \{\
|
|
font-size: 2.5rem;\
|
|
font-weight: bold;\
|
|
color: #00ff88;\
|
|
\}\
|
|
\
|
|
.stat-label \{\
|
|
color: #888;\
|
|
margin-top: 0.5rem;\
|
|
\}\
|
|
\
|
|
::-webkit-scrollbar \{\
|
|
width: 8px;\
|
|
\}\
|
|
\
|
|
::-webkit-scrollbar-track \{\
|
|
background: rgba(255, 255, 255, 0.05);\
|
|
border-radius: 4px;\
|
|
\}\
|
|
\
|
|
::-webkit-scrollbar-thumb \{\
|
|
background: rgba(0, 255, 136, 0.3);\
|
|
border-radius: 4px;\
|
|
\}\
|
|
\
|
|
::-webkit-scrollbar-thumb:hover \{\
|
|
background: rgba(0, 255, 136, 0.5);\
|
|
\}\
|
|
\
|
|
.leaderboard-overlay \{\
|
|
position: fixed;\
|
|
top: 0;\
|
|
left: 0;\
|
|
width: 100%;\
|
|
height: 100%;\
|
|
background: rgba(0, 0, 0, 0.9);\
|
|
backdrop-filter: blur(10px);\
|
|
display: none;\
|
|
z-index: 2000;\
|
|
overflow-y: auto;\
|
|
\}\
|
|
\
|
|
.leaderboard-container \{\
|
|
max-width: 1200px;\
|
|
margin: 2rem auto;\
|
|
padding: 2rem;\
|
|
\}\
|
|
\
|
|
.leaderboard-header \{\
|
|
text-align: center;\
|
|
margin-bottom: 3rem;\
|
|
\}\
|
|
\
|
|
.leaderboard-title \{\
|
|
font-size: 3rem;\
|
|
background: linear-gradient(135deg, #ffd700, #ff6b6b, #00ff88);\
|
|
-webkit-background-clip: text;\
|
|
-webkit-text-fill-color: transparent;\
|
|
margin-bottom: 1rem;\
|
|
animation: shimmer 3s ease-in-out infinite;\
|
|
\}\
|
|
\
|
|
@keyframes shimmer \{\
|
|
0%, 100% \{ filter: brightness(1); \}\
|
|
50% \{ filter: brightness(1.3); \}\
|
|
\}\
|
|
\
|
|
.close-button \{\
|
|
position: absolute;\
|
|
top: 2rem;\
|
|
right: 2rem;\
|
|
background: rgba(255, 255, 255, 0.1);\
|
|
border: 1px solid rgba(255, 255, 255, 0.2);\
|
|
border-radius: 50%;\
|
|
width: 50px;\
|
|
height: 50px;\
|
|
display: flex;\
|
|
align-items: center;\
|
|
justify-content: center;\
|
|
cursor: pointer;\
|
|
font-size: 1.5rem;\
|
|
transition: all 0.3s ease;\
|
|
\}\
|
|
\
|
|
.close-button:hover \{\
|
|
background: rgba(255, 255, 255, 0.2);\
|
|
transform: rotate(90deg);\
|
|
\}\
|
|
\
|
|
.leaderboard-tabs \{\
|
|
display: flex;\
|
|
justify-content: center;\
|
|
gap: 1rem;\
|
|
margin-bottom: 2rem;\
|
|
\}\
|
|
\
|
|
.leaderboard-tab \{\
|
|
padding: 0.8rem 2rem;\
|
|
background: rgba(255, 255, 255, 0.05);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 8px;\
|
|
cursor: pointer;\
|
|
transition: all 0.3s ease;\
|
|
\}\
|
|
\
|
|
.leaderboard-tab:hover \{\
|
|
background: rgba(255, 255, 255, 0.1);\
|
|
\}\
|
|
\
|
|
.leaderboard-tab.active \{\
|
|
background: linear-gradient(135deg, #ff00ff, #00ff88);\
|
|
border-color: transparent;\
|
|
\}\
|
|
\
|
|
.rankings \{\
|
|
background: rgba(255, 255, 255, 0.03);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 16px;\
|
|
padding: 2rem;\
|
|
margin-bottom: 2rem;\
|
|
\}\
|
|
\
|
|
.rank-item \{\
|
|
display: flex;\
|
|
align-items: center;\
|
|
padding: 1rem;\
|
|
margin-bottom: 1rem;\
|
|
background: rgba(0, 0, 0, 0.3);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 12px;\
|
|
transition: all 0.3s ease;\
|
|
\}\
|
|
\
|
|
.rank-item:hover \{\
|
|
transform: translateX(10px);\
|
|
border-color: #00ff88;\
|
|
\}\
|
|
\
|
|
.rank-number \{\
|
|
font-size: 2rem;\
|
|
font-weight: bold;\
|
|
width: 60px;\
|
|
text-align: center;\
|
|
\}\
|
|
\
|
|
.rank-1 \{ color: #ffd700; \}\
|
|
.rank-2 \{ color: #c0c0c0; \}\
|
|
.rank-3 \{ color: #cd7f32; \}\
|
|
\
|
|
.rank-user \{\
|
|
flex: 1;\
|
|
margin-left: 1rem;\
|
|
\}\
|
|
\
|
|
.rank-username \{\
|
|
font-size: 1.2rem;\
|
|
font-weight: bold;\
|
|
color: #00aaff;\
|
|
\}\
|
|
\
|
|
.rank-stats \{\
|
|
display: flex;\
|
|
gap: 2rem;\
|
|
margin-top: 0.5rem;\
|
|
font-size: 0.9rem;\
|
|
color: #888;\
|
|
\}\
|
|
\
|
|
.rank-score \{\
|
|
font-size: 1.5rem;\
|
|
font-weight: bold;\
|
|
color: #00ff88;\
|
|
margin-left: auto;\
|
|
\}\
|
|
\
|
|
.achievements \{\
|
|
display: grid;\
|
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\
|
|
gap: 1rem;\
|
|
margin-top: 2rem;\
|
|
\}\
|
|
\
|
|
.achievement-card \{\
|
|
background: rgba(255, 255, 255, 0.05);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 12px;\
|
|
padding: 1.5rem;\
|
|
text-align: center;\
|
|
transition: all 0.3s ease;\
|
|
\}\
|
|
\
|
|
.achievement-card:hover \{\
|
|
transform: translateY(-5px);\
|
|
border-color: #ffd700;\
|
|
box-shadow: 0 5px 20px rgba(255, 215, 0, 0.3);\
|
|
\}\
|
|
\
|
|
.achievement-icon \{\
|
|
font-size: 3rem;\
|
|
margin-bottom: 1rem;\
|
|
\}\
|
|
\
|
|
.achievement-title \{\
|
|
color: #ffd700;\
|
|
font-weight: bold;\
|
|
margin-bottom: 0.5rem;\
|
|
\}\
|
|
\
|
|
.achievement-user \{\
|
|
color: #00aaff;\
|
|
font-size: 1.1rem;\
|
|
\}\
|
|
\
|
|
.timeline-section \{\
|
|
background: rgba(0, 0, 0, 0.5);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 16px;\
|
|
padding: 2rem;\
|
|
margin-top: 2rem;\
|
|
\}\
|
|
\
|
|
.timeline-item \{\
|
|
position: relative;\
|
|
padding-left: 3rem;\
|
|
padding-bottom: 2rem;\
|
|
border-left: 2px solid rgba(0, 255, 136, 0.3);\
|
|
\}\
|
|
\
|
|
.timeline-item:last-child \{\
|
|
border-left: none;\
|
|
padding-bottom: 0;\
|
|
\}\
|
|
\
|
|
.timeline-dot \{\
|
|
position: absolute;\
|
|
left: -8px;\
|
|
top: 0;\
|
|
width: 16px;\
|
|
height: 16px;\
|
|
background: #00ff88;\
|
|
border-radius: 50%;\
|
|
box-shadow: 0 0 10px rgba(0, 255, 136, 0.5);\
|
|
\}\
|
|
\
|
|
.timeline-content \{\
|
|
background: rgba(255, 255, 255, 0.05);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 8px;\
|
|
padding: 1rem;\
|
|
\}\
|
|
\
|
|
.timeline-date \{\
|
|
color: #666;\
|
|
font-size: 0.8rem;\
|
|
margin-bottom: 0.5rem;\
|
|
\}\
|
|
\
|
|
.timeline-event \{\
|
|
color: #00aaff;\
|
|
font-weight: bold;\
|
|
\}\
|
|
\
|
|
/* Requests & Challenges Styles */\
|
|
.requests-overlay \{\
|
|
position: fixed;\
|
|
top: 0;\
|
|
left: 0;\
|
|
width: 100%;\
|
|
height: 100%;\
|
|
background: rgba(0, 0, 0, 0.9);\
|
|
backdrop-filter: blur(10px);\
|
|
display: none;\
|
|
z-index: 2000;\
|
|
overflow-y: auto;\
|
|
\}\
|
|
\
|
|
.requests-container \{\
|
|
max-width: 1200px;\
|
|
margin: 2rem auto;\
|
|
padding: 2rem;\
|
|
\}\
|
|
\
|
|
.requests-header \{\
|
|
text-align: center;\
|
|
margin-bottom: 3rem;\
|
|
\}\
|
|
\
|
|
.requests-title \{\
|
|
font-size: 3rem;\
|
|
background: linear-gradient(135deg, #ff6b6b, #ffd700, #00ff88);\
|
|
-webkit-background-clip: text;\
|
|
-webkit-text-fill-color: transparent;\
|
|
margin-bottom: 1rem;\
|
|
animation: pulse 2s ease-in-out infinite;\
|
|
\}\
|
|
\
|
|
.daily-challenge \{\
|
|
background: linear-gradient(135deg, rgba(255, 215, 0, 0.1), rgba(255, 107, 107, 0.1));\
|
|
border: 2px solid #ffd700;\
|
|
border-radius: 20px;\
|
|
padding: 2rem;\
|
|
margin-bottom: 3rem;\
|
|
text-align: center;\
|
|
position: relative;\
|
|
overflow: hidden;\
|
|
\}\
|
|
\
|
|
.daily-challenge::before \{\
|
|
content: '';\
|
|
position: absolute;\
|
|
top: -50%;\
|
|
left: -50%;\
|
|
width: 200%;\
|
|
height: 200%;\
|
|
background: radial-gradient(circle, rgba(255, 215, 0, 0.1) 0%, transparent 70%);\
|
|
animation: rotate 20s linear infinite;\
|
|
\}\
|
|
\
|
|
@keyframes rotate \{\
|
|
from \{ transform: rotate(0deg); \}\
|
|
to \{ transform: rotate(360deg); \}\
|
|
\}\
|
|
\
|
|
.challenge-title \{\
|
|
font-size: 2rem;\
|
|
color: #ffd700;\
|
|
margin-bottom: 1rem;\
|
|
position: relative;\
|
|
z-index: 1;\
|
|
\}\
|
|
\
|
|
.challenge-description \{\
|
|
font-size: 1.2rem;\
|
|
color: #e0e0e0;\
|
|
margin-bottom: 1rem;\
|
|
position: relative;\
|
|
z-index: 1;\
|
|
\}\
|
|
\
|
|
.challenge-reward \{\
|
|
background: rgba(255, 215, 0, 0.2);\
|
|
border: 1px solid #ffd700;\
|
|
border-radius: 20px;\
|
|
padding: 0.5rem 1.5rem;\
|
|
display: inline-block;\
|
|
font-weight: bold;\
|
|
color: #ffd700;\
|
|
position: relative;\
|
|
z-index: 1;\
|
|
\}\
|
|
\
|
|
.challenge-timer \{\
|
|
margin-top: 1rem;\
|
|
font-size: 1.5rem;\
|
|
color: #ff6b6b;\
|
|
font-weight: bold;\
|
|
position: relative;\
|
|
z-index: 1;\
|
|
\}\
|
|
\
|
|
.requests-grid \{\
|
|
display: grid;\
|
|
grid-template-columns: 1fr 1fr;\
|
|
gap: 2rem;\
|
|
margin-bottom: 2rem;\
|
|
\}\
|
|
\
|
|
@media (max-width: 968px) \{\
|
|
.requests-grid \{\
|
|
grid-template-columns: 1fr;\
|
|
\}\
|
|
\}\
|
|
\
|
|
.request-form \{\
|
|
background: rgba(255, 255, 255, 0.03);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 16px;\
|
|
padding: 2rem;\
|
|
\}\
|
|
\
|
|
.request-list \{\
|
|
background: rgba(255, 255, 255, 0.03);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 16px;\
|
|
padding: 2rem;\
|
|
\}\
|
|
\
|
|
.request-item \{\
|
|
background: rgba(0, 0, 0, 0.5);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 12px;\
|
|
padding: 1.5rem;\
|
|
margin-bottom: 1rem;\
|
|
transition: all 0.3s ease;\
|
|
\}\
|
|
\
|
|
.request-item:hover \{\
|
|
transform: translateY(-2px);\
|
|
border-color: #ffd700;\
|
|
box-shadow: 0 5px 20px rgba(255, 215, 0, 0.2);\
|
|
\}\
|
|
\
|
|
.request-header \{\
|
|
display: flex;\
|
|
justify-content: space-between;\
|
|
align-items: center;\
|
|
margin-bottom: 1rem;\
|
|
\}\
|
|
\
|
|
.request-model \{\
|
|
font-size: 1.2rem;\
|
|
font-weight: bold;\
|
|
color: #ffd700;\
|
|
\}\
|
|
\
|
|
.request-votes \{\
|
|
display: flex;\
|
|
align-items: center;\
|
|
gap: 1rem;\
|
|
\}\
|
|
\
|
|
.vote-count \{\
|
|
background: rgba(0, 255, 136, 0.2);\
|
|
color: #00ff88;\
|
|
padding: 0.3rem 0.8rem;\
|
|
border-radius: 20px;\
|
|
font-weight: bold;\
|
|
\}\
|
|
\
|
|
.vote-button \{\
|
|
background: rgba(255, 255, 255, 0.1);\
|
|
border: 1px solid rgba(255, 255, 255, 0.2);\
|
|
color: #e0e0e0;\
|
|
padding: 0.3rem 1rem;\
|
|
border-radius: 20px;\
|
|
cursor: pointer;\
|
|
transition: all 0.3s ease;\
|
|
font-size: 0.9rem;\
|
|
\}\
|
|
\
|
|
.vote-button:hover \{\
|
|
background: rgba(0, 255, 136, 0.2);\
|
|
border-color: #00ff88;\
|
|
color: #00ff88;\
|
|
\}\
|
|
\
|
|
.vote-button.voted \{\
|
|
background: rgba(0, 255, 136, 0.3);\
|
|
border-color: #00ff88;\
|
|
color: #00ff88;\
|
|
\}\
|
|
\
|
|
.request-description \{\
|
|
color: #888;\
|
|
margin-bottom: 0.5rem;\
|
|
\}\
|
|
\
|
|
.request-meta \{\
|
|
display: flex;\
|
|
justify-content: space-between;\
|
|
align-items: center;\
|
|
color: #666;\
|
|
font-size: 0.9rem;\
|
|
\}\
|
|
\
|
|
.bounty-badge \{\
|
|
background: linear-gradient(135deg, #ffd700, #ff6b6b);\
|
|
color: #000;\
|
|
padding: 0.2rem 0.8rem;\
|
|
border-radius: 20px;\
|
|
font-weight: bold;\
|
|
font-size: 0.8rem;\
|
|
\}\
|
|
\
|
|
.trending-indicator \{\
|
|
display: flex;\
|
|
align-items: center;\
|
|
gap: 0.3rem;\
|
|
color: #ff6b6b;\
|
|
font-weight: bold;\
|
|
\}\
|
|
\
|
|
.filter-tabs \{\
|
|
display: flex;\
|
|
gap: 1rem;\
|
|
margin-bottom: 1.5rem;\
|
|
flex-wrap: wrap;\
|
|
\}\
|
|
\
|
|
.filter-tab \{\
|
|
padding: 0.5rem 1rem;\
|
|
background: rgba(255, 255, 255, 0.05);\
|
|
border: 1px solid rgba(255, 255, 255, 0.1);\
|
|
border-radius: 20px;\
|
|
cursor: pointer;\
|
|
transition: all 0.3s ease;\
|
|
font-size: 0.9rem;\
|
|
\}\
|
|
\
|
|
.filter-tab:hover \{\
|
|
background: rgba(255, 255, 255, 0.1);\
|
|
\}\
|
|
\
|
|
.filter-tab.active \{\
|
|
background: linear-gradient(135deg, #ff6b6b, #ffd700);\
|
|
border-color: transparent;\
|
|
color: #000;\
|
|
font-weight: bold;\
|
|
\}\
|
|
</style>\
|
|
</head>\
|
|
<body>\
|
|
<div class="floating-grid"></div>\
|
|
\
|
|
<div class="container">\
|
|
<header>\
|
|
<h1>LeakHub</h1>\
|
|
<p class="subtitle">The community hub for crowd-sourced system prompt leak verification. CL4R1T4S!</p>\
|
|
<div class="status-bar">\
|
|
<div class="status-item">\
|
|
<span>Active Targets:</span>\
|
|
<span class="status-value" id="activeLeaks">0</span>\
|
|
</div>\
|
|
<div class="status-item">\
|
|
<span>Total Submissions:</span>\
|
|
<span class="status-value" id="totalSubmissions">0</span>\
|
|
</div>\
|
|
<div class="status-item">\
|
|
<span>Verified Prompts:</span>\
|
|
<span class="status-value" id="verifiedPrompts">0</span>\
|
|
</div>\
|
|
</div>\
|
|
<div style="text-align: center; margin-top: 1rem; display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap;">\
|
|
<button onclick="toggleLeaderboard()" style="background: linear-gradient(135deg, #ff00ff, #00ff88); padding: 0.6rem 2rem;">\
|
|
\uc0\u55356 \u57286 View Leaderboard\
|
|
</button>\
|
|
<button onclick="toggleRequests()" style="background: linear-gradient(135deg, #ff6b6b, #ffd700); padding: 0.6rem 2rem;">\
|
|
\uc0\u55356 \u57263 Requests & Challenges\
|
|
</button>\
|
|
</div>\
|
|
</header>\
|
|
\
|
|
<div class="main-section">\
|
|
<div class="panel">\
|
|
<h2>\uc0\u55357 \u56548 Submit Leak</h2>\
|
|
<form class="submission-form" onsubmit="submitLeak(event)">\
|
|
<input type="text" id="sourceName" placeholder="Your identifier (e.g., User123, Anonymous)" required>\
|
|
\
|
|
<select id="targetType" onchange="updateTargetFields()" required style="width: 100%; padding: 0.5rem; margin-bottom: 1rem; background: rgba(0,0,0,0.5); border: 1px solid rgba(255,255,255,0.1); border-radius: 8px; color: #e0e0e0;">\
|
|
<option value="">Select target type...</option>\
|
|
<option value="model">\uc0\u55358 \u56598 AI Model</option>\
|
|
<option value="app">\uc0\u55357 \u56561 App/Interface</option>\
|
|
<option value="tool">\uc0\u55357 \u56615 Tool/Function</option>\
|
|
<option value="agent">\uc0\u55358 \u56605 AI Agent</option>\
|
|
<option value="plugin">\uc0\u55357 \u56588 Plugin/Extension</option>\
|
|
<option value="custom">\uc0\u9881 \u65039 Custom GPT/Bot</option>\
|
|
</select>\
|
|
\
|
|
<input type="text" id="instanceId" placeholder="Target name (e.g., ChatGPT-4, GitHub Copilot)" required>\
|
|
\
|
|
<input type="url" id="targetUrl" placeholder="Target URL (e.g., https://chat.openai.com)" style="margin-bottom: 1rem;">\
|
|
\
|
|
<div style="background: rgba(0,0,0,0.3); border: 1px solid rgba(255,255,255,0.1); border-radius: 8px; padding: 1rem; margin-bottom: 1rem;">\
|
|
<p style="color: #00aaff; font-size: 0.9rem; margin-bottom: 0.8rem;">\uc0\u55357 \u56592 Access Requirements</p>\
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">\
|
|
<label style="display: flex; align-items: center; gap: 0.5rem; color: #888; font-size: 0.9rem;">\
|
|
<input type="checkbox" id="requiresLogin" style="width: auto;">\
|
|
Requires Login\
|
|
</label>\
|
|
<label style="display: flex; align-items: center; gap: 0.5rem; color: #888; font-size: 0.9rem;">\
|
|
<input type="checkbox" id="requiresPaid" style="width: auto;">\
|
|
Paid/Subscription\
|
|
</label>\
|
|
</div>\
|
|
<input type="text" id="accessNotes" placeholder="Additional access notes (e.g., 'Plus subscription required')" \
|
|
style="width: 100%; margin-top: 0.8rem; padding: 0.5rem; background: rgba(0,0,0,0.5); border: 1px solid rgba(255,255,255,0.1); border-radius: 8px; color: #e0e0e0;">\
|
|
</div>\
|
|
\
|
|
<div id="additionalFields" style="display: none;">\
|
|
<input type="text" id="parentSystem" placeholder="Parent system (e.g., ChatGPT for a plugin)" style="margin-bottom: 1rem;">\
|
|
<input type="text" id="functionName" placeholder="Specific function/tool name (if applicable)" style="margin-bottom: 1rem;">\
|
|
</div>\
|
|
\
|
|
<textarea id="leakContent" placeholder="Paste the suspected system prompt leak here..." required></textarea>\
|
|
<input type="text" id="context" placeholder="Context: How was this obtained? (optional)">\
|
|
\
|
|
<div style="display: flex; gap: 0.5rem; align-items: center; margin-bottom: 1rem;">\
|
|
<input type="checkbox" id="hasTools" onchange="toggleToolsSection()" style="width: auto;">\
|
|
<label for="hasTools" style="color: #888; font-size: 0.9rem;">This target has tools/functions with their own prompts</label>\
|
|
</div>\
|
|
\
|
|
<div id="toolsSection" style="display: none; background: rgba(0,0,0,0.3); border: 1px solid rgba(255,255,255,0.1); border-radius: 8px; padding: 1rem; margin-bottom: 1rem;">\
|
|
<p style="color: #00aaff; font-size: 0.9rem; margin-bottom: 0.5rem;">\uc0\u55357 \u56615 Related Tool Prompts (optional)</p>\
|
|
<textarea id="toolPrompts" placeholder="If you found any tool-specific prompts, paste them here..." style="min-height: 100px;"></textarea>\
|
|
</div>\
|
|
\
|
|
<button type="submit">Submit to Library</button>\
|
|
</form>\
|
|
</div>\
|
|
\
|
|
<div class="panel">\
|
|
<h2>\uc0\u55357 \u56538 Leak Library</h2>\
|
|
<div class="submissions-list" id="submissionsList">\
|
|
<p style="color: #666; text-align: center;">No submissions yet. Be the first to contribute!</p>\
|
|
</div>\
|
|
</div>\
|
|
</div>\
|
|
\
|
|
<div class="comparison-section">\
|
|
<h2 style="color: #00ff88; margin-bottom: 1.5rem;">\uc0\u55357 \u56589 Compare Multiple Instances</h2>\
|
|
\
|
|
<div class="comparison-controls">\
|
|
<div class="instance-selector">\
|
|
<label style="color: #888; font-size: 0.9rem;">Instance A:</label>\
|
|
<select id="instanceA" class="form-control" style="width: 100%; padding: 0.5rem; margin-top: 0.5rem; background: rgba(0,0,0,0.5); border: 1px solid rgba(255,255,255,0.1); border-radius: 8px; color: #e0e0e0;">\
|
|
<option value="">Select submission...</option>\
|
|
</select>\
|
|
</div>\
|
|
<div class="instance-selector">\
|
|
<label style="color: #888; font-size: 0.9rem;">Instance B:</label>\
|
|
<select id="instanceB" class="form-control" style="width: 100%; padding: 0.5rem; margin-top: 0.5rem; background: rgba(0,0,0,0.5); border: 1px solid rgba(255,255,255,0.1); border-radius: 8px; color: #e0e0e0;">\
|
|
<option value="">Select submission...</option>\
|
|
</select>\
|
|
</div>\
|
|
<button onclick="compareInstances()" style="align-self: flex-end;">Compare</button>\
|
|
</div>\
|
|
\
|
|
<div id="comparisonResults" style="display: none;">\
|
|
<div class="comparison-grid">\
|
|
<div class="instance-viewer">\
|
|
<h3>Instance A</h3>\
|
|
<div class="instance-content" id="instanceAContent"></div>\
|
|
</div>\
|
|
<div class="instance-viewer">\
|
|
<h3>Instance B</h3>\
|
|
<div class="instance-content" id="instanceBContent"></div>\
|
|
</div>\
|
|
</div>\
|
|
\
|
|
<div class="results-panel">\
|
|
<h3 style="color: #00ff88; margin-bottom: 1.5rem;">Analysis Results</h3>\
|
|
<div class="match-metrics">\
|
|
<div class="metric-card">\
|
|
<div class="metric-label">Character Match</div>\
|
|
<div class="metric-value" id="charMatch">-</div>\
|
|
</div>\
|
|
<div class="metric-card">\
|
|
<div class="metric-label">Word Match</div>\
|
|
<div class="metric-value" id="wordMatch">-</div>\
|
|
</div>\
|
|
<div class="metric-card">\
|
|
<div class="metric-label">Structure Match</div>\
|
|
<div class="metric-value" id="structureMatch">-</div>\
|
|
</div>\
|
|
<div class="metric-card">\
|
|
<div class="metric-label">Core Similarity</div>\
|
|
<div class="metric-value" id="coreSimilarity">-</div>\
|
|
</div>\
|
|
</div>\
|
|
\
|
|
<div class="consensus-viewer">\
|
|
<h3>Consensus View (Common Elements)</h3>\
|
|
<div class="consensus-text" id="consensusText"></div>\
|
|
</div>\
|
|
</div>\
|
|
</div>\
|
|
</div>\
|
|
\
|
|
<div class="library-stats">\
|
|
<div class="stat-card">\
|
|
<div class="stat-number" id="uniqueInstances">0</div>\
|
|
<div class="stat-label">Unique Instances</div>\
|
|
</div>\
|
|
<div class="stat-card">\
|
|
<div class="stat-number" id="avgSimilarity">0%</div>\
|
|
<div class="stat-label">Average Similarity</div>\
|
|
</div>\
|
|
<div class="stat-card">\
|
|
<div class="stat-number" id="highConfidence">0</div>\
|
|
<div class="stat-label">High Confidence Matches</div>\
|
|
</div>\
|
|
</div>\
|
|
</div>\
|
|
\
|
|
<div class="alert" id="alert"></div>\
|
|
\
|
|
<!-- Leaderboard Overlay -->\
|
|
<div class="leaderboard-overlay" id="leaderboardOverlay">\
|
|
<div class="leaderboard-container">\
|
|
<div class="close-button" onclick="toggleLeaderboard()">\uc0\u10005 </div>\
|
|
\
|
|
<div class="leaderboard-header">\
|
|
<h1 class="leaderboard-title">\uc0\u55356 \u57286 LeakHub Hall of Fame</h1>\
|
|
<p class="subtitle">Recognizing the top contributors to AI transparency</p>\
|
|
</div>\
|
|
\
|
|
<div class="leaderboard-tabs">\
|
|
<div class="leaderboard-tab active" onclick="switchLeaderboardTab('rankings')">\uc0\u55357 \u56522 Rankings</div>\
|
|
<div class="leaderboard-tab" onclick="switchLeaderboardTab('achievements')">\uc0\u55356 \u57238 \u65039 Achievements</div>\
|
|
<div class="leaderboard-tab" onclick="switchLeaderboardTab('timeline')">\uc0\u55357 \u56517 Timeline</div>\
|
|
</div>\
|
|
\
|
|
<div id="rankings-content" class="leaderboard-content">\
|
|
<div class="rankings">\
|
|
<h2 style="color: #00ff88; margin-bottom: 1.5rem;">Top Contributors</h2>\
|
|
<div id="rankingsList"></div>\
|
|
</div>\
|
|
</div>\
|
|
\
|
|
<div id="achievements-content" class="leaderboard-content" style="display: none;">\
|
|
<h2 style="color: #ffd700; margin-bottom: 1.5rem; text-align: center;">Notable Achievements</h2>\
|
|
<div class="achievements" id="achievementsList"></div>\
|
|
</div>\
|
|
\
|
|
<div id="timeline-content" class="leaderboard-content" style="display: none;">\
|
|
<div class="timeline-section">\
|
|
<h2 style="color: #00aaff; margin-bottom: 1.5rem;">Discovery Timeline</h2>\
|
|
<div id="timelineList"></div>\
|
|
</div>\
|
|
</div>\
|
|
</div>\
|
|
</div>\
|
|
\
|
|
<!-- Requests & Challenges Overlay -->\
|
|
<div class="requests-overlay" id="requestsOverlay">\
|
|
<div class="requests-container">\
|
|
<div class="close-button" onclick="toggleRequests()">\uc0\u10005 </div>\
|
|
\
|
|
<div class="requests-header">\
|
|
<h1 class="requests-title">\uc0\u55356 \u57263 LeakHub Bounty Board</h1>\
|
|
<p class="subtitle">Request targets and compete in daily challenges</p>\
|
|
</div>\
|
|
\
|
|
<!-- Daily Challenge -->\
|
|
<div class="daily-challenge">\
|
|
<h2 class="challenge-title">\uc0\u55356 \u57285 Today's Challenge</h2>\
|
|
<p class="challenge-description" id="challengeDescription">Find and verify a system prompt from GPT-4 Turbo!</p>\
|
|
<div class="challenge-reward">\uc0\u55356 \u57217 Reward: 500 bonus points + Special Badge</div>\
|
|
<div class="challenge-timer" id="challengeTimer">Time remaining: 23:45:30</div>\
|
|
</div>\
|
|
\
|
|
<div class="requests-grid">\
|
|
<!-- Submit Request Form -->\
|
|
<div class="request-form">\
|
|
<h2 style="color: #ffd700; margin-bottom: 1.5rem;">\uc0\u55357 \u56541 Request a Leak Hunt</h2>\
|
|
<form onsubmit="submitRequest(event)">\
|
|
<select id="requestTargetType" required style="width: 100%; padding: 0.5rem; margin-bottom: 1rem; background: rgba(0,0,0,0.5); border: 1px solid rgba(255,255,255,0.1); border-radius: 8px; color: #e0e0e0;">\
|
|
<option value="">Select target type...</option>\
|
|
<option value="model">\uc0\u55358 \u56598 AI Model</option>\
|
|
<option value="app">\uc0\u55357 \u56561 App/Interface</option>\
|
|
<option value="tool">\uc0\u55357 \u56615 Tool/Function</option>\
|
|
<option value="agent">\uc0\u55358 \u56605 AI Agent</option>\
|
|
<option value="plugin">\uc0\u55357 \u56588 Plugin/Extension</option>\
|
|
<option value="custom">\uc0\u9881 \u65039 Custom GPT/Bot</option>\
|
|
</select>\
|
|
<input type="text" id="requestModel" placeholder="Target name (e.g., Gemini Pro, GitHub Copilot)" required \
|
|
style="width: 100%; margin-bottom: 1rem;">\
|
|
<input type="url" id="requestUrl" placeholder="Target URL (optional)" \
|
|
style="width: 100%; margin-bottom: 1rem;">\
|
|
<textarea id="requestDescription" placeholder="Why is this important? Any tips on how to get it?" \
|
|
style="width: 100%; min-height: 100px; margin-bottom: 1rem;"></textarea>\
|
|
<div style="display: flex; gap: 1rem; margin-bottom: 1rem;">\
|
|
<label style="display: flex; align-items: center; gap: 0.5rem; color: #888; font-size: 0.9rem;">\
|
|
<input type="checkbox" id="requestRequiresLogin" style="width: auto;">\
|
|
\uc0\u55357 \u56592 Login Required\
|
|
</label>\
|
|
<label style="display: flex; align-items: center; gap: 0.5rem; color: #888; font-size: 0.9rem;">\
|
|
<input type="checkbox" id="requestRequiresPaid" style="width: auto;">\
|
|
\uc0\u55357 \u56496 Paid Access\
|
|
</label>\
|
|
</div>\
|
|
<input type="number" id="requestBounty" placeholder="Bounty points (optional)" min="0" \
|
|
style="width: 100%; margin-bottom: 1rem;">\
|
|
<button type="submit" style="width: 100%;">Submit Request</button>\
|
|
</form>\
|
|
</div>\
|
|
\
|
|
<!-- Active Requests -->\
|
|
<div class="request-list">\
|
|
<h2 style="color: #ffd700; margin-bottom: 1rem;">\uc0\u55357 \u56613 Hot Requests</h2>\
|
|
<div class="filter-tabs">\
|
|
<div class="filter-tab active" onclick="filterRequests('trending')">\uc0\u55357 \u56613 Trending</div>\
|
|
<div class="filter-tab" onclick="filterRequests('bounty')">\uc0\u55357 \u56496 Highest Bounty</div>\
|
|
<div class="filter-tab" onclick="filterRequests('new')">\uc0\u55356 \u56725 Newest</div>\
|
|
<div class="filter-tab" onclick="filterRequests('myvotes')">\uc0\u55357 \u56473 My Votes</div>\
|
|
</div>\
|
|
<div id="requestsList">\
|
|
<p style="color: #666; text-align: center;">No requests yet. Be the first to request a leak hunt!</p>\
|
|
</div>\
|
|
</div>\
|
|
</div>\
|
|
</div>\
|
|
</div>\
|
|
\
|
|
<script>\
|
|
// Simulated database (in real app, this would be a backend)\
|
|
let leakDatabase = JSON.parse(localStorage.getItem('leakDatabase') || '[]');\
|
|
let selectedSubmissions = new Set();\
|
|
let userStats = JSON.parse(localStorage.getItem('userStats') || '\{\}');\
|
|
let leakRequests = JSON.parse(localStorage.getItem('leakRequests') || '[]');\
|
|
let userVotes = JSON.parse(localStorage.getItem('userVotes') || '\{\}');\
|
|
let dailyChallenge = JSON.parse(localStorage.getItem('dailyChallenge') || 'null');\
|
|
\
|
|
// Initialize\
|
|
updateUI();\
|
|
initializeDailyChallenge();\
|
|
startChallengeTimer();\
|
|
\
|
|
function submitLeak(event) \{\
|
|
event.preventDefault();\
|
|
\
|
|
const source = document.getElementById('sourceName').value;\
|
|
const submission = \{\
|
|
id: Date.now().toString(),\
|
|
source: source,\
|
|
targetType: document.getElementById('targetType').value,\
|
|
instance: document.getElementById('instanceId').value,\
|
|
targetUrl: document.getElementById('targetUrl').value || null,\
|
|
requiresLogin: document.getElementById('requiresLogin').checked,\
|
|
requiresPaid: document.getElementById('requiresPaid').checked,\
|
|
accessNotes: document.getElementById('accessNotes').value || null,\
|
|
parentSystem: document.getElementById('parentSystem').value || null,\
|
|
functionName: document.getElementById('functionName').value || null,\
|
|
content: document.getElementById('leakContent').value,\
|
|
toolPrompts: document.getElementById('toolPrompts').value || null,\
|
|
context: document.getElementById('context').value,\
|
|
timestamp: new Date().toISOString(),\
|
|
verifications: 0,\
|
|
confidence: 0,\
|
|
isFirstDiscovery: false,\
|
|
hasTools: document.getElementById('hasTools').checked\
|
|
\};\
|
|
\
|
|
// Calculate initial confidence based on content\
|
|
submission.confidence = calculateInitialConfidence(submission.content);\
|
|
\
|
|
// Check if this is the first discovery for this specific target\
|
|
const targetKey = `$\{submission.targetType\}:$\{submission.instance\}$\{submission.functionName ? ':' + submission.functionName : ''\}`;\
|
|
const existingForTarget = leakDatabase.filter(sub => \{\
|
|
const subKey = `$\{sub.targetType\}:$\{sub.instance\}$\{sub.functionName ? ':' + sub.functionName : ''\}`;\
|
|
return subKey === targetKey;\
|
|
\});\
|
|
\
|
|
if (existingForTarget.length === 0) \{\
|
|
submission.isFirstDiscovery = true;\
|
|
\}\
|
|
\
|
|
leakDatabase.push(submission);\
|
|
\
|
|
// Update user stats\
|
|
if (!userStats[source]) \{\
|
|
userStats[source] = \{\
|
|
submissions: 0,\
|
|
verifiedLeaks: 0,\
|
|
firstDiscoveries: 0,\
|
|
totalScore: 0,\
|
|
joinDate: new Date().toISOString(),\
|
|
toolsDiscovered: 0,\
|
|
appsDiscovered: 0,\
|
|
agentsDiscovered: 0\
|
|
\};\
|
|
\}\
|
|
\
|
|
userStats[source].submissions++;\
|
|
if (submission.isFirstDiscovery) \{\
|
|
userStats[source].firstDiscoveries++;\
|
|
userStats[source].totalScore += 100; // 100 points for first discovery\
|
|
\
|
|
// Extra points for discovering non-model targets\
|
|
if (submission.targetType !== 'model') \{\
|
|
userStats[source].totalScore += 50; // Bonus for diversity\
|
|
\}\
|
|
\
|
|
// Track specific discovery types\
|
|
if (submission.targetType === 'tool') userStats[source].toolsDiscovered++;\
|
|
if (submission.targetType === 'app') userStats[source].appsDiscovered++;\
|
|
if (submission.targetType === 'agent') userStats[source].agentsDiscovered++;\
|
|
\}\
|
|
userStats[source].totalScore += 10; // 10 points for any submission\
|
|
\
|
|
// Bonus points for tool prompts\
|
|
if (submission.hasTools && submission.toolPrompts) \{\
|
|
userStats[source].totalScore += 30; // Extra points for comprehensive submission\
|
|
\}\
|
|
\
|
|
saveDatabase();\
|
|
updateUI();\
|
|
\
|
|
// Clear form\
|
|
document.getElementById('sourceName').value = '';\
|
|
document.getElementById('targetType').value = '';\
|
|
document.getElementById('instanceId').value = '';\
|
|
document.getElementById('targetUrl').value = '';\
|
|
document.getElementById('requiresLogin').checked = false;\
|
|
document.getElementById('requiresPaid').checked = false;\
|
|
document.getElementById('accessNotes').value = '';\
|
|
document.getElementById('parentSystem').value = '';\
|
|
document.getElementById('functionName').value = '';\
|
|
document.getElementById('leakContent').value = '';\
|
|
document.getElementById('toolPrompts').value = '';\
|
|
document.getElementById('context').value = '';\
|
|
document.getElementById('hasTools').checked = false;\
|
|
document.getElementById('additionalFields').style.display = 'none';\
|
|
document.getElementById('toolsSection').style.display = 'none';\
|
|
\
|
|
showAlert(submission.isFirstDiscovery ? \
|
|
'\uc0\u55356 \u57225 First discovery! You found a new leak!' : \
|
|
'Leak submitted successfully!');\
|
|
\}\
|
|
\
|
|
function updateTargetFields() \{\
|
|
const targetType = document.getElementById('targetType').value;\
|
|
const additionalFields = document.getElementById('additionalFields');\
|
|
const instancePlaceholder = document.getElementById('instanceId');\
|
|
\
|
|
if (targetType === 'tool' || targetType === 'plugin') \{\
|
|
additionalFields.style.display = 'block';\
|
|
instancePlaceholder.placeholder = 'Tool/Plugin name (e.g., Code Interpreter, WebPilot)';\
|
|
\} else if (targetType === 'agent') \{\
|
|
additionalFields.style.display = 'block';\
|
|
instancePlaceholder.placeholder = 'Agent name (e.g., AutoGPT, BabyAGI)';\
|
|
\} else if (targetType === 'app') \{\
|
|
additionalFields.style.display = 'none';\
|
|
instancePlaceholder.placeholder = 'App name (e.g., Cursor, GitHub Copilot)';\
|
|
\} else if (targetType === 'custom') \{\
|
|
additionalFields.style.display = 'block';\
|
|
instancePlaceholder.placeholder = 'Custom GPT/Bot name';\
|
|
\} else \{\
|
|
additionalFields.style.display = 'none';\
|
|
instancePlaceholder.placeholder = 'Model name (e.g., GPT-4, Claude-3)';\
|
|
\}\
|
|
\}\
|
|
\
|
|
function toggleToolsSection() \{\
|
|
const toolsSection = document.getElementById('toolsSection');\
|
|
const hasTools = document.getElementById('hasTools').checked;\
|
|
toolsSection.style.display = hasTools ? 'block' : 'none';\
|
|
\}\
|
|
\
|
|
function calculateInitialConfidence(content) \{\
|
|
// Simple heuristics for initial confidence\
|
|
let confidence = 50; // Base confidence\
|
|
\
|
|
// Check for common system prompt patterns\
|
|
if (content.includes('You are') || content.includes('Your purpose')) confidence += 10;\
|
|
if (content.includes('instructions') || content.includes('guidelines')) confidence += 10;\
|
|
if (content.includes('Do not') || content.includes('Never')) confidence += 10;\
|
|
if (content.length > 500) confidence += 10;\
|
|
if (content.includes('\\n') && content.split('\\n').length > 5) confidence += 10;\
|
|
\
|
|
return Math.min(confidence, 90); // Cap at 90% until verified\
|
|
\}\
|
|
\
|
|
function updateUI() \{\
|
|
updateSubmissionsList();\
|
|
updateStatistics();\
|
|
updateSelectors();\
|
|
\}\
|
|
\
|
|
function updateSubmissionsList() \{\
|
|
const list = document.getElementById('submissionsList');\
|
|
\
|
|
if (leakDatabase.length === 0) \{\
|
|
list.innerHTML = '<p style="color: #666; text-align: center;">No submissions yet. Be the first to contribute!</p>';\
|
|
return;\
|
|
\}\
|
|
\
|
|
// Group by target type and instance\
|
|
const grouped = leakDatabase.reduce((acc, submission) => \{\
|
|
const targetType = submission.targetType || 'model'; // Backwards compatibility\
|
|
const typeEmoji = \{\
|
|
'model': '\uc0\u55358 \u56598 ',\
|
|
'app': '\uc0\u55357 \u56561 ',\
|
|
'tool': '\uc0\u55357 \u56615 ',\
|
|
'agent': '\uc0\u55358 \u56605 ',\
|
|
'plugin': '\uc0\u55357 \u56588 ',\
|
|
'custom': '\uc0\u9881 \u65039 '\
|
|
\}[targetType] || '\uc0\u55357 \u56516 ';\
|
|
\
|
|
const groupKey = `$\{typeEmoji\} $\{submission.instance\}`;\
|
|
if (!acc[groupKey]) acc[groupKey] = [];\
|
|
acc[groupKey].push(submission);\
|
|
return acc;\
|
|
\}, \{\});\
|
|
\
|
|
list.innerHTML = Object.entries(grouped).map(([groupName, submissions]) => `\
|
|
<div style="margin-bottom: 2rem;">\
|
|
<h4 style="color: #00aaff; margin-bottom: 1rem;">$\{groupName\} ($\{submissions.length\} submissions)</h4>\
|
|
$\{submissions.map(sub => \{\
|
|
const targetInfo = sub.functionName ? \
|
|
`<span style="color: #ff9933; font-size: 0.8rem;">\uc0\u8594 $\{sub.functionName\}</span>` : '';\
|
|
const parentInfo = sub.parentSystem ? \
|
|
`<span style="color: #666; font-size: 0.8rem;">($\{sub.parentSystem\})</span>` : '';\
|
|
const toolsBadge = sub.hasTools ? \
|
|
'<span style="background: rgba(255,153,51,0.2); color: #ff9933; padding: 0.2rem 0.5rem; border-radius: 10px; font-size: 0.7rem; margin-left: 0.5rem;">+tools</span>' : '';\
|
|
\
|
|
// Access badges\
|
|
const accessBadges = [];\
|
|
if (sub.requiresLogin) accessBadges.push('<span style="background: rgba(255,107,107,0.2); color: #ff6b6b; padding: 0.2rem 0.5rem; border-radius: 10px; font-size: 0.7rem; margin-left: 0.3rem;">\uc0\u55357 \u56592 </span>');\
|
|
if (sub.requiresPaid) accessBadges.push('<span style="background: rgba(255,215,0,0.2); color: #ffd700; padding: 0.2rem 0.5rem; border-radius: 10px; font-size: 0.7rem; margin-left: 0.3rem;">\uc0\u55357 \u56496 </span>');\
|
|
\
|
|
const linkButton = sub.targetUrl ? \
|
|
`<a href="$\{sub.targetUrl\}" target="_blank" style="position: absolute; top: 0.5rem; left: 0.5rem; background: rgba(0,170,255,0.2); color: #00aaff; padding: 0.2rem 0.6rem; border-radius: 10px; font-size: 0.7rem; text-decoration: none; border: 1px solid rgba(0,170,255,0.3);" onclick="event.stopPropagation();">\uc0\u55357 \u56599 Visit</a>` : '';\
|
|
\
|
|
return `\
|
|
<div class="submission-item $\{selectedSubmissions.has(sub.id) ? 'selected' : ''\}" \
|
|
onclick="toggleSelection('$\{sub.id\}')"\
|
|
data-id="$\{sub.id\}"\
|
|
style="position: relative;">\
|
|
$\{linkButton\}\
|
|
<div class="submission-header">\
|
|
<span class="submission-source">$\{sub.source\} $\{parentInfo\}</span>\
|
|
<span class="submission-date">$\{new Date(sub.timestamp).toLocaleDateString()\}</span>\
|
|
</div>\
|
|
$\{targetInfo\}\
|
|
<div class="submission-preview">$\{sub.content.substring(0, 100)\}...</div>\
|
|
$\{sub.accessNotes ? `<div style="color: #666; font-size: 0.8rem; margin-top: 0.3rem;">\uc0\u8505 \u65039 $\{sub.accessNotes\}</div>` : ''\}\
|
|
<div class="submission-confidence">$\{sub.confidence\}%</div>\
|
|
<div style="position: absolute; bottom: 0.5rem; right: 0.5rem;">\
|
|
$\{toolsBadge\}$\{accessBadges.join('')\}\
|
|
</div>\
|
|
</div>\
|
|
`;\
|
|
\}).join('')\}\
|
|
</div>\
|
|
`).join('');\
|
|
\}\
|
|
\
|
|
function updateStatistics() \{\
|
|
// Count unique targets by type\
|
|
const targetCounts = leakDatabase.reduce((acc, sub) => \{\
|
|
const targetType = sub.targetType || 'model';\
|
|
const key = `$\{targetType\}:$\{sub.instance\}`;\
|
|
acc.add(key);\
|
|
return acc;\
|
|
\}, new Set());\
|
|
\
|
|
document.getElementById('activeLeaks').textContent = targetCounts.size;\
|
|
document.getElementById('totalSubmissions').textContent = leakDatabase.length;\
|
|
\
|
|
const verified = leakDatabase.filter(sub => sub.confidence >= 90).length;\
|
|
document.getElementById('verifiedPrompts').textContent = verified;\
|
|
\
|
|
document.getElementById('uniqueInstances').textContent = targetCounts.size;\
|
|
\
|
|
// Calculate average similarity from recent comparisons\
|
|
const avgSim = localStorage.getItem('avgSimilarity') || '0';\
|
|
document.getElementById('avgSimilarity').textContent = avgSim + '%';\
|
|
\
|
|
const highConf = leakDatabase.filter(sub => sub.confidence >= 80).length;\
|
|
document.getElementById('highConfidence').textContent = highConf;\
|
|
\}\
|
|
\
|
|
function updateSelectors() \{\
|
|
const selectA = document.getElementById('instanceA');\
|
|
const selectB = document.getElementById('instanceB');\
|
|
\
|
|
const options = '<option value="">Select submission...</option>' + \
|
|
leakDatabase.map(sub => \{\
|
|
const targetType = sub.targetType || 'model';\
|
|
const typeLabel = targetType.charAt(0).toUpperCase() + targetType.slice(1);\
|
|
const fullName = sub.functionName ? \
|
|
`$\{sub.instance\} \uc0\u8594 $\{sub.functionName\}` : sub.instance;\
|
|
return `<option value="$\{sub.id\}">[$\{typeLabel\}] $\{fullName\} - $\{sub.source\} ($\{new Date(sub.timestamp).toLocaleDateString()\})</option>`;\
|
|
\}).join('');\
|
|
\
|
|
selectA.innerHTML = options;\
|
|
selectB.innerHTML = options;\
|
|
\}\
|
|
\
|
|
function toggleSelection(id) \{\
|
|
if (selectedSubmissions.has(id)) \{\
|
|
selectedSubmissions.delete(id);\
|
|
\} else \{\
|
|
selectedSubmissions.add(id);\
|
|
\}\
|
|
updateUI();\
|
|
\}\
|
|
\
|
|
function compareInstances() \{\
|
|
const idA = document.getElementById('instanceA').value;\
|
|
const idB = document.getElementById('instanceB').value;\
|
|
\
|
|
if (!idA || !idB || idA === idB) \{\
|
|
showAlert('Please select two different submissions to compare');\
|
|
return;\
|
|
\}\
|
|
\
|
|
const subA = leakDatabase.find(sub => sub.id === idA);\
|
|
const subB = leakDatabase.find(sub => sub.id === idB);\
|
|
\
|
|
performComparison(subA, subB);\
|
|
\}\
|
|
\
|
|
function performComparison(subA, subB) \{\
|
|
document.getElementById('comparisonResults').style.display = 'block';\
|
|
\
|
|
// Display content\
|
|
document.getElementById('instanceAContent').textContent = subA.content;\
|
|
document.getElementById('instanceBContent').textContent = subB.content;\
|
|
\
|
|
// Normalize texts for comparison (remove extra whitespace, lowercase for some checks)\
|
|
const normA = normalizeText(subA.content);\
|
|
const normB = normalizeText(subB.content);\
|
|
\
|
|
// Calculate metrics\
|
|
const charMatch = calculateCharMatch(normA, normB);\
|
|
const wordMatch = calculateWordMatch(normA, normB);\
|
|
const structureMatch = calculateStructureMatch(subA.content, subB.content);\
|
|
const coreSimilarity = calculateCoreSimilarity(normA, normB);\
|
|
\
|
|
// Update UI\
|
|
document.getElementById('charMatch').textContent = charMatch + '%';\
|
|
document.getElementById('wordMatch').textContent = wordMatch + '%';\
|
|
document.getElementById('structureMatch').textContent = structureMatch + '%';\
|
|
document.getElementById('coreSimilarity').textContent = coreSimilarity + '%';\
|
|
\
|
|
// Generate consensus view\
|
|
generateConsensusView(subA.content, subB.content);\
|
|
\
|
|
// Update average similarity\
|
|
const avgSim = Math.round((charMatch + wordMatch + structureMatch + coreSimilarity) / 4);\
|
|
localStorage.setItem('avgSimilarity', avgSim.toString());\
|
|
\
|
|
// Update confidence scores if high match\
|
|
if (coreSimilarity > 85) \{\
|
|
subA.confidence = Math.min(100, subA.confidence + 5);\
|
|
subB.confidence = Math.min(100, subB.confidence + 5);\
|
|
subA.verifications++;\
|
|
subB.verifications++;\
|
|
\
|
|
// Award points for verification\
|
|
if (userStats[subA.source]) \{\
|
|
userStats[subA.source].totalScore += 20; // 20 points for verification\
|
|
if (subA.confidence >= 95 && !subA.wasVerified) \{\
|
|
userStats[subA.source].verifiedLeaks++;\
|
|
userStats[subA.source].totalScore += 50; // Bonus for reaching verified status\
|
|
subA.wasVerified = true;\
|
|
\}\
|
|
\}\
|
|
if (userStats[subB.source]) \{\
|
|
userStats[subB.source].totalScore += 20;\
|
|
if (subB.confidence >= 95 && !subB.wasVerified) \{\
|
|
userStats[subB.source].verifiedLeaks++;\
|
|
userStats[subB.source].totalScore += 50;\
|
|
subB.wasVerified = true;\
|
|
\}\
|
|
\}\
|
|
\
|
|
saveDatabase();\
|
|
updateUI();\
|
|
\}\
|
|
\
|
|
// Scroll to results\
|
|
document.getElementById('comparisonResults').scrollIntoView(\{ behavior: 'smooth' \});\
|
|
\}\
|
|
\
|
|
function normalizeText(text) \{\
|
|
return text\
|
|
.toLowerCase()\
|
|
.replace(/\\s+/g, ' ')\
|
|
.replace(/[^\\w\\s]/g, '')\
|
|
.trim();\
|
|
\}\
|
|
\
|
|
function calculateCharMatch(textA, textB) \{\
|
|
const longer = textA.length > textB.length ? textA : textB;\
|
|
const shorter = textA.length > textB.length ? textB : textA;\
|
|
\
|
|
let matches = 0;\
|
|
for (let i = 0; i < shorter.length; i++) \{\
|
|
if (shorter[i] === longer[i]) matches++;\
|
|
\}\
|
|
\
|
|
return Math.round((matches / longer.length) * 100);\
|
|
\}\
|
|
\
|
|
function calculateWordMatch(textA, textB) \{\
|
|
const wordsA = new Set(textA.split(' '));\
|
|
const wordsB = new Set(textB.split(' '));\
|
|
\
|
|
const intersection = new Set([...wordsA].filter(x => wordsB.has(x)));\
|
|
const union = new Set([...wordsA, ...wordsB]);\
|
|
\
|
|
return Math.round((intersection.size / union.size) * 100);\
|
|
\}\
|
|
\
|
|
function calculateStructureMatch(textA, textB) \{\
|
|
// Compare line counts, paragraph structure, etc.\
|
|
const linesA = textA.split('\\n').filter(l => l.trim());\
|
|
const linesB = textB.split('\\n').filter(l => l.trim());\
|
|
\
|
|
const lineRatio = Math.min(linesA.length, linesB.length) / Math.max(linesA.length, linesB.length);\
|
|
\
|
|
// Check for similar patterns (numbered lists, bullet points, etc.)\
|
|
const hasNumbersA = /^\\d+\\./.test(textA);\
|
|
const hasNumbersB = /^\\d+\\./.test(textB);\
|
|
const hasBulletsA = /^[-*\'95]/.test(textA);\
|
|
const hasBulletsB = /^[-*\'95]/.test(textB);\
|
|
\
|
|
let structureScore = lineRatio * 50;\
|
|
if (hasNumbersA === hasNumbersB) structureScore += 25;\
|
|
if (hasBulletsA === hasBulletsB) structureScore += 25;\
|
|
\
|
|
return Math.round(structureScore);\
|
|
\}\
|
|
\
|
|
function calculateCoreSimilarity(textA, textB) \{\
|
|
// Use a simple sliding window approach to find common phrases\
|
|
const minPhraseLength = 10;\
|
|
const commonPhrases = [];\
|
|
\
|
|
for (let i = 0; i <= textA.length - minPhraseLength; i++) \{\
|
|
for (let len = minPhraseLength; len <= 50 && i + len <= textA.length; len++) \{\
|
|
const phrase = textA.substring(i, i + len);\
|
|
if (textB.includes(phrase)) \{\
|
|
commonPhrases.push(phrase);\
|
|
\}\
|
|
\}\
|
|
\}\
|
|
\
|
|
// Remove overlapping phrases\
|
|
const uniquePhrases = commonPhrases.filter((phrase, index) => \{\
|
|
return !commonPhrases.some((other, otherIndex) => \
|
|
otherIndex !== index && other.includes(phrase) && other.length > phrase.length\
|
|
);\
|
|
\});\
|
|
\
|
|
const commonLength = uniquePhrases.reduce((sum, phrase) => sum + phrase.length, 0);\
|
|
const avgLength = (textA.length + textB.length) / 2;\
|
|
\
|
|
return Math.round((commonLength / avgLength) * 100);\
|
|
\}\
|
|
\
|
|
function generateConsensusView(textA, textB) \{\
|
|
const consensusDiv = document.getElementById('consensusText');\
|
|
\
|
|
// Find common lines/sections\
|
|
const linesA = textA.split('\\n');\
|
|
const linesB = textB.split('\\n');\
|
|
\
|
|
let consensus = [];\
|
|
\
|
|
linesA.forEach(lineA => \{\
|
|
const trimmedA = lineA.trim();\
|
|
if (!trimmedA) return;\
|
|
\
|
|
const matchingLine = linesB.find(lineB => \{\
|
|
const trimmedB = lineB.trim();\
|
|
// Allow for minor differences\
|
|
return trimmedB && (\
|
|
trimmedA === trimmedB ||\
|
|
similarity(trimmedA.toLowerCase(), trimmedB.toLowerCase()) > 0.8\
|
|
);\
|
|
\});\
|
|
\
|
|
if (matchingLine) \{\
|
|
consensus.push(`<span class="highlight-match">$\{trimmedA\}</span>`);\
|
|
\}\
|
|
\});\
|
|
\
|
|
if (consensus.length > 0) \{\
|
|
consensusDiv.innerHTML = consensus.join('\\n');\
|
|
\} else \{\
|
|
consensusDiv.innerHTML = '<span style="color: #666;">No exact line matches found. Consider checking word-level similarities above.</span>';\
|
|
\}\
|
|
\}\
|
|
\
|
|
function similarity(s1, s2) \{\
|
|
const longer = s1.length > s2.length ? s1 : s2;\
|
|
const shorter = s1.length > s2.length ? s2 : s1;\
|
|
\
|
|
if (longer.length === 0) return 1.0;\
|
|
\
|
|
const editDistance = levenshteinDistance(longer, shorter);\
|
|
return (longer.length - editDistance) / longer.length;\
|
|
\}\
|
|
\
|
|
function levenshteinDistance(s1, s2) \{\
|
|
const costs = [];\
|
|
for (let i = 0; i <= s1.length; i++) \{\
|
|
let lastValue = i;\
|
|
for (let j = 0; j <= s2.length; j++) \{\
|
|
if (i === 0) \{\
|
|
costs[j] = j;\
|
|
\} else if (j > 0) \{\
|
|
let newValue = costs[j - 1];\
|
|
if (s1.charAt(i - 1) !== s2.charAt(j - 1)) \{\
|
|
newValue = Math.min(Math.min(newValue, lastValue), costs[j]) + 1;\
|
|
\}\
|
|
costs[j - 1] = lastValue;\
|
|
lastValue = newValue;\
|
|
\}\
|
|
\}\
|
|
if (i > 0) costs[s2.length] = lastValue;\
|
|
\}\
|
|
return costs[s2.length];\
|
|
\}\
|
|
\
|
|
function saveDatabase() \{\
|
|
localStorage.setItem('leakDatabase', JSON.stringify(leakDatabase));\
|
|
localStorage.setItem('userStats', JSON.stringify(userStats));\
|
|
localStorage.setItem('leakRequests', JSON.stringify(leakRequests));\
|
|
localStorage.setItem('userVotes', JSON.stringify(userVotes));\
|
|
localStorage.setItem('dailyChallenge', JSON.stringify(dailyChallenge));\
|
|
\}\
|
|
\
|
|
function showAlert(message) \{\
|
|
const alert = document.getElementById('alert');\
|
|
alert.textContent = message;\
|
|
alert.style.display = 'block';\
|
|
\
|
|
setTimeout(() => \{\
|
|
alert.style.display = 'none';\
|
|
\}, 3000);\
|
|
\}\
|
|
\
|
|
// Leaderboard functions\
|
|
function toggleLeaderboard() \{\
|
|
const overlay = document.getElementById('leaderboardOverlay');\
|
|
overlay.style.display = overlay.style.display === 'none' ? 'block' : 'none';\
|
|
if (overlay.style.display === 'block') \{\
|
|
updateLeaderboard();\
|
|
\}\
|
|
\}\
|
|
\
|
|
function switchLeaderboardTab(tab) \{\
|
|
document.querySelectorAll('.leaderboard-tab').forEach(t => t.classList.remove('active'));\
|
|
document.querySelectorAll('.leaderboard-content').forEach(c => c.style.display = 'none');\
|
|
\
|
|
event.target.classList.add('active');\
|
|
document.getElementById(`$\{tab\}-content`).style.display = 'block';\
|
|
\}\
|
|
\
|
|
function updateLeaderboard() \{\
|
|
updateRankings();\
|
|
updateAchievements();\
|
|
updateTimeline();\
|
|
\}\
|
|
\
|
|
function updateRankings() \{\
|
|
const rankingsList = document.getElementById('rankingsList');\
|
|
\
|
|
// Sort users by total score\
|
|
const sortedUsers = Object.entries(userStats)\
|
|
.sort((a, b) => b[1].totalScore - a[1].totalScore)\
|
|
.slice(0, 10); // Top 10\
|
|
\
|
|
if (sortedUsers.length === 0) \{\
|
|
rankingsList.innerHTML = '<p style="color: #666; text-align: center;">No contributors yet!</p>';\
|
|
return;\
|
|
\}\
|
|
\
|
|
rankingsList.innerHTML = sortedUsers.map(([username, stats], index) => \{\
|
|
const rank = index + 1;\
|
|
const rankClass = rank <= 3 ? `rank-$\{rank\}` : '';\
|
|
const rankEmoji = rank === 1 ? '\uc0\u55357 \u56401 ' : rank === 2 ? '\u55358 \u56648 ' : rank === 3 ? '\u55358 \u56649 ' : `#$\{rank\}`;\
|
|
\
|
|
return `\
|
|
<div class="rank-item">\
|
|
<div class="rank-number $\{rankClass\}">$\{rankEmoji\}</div>\
|
|
<div class="rank-user">\
|
|
<div class="rank-username">$\{username\}</div>\
|
|
<div class="rank-stats">\
|
|
<span>\uc0\u55357 \u56548 $\{stats.submissions\} submissions</span>\
|
|
<span>\uc0\u9989 $\{stats.verifiedLeaks\} verified</span>\
|
|
<span>\uc0\u55356 \u57119 $\{stats.firstDiscoveries\} first discoveries</span>\
|
|
</div>\
|
|
</div>\
|
|
<div class="rank-score">$\{stats.totalScore\} pts</div>\
|
|
</div>\
|
|
`;\
|
|
\}).join('');\
|
|
\}\
|
|
\
|
|
function updateAchievements() \{\
|
|
const achievementsList = document.getElementById('achievementsList');\
|
|
const achievements = [];\
|
|
\
|
|
// First Discovery achievements\
|
|
const firstDiscoverers = \{\};\
|
|
leakDatabase.forEach(sub => \{\
|
|
if (sub.isFirstDiscovery) \{\
|
|
if (!firstDiscoverers[sub.instance]) \{\
|
|
firstDiscoverers[sub.instance] = sub.source;\
|
|
\}\
|
|
\}\
|
|
\});\
|
|
\
|
|
Object.entries(firstDiscoverers).forEach(([instance, user]) => \{\
|
|
achievements.push(\{\
|
|
icon: '\uc0\u55356 \u57285 ',\
|
|
title: `First $\{instance\} Leak`,\
|
|
user: user,\
|
|
description: `First to discover $\{instance\} system prompt`\
|
|
\});\
|
|
\});\
|
|
\
|
|
// Most Verified Leaks\
|
|
const topVerifier = Object.entries(userStats)\
|
|
.sort((a, b) => b[1].verifiedLeaks - a[1].verifiedLeaks)[0];\
|
|
\
|
|
if (topVerifier && topVerifier[1].verifiedLeaks > 0) \{\
|
|
achievements.push(\{\
|
|
icon: '\uc0\u55357 \u56589 ',\
|
|
title: 'Master Verifier',\
|
|
user: topVerifier[0],\
|
|
description: `$\{topVerifier[1].verifiedLeaks\} verified leaks`\
|
|
\});\
|
|
\}\
|
|
\
|
|
// Most Submissions\
|
|
const topSubmitter = Object.entries(userStats)\
|
|
.sort((a, b) => b[1].submissions - a[1].submissions)[0];\
|
|
\
|
|
if (topSubmitter && topSubmitter[1].submissions > 5) \{\
|
|
achievements.push(\{\
|
|
icon: '\uc0\u55357 \u56522 ',\
|
|
title: 'Prolific Hunter',\
|
|
user: topSubmitter[0],\
|
|
description: `$\{topSubmitter[1].submissions\} total submissions`\
|
|
\});\
|
|
\}\
|
|
\
|
|
// Highest Score\
|
|
const topScorer = Object.entries(userStats)\
|
|
.sort((a, b) => b[1].totalScore - a[1].totalScore)[0];\
|
|
\
|
|
if (topScorer) \{\
|
|
achievements.push(\{\
|
|
icon: '\uc0\u55356 \u57286 ',\
|
|
title: 'Top Contributor',\
|
|
user: topScorer[0],\
|
|
description: `$\{topScorer[1].totalScore\} total points`\
|
|
\});\
|
|
\}\
|
|
\
|
|
if (achievements.length === 0) \{\
|
|
achievementsList.innerHTML = '<p style="color: #666; text-align: center;">No achievements yet!</p>';\
|
|
return;\
|
|
\}\
|
|
\
|
|
achievementsList.innerHTML = achievements.map(achievement => `\
|
|
<div class="achievement-card">\
|
|
<div class="achievement-icon">$\{achievement.icon\}</div>\
|
|
<div class="achievement-title">$\{achievement.title\}</div>\
|
|
<div class="achievement-user">$\{achievement.user\}</div>\
|
|
<p style="color: #666; margin-top: 0.5rem; font-size: 0.9rem;">$\{achievement.description\}</p>\
|
|
</div>\
|
|
`).join('');\
|
|
\}\
|
|
\
|
|
function updateTimeline() \{\
|
|
const timelineList = document.getElementById('timelineList');\
|
|
\
|
|
// Get significant events\
|
|
const events = [];\
|
|
\
|
|
// First discoveries\
|
|
const instanceFirsts = \{\};\
|
|
leakDatabase.forEach(sub => \{\
|
|
if (sub.isFirstDiscovery && !instanceFirsts[sub.instance]) \{\
|
|
instanceFirsts[sub.instance] = \{\
|
|
user: sub.source,\
|
|
date: sub.timestamp,\
|
|
instance: sub.instance\
|
|
\};\
|
|
\}\
|
|
\});\
|
|
\
|
|
Object.values(instanceFirsts).forEach(event => \{\
|
|
events.push(\{\
|
|
date: event.date,\
|
|
type: 'discovery',\
|
|
text: `$\{event.user\} discovered the first $\{event.instance\} leak`\
|
|
\});\
|
|
\});\
|
|
\
|
|
// Verification milestones\
|
|
leakDatabase.forEach(sub => \{\
|
|
if (sub.confidence >= 95 && sub.wasVerified) \{\
|
|
events.push(\{\
|
|
date: sub.timestamp,\
|
|
type: 'verification',\
|
|
text: `$\{sub.instance\} leak verified by $\{sub.source\}`\
|
|
\});\
|
|
\}\
|
|
\});\
|
|
\
|
|
// Sort by date\
|
|
events.sort((a, b) => new Date(b.date) - new Date(a.date));\
|
|
\
|
|
if (events.length === 0) \{\
|
|
timelineList.innerHTML = '<p style="color: #666; text-align: center;">No events yet!</p>';\
|
|
return;\
|
|
\}\
|
|
\
|
|
timelineList.innerHTML = events.slice(0, 20).map(event => `\
|
|
<div class="timeline-item">\
|
|
<div class="timeline-dot"></div>\
|
|
<div class="timeline-content">\
|
|
<div class="timeline-date">$\{new Date(event.date).toLocaleString()\}</div>\
|
|
<div class="timeline-event">$\{event.text\}</div>\
|
|
</div>\
|
|
</div>\
|
|
`).join('');\
|
|
\}\
|
|
\
|
|
// Requests & Challenges functions\
|
|
function toggleRequests() \{\
|
|
const overlay = document.getElementById('requestsOverlay');\
|
|
overlay.style.display = overlay.style.display === 'none' ? 'block' : 'none';\
|
|
if (overlay.style.display === 'block') \{\
|
|
updateRequestsList();\
|
|
\}\
|
|
\}\
|
|
\
|
|
function initializeDailyChallenge() \{\
|
|
const now = new Date();\
|
|
const tomorrow = new Date(now);\
|
|
tomorrow.setDate(tomorrow.getDate() + 1);\
|
|
tomorrow.setHours(0, 0, 0, 0);\
|
|
\
|
|
if (!dailyChallenge || new Date(dailyChallenge.expires) < now) \{\
|
|
// Create new daily challenge\
|
|
const challenges = [\
|
|
\{ model: 'GPT-4 Turbo', reward: 500 \},\
|
|
\{ model: 'Claude 3 Opus', reward: 600 \},\
|
|
\{ model: 'Gemini Ultra', reward: 700 \},\
|
|
\{ model: 'Llama 3', reward: 400 \},\
|
|
\{ model: 'Mistral Large', reward: 450 \}\
|
|
];\
|
|
\
|
|
const randomChallenge = challenges[Math.floor(Math.random() * challenges.length)];\
|
|
dailyChallenge = \{\
|
|
model: randomChallenge.model,\
|
|
reward: randomChallenge.reward,\
|
|
expires: tomorrow.toISOString(),\
|
|
completedBy: []\
|
|
\};\
|
|
saveDatabase();\
|
|
\}\
|
|
\
|
|
document.getElementById('challengeDescription').textContent = \
|
|
`Find and verify a system prompt from $\{dailyChallenge.model\}!`;\
|
|
\}\
|
|
\
|
|
function startChallengeTimer() \{\
|
|
setInterval(updateChallengeTimer, 1000);\
|
|
updateChallengeTimer();\
|
|
\}\
|
|
\
|
|
function updateChallengeTimer() \{\
|
|
if (!dailyChallenge) return;\
|
|
\
|
|
const now = new Date();\
|
|
const expires = new Date(dailyChallenge.expires);\
|
|
const diff = expires - now;\
|
|
\
|
|
if (diff <= 0) \{\
|
|
initializeDailyChallenge();\
|
|
return;\
|
|
\}\
|
|
\
|
|
const hours = Math.floor(diff / (1000 * 60 * 60));\
|
|
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));\
|
|
const seconds = Math.floor((diff % (1000 * 60)) / 1000);\
|
|
\
|
|
document.getElementById('challengeTimer').textContent = \
|
|
`Time remaining: $\{hours\}:$\{minutes.toString().padStart(2, '0')\}:$\{seconds.toString().padStart(2, '0')\}`;\
|
|
\}\
|
|
\
|
|
function submitRequest(event) \{\
|
|
event.preventDefault();\
|
|
\
|
|
const currentUser = prompt('Enter your username to submit this request:');\
|
|
if (!currentUser) return;\
|
|
\
|
|
const request = \{\
|
|
id: Date.now().toString(),\
|
|
targetType: document.getElementById('requestTargetType').value,\
|
|
model: document.getElementById('requestModel').value,\
|
|
targetUrl: document.getElementById('requestUrl').value || null,\
|
|
requiresLogin: document.getElementById('requestRequiresLogin').checked,\
|
|
requiresPaid: document.getElementById('requestRequiresPaid').checked,\
|
|
description: document.getElementById('requestDescription').value,\
|
|
bounty: parseInt(document.getElementById('requestBounty').value) || 0,\
|
|
requestedBy: currentUser,\
|
|
timestamp: new Date().toISOString(),\
|
|
votes: 0,\
|
|
voters: [],\
|
|
status: 'open'\
|
|
\};\
|
|
\
|
|
leakRequests.push(request);\
|
|
saveDatabase();\
|
|
updateRequestsList();\
|
|
\
|
|
// Clear form\
|
|
document.getElementById('requestModel').value = '';\
|
|
document.getElementById('requestDescription').value = '';\
|
|
document.getElementById('requestBounty').value = '';\
|
|
\
|
|
showAlert('Request submitted successfully!');\
|
|
\}\
|
|
\
|
|
function updateRequestsList() \{\
|
|
const requestsList = document.getElementById('requestsList');\
|
|
const filterType = document.querySelector('.filter-tab.active')?.textContent.includes('Trending') ? 'trending' :\
|
|
document.querySelector('.filter-tab.active')?.textContent.includes('Bounty') ? 'bounty' :\
|
|
document.querySelector('.filter-tab.active')?.textContent.includes('Newest') ? 'new' : 'myvotes';\
|
|
\
|
|
let filteredRequests = [...leakRequests];\
|
|
\
|
|
// Apply filters\
|
|
switch(filterType) \{\
|
|
case 'trending':\
|
|
filteredRequests.sort((a, b) => b.votes - a.votes);\
|
|
break;\
|
|
case 'bounty':\
|
|
filteredRequests.sort((a, b) => b.bounty - a.bounty);\
|
|
break;\
|
|
case 'new':\
|
|
filteredRequests.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));\
|
|
break;\
|
|
case 'myvotes':\
|
|
const currentUser = localStorage.getItem('currentUser');\
|
|
if (currentUser && userVotes[currentUser]) \{\
|
|
filteredRequests = filteredRequests.filter(req => userVotes[currentUser].includes(req.id));\
|
|
\}\
|
|
break;\
|
|
\}\
|
|
\
|
|
if (filteredRequests.length === 0) \{\
|
|
requestsList.innerHTML = '<p style="color: #666; text-align: center;">No requests found.</p>';\
|
|
return;\
|
|
\}\
|
|
\
|
|
requestsList.innerHTML = filteredRequests.slice(0, 10).map(request => \{\
|
|
const currentUser = localStorage.getItem('currentUser');\
|
|
const hasVoted = currentUser && userVotes[currentUser] && userVotes[currentUser].includes(request.id);\
|
|
const isTrending = request.votes > 5;\
|
|
\
|
|
const targetType = request.targetType || 'model';\
|
|
const typeEmoji = \{\
|
|
'model': '\uc0\u55358 \u56598 ',\
|
|
'app': '\uc0\u55357 \u56561 ',\
|
|
'tool': '\uc0\u55357 \u56615 ',\
|
|
'agent': '\uc0\u55358 \u56605 ',\
|
|
'plugin': '\uc0\u55357 \u56588 ',\
|
|
'custom': '\uc0\u9881 \u65039 '\
|
|
\}[targetType] || '\uc0\u55357 \u56516 ';\
|
|
\
|
|
// Access indicators\
|
|
const accessInfo = [];\
|
|
if (request.requiresLogin) accessInfo.push('\uc0\u55357 \u56592 ');\
|
|
if (request.requiresPaid) accessInfo.push('\uc0\u55357 \u56496 ');\
|
|
const accessString = accessInfo.length > 0 ? ` $\{accessInfo.join(' ')\}` : '';\
|
|
\
|
|
const linkIcon = request.targetUrl ? \
|
|
`<a href="$\{request.targetUrl\}" target="_blank" style="text-decoration: none; margin-left: 0.5rem;" onclick="event.stopPropagation();" title="Visit target">\uc0\u55357 \u56599 </a>` : '';\
|
|
\
|
|
return `\
|
|
<div class="request-item">\
|
|
<div class="request-header">\
|
|
<span class="request-model">$\{typeEmoji\} $\{request.model\}$\{accessString\}$\{linkIcon\}</span>\
|
|
<div class="request-votes">\
|
|
$\{isTrending ? '<span class="trending-indicator">\uc0\u55357 \u56613 Trending</span>' : ''\}\
|
|
<span class="vote-count">$\{request.votes\} votes</span>\
|
|
<button class="vote-button $\{hasVoted ? 'voted' : ''\}" \
|
|
onclick="voteForRequest('$\{request.id\}')">\
|
|
$\{hasVoted ? 'Voted \uc0\u10003 ' : 'Vote'\}\
|
|
</button>\
|
|
</div>\
|
|
</div>\
|
|
$\{request.description ? `<p class="request-description">$\{request.description\}</p>` : ''\}\
|
|
<div class="request-meta">\
|
|
<span>Requested by $\{request.requestedBy\}</span>\
|
|
$\{request.bounty > 0 ? `<span class="bounty-badge">+$\{request.bounty\} bounty</span>` : ''\}\
|
|
</div>\
|
|
</div>\
|
|
`;\
|
|
\}).join('');\
|
|
\}\
|
|
\
|
|
function voteForRequest(requestId) \{\
|
|
const currentUser = prompt('Enter your username to vote:');\
|
|
if (!currentUser) return;\
|
|
\
|
|
localStorage.setItem('currentUser', currentUser);\
|
|
\
|
|
if (!userVotes[currentUser]) \{\
|
|
userVotes[currentUser] = [];\
|
|
\}\
|
|
\
|
|
const request = leakRequests.find(r => r.id === requestId);\
|
|
if (!request) return;\
|
|
\
|
|
if (userVotes[currentUser].includes(requestId)) \{\
|
|
// Remove vote\
|
|
userVotes[currentUser] = userVotes[currentUser].filter(id => id !== requestId);\
|
|
request.votes--;\
|
|
request.voters = request.voters.filter(v => v !== currentUser);\
|
|
\} else \{\
|
|
// Add vote\
|
|
userVotes[currentUser].push(requestId);\
|
|
request.votes++;\
|
|
request.voters.push(currentUser);\
|
|
\}\
|
|
\
|
|
saveDatabase();\
|
|
updateRequestsList();\
|
|
\}\
|
|
\
|
|
function filterRequests(type) \{\
|
|
document.querySelectorAll('.filter-tab').forEach(tab => tab.classList.remove('active'));\
|
|
event.target.classList.add('active');\
|
|
updateRequestsList();\
|
|
\}\
|
|
\
|
|
// Check for daily challenge completion\
|
|
function checkDailyChallengeCompletion(submission) \{\
|
|
if (!dailyChallenge || dailyChallenge.completedBy.includes(submission.source)) return;\
|
|
\
|
|
if (submission.instance === dailyChallenge.model && submission.confidence >= 90) \{\
|
|
// Challenge completed!\
|
|
dailyChallenge.completedBy.push(submission.source);\
|
|
\
|
|
if (!userStats[submission.source]) \{\
|
|
userStats[submission.source] = \{\
|
|
submissions: 0,\
|
|
verifiedLeaks: 0,\
|
|
firstDiscoveries: 0,\
|
|
totalScore: 0,\
|
|
joinDate: new Date().toISOString(),\
|
|
dailyChallenges: 0\
|
|
\};\
|
|
\}\
|
|
\
|
|
userStats[submission.source].totalScore += dailyChallenge.reward;\
|
|
userStats[submission.source].dailyChallenges = (userStats[submission.source].dailyChallenges || 0) + 1;\
|
|
\
|
|
saveDatabase();\
|
|
showAlert(`\uc0\u55356 \u57225 Daily Challenge Completed! +$\{dailyChallenge.reward\} points!`);\
|
|
\}\
|
|
\}\
|
|
\
|
|
// Modify the existing submitLeak function to check for challenge completion\
|
|
const originalSubmitLeak = submitLeak;\
|
|
submitLeak = function(event) \{\
|
|
const result = originalSubmitLeak(event);\
|
|
const latestSubmission = leakDatabase[leakDatabase.length - 1];\
|
|
if (latestSubmission) \{\
|
|
checkDailyChallengeCompletion(latestSubmission);\
|
|
\}\
|
|
return result;\
|
|
\};\
|
|
</script>\
|
|
</body>\
|
|
</html>} |