Initial Commit
This commit is contained in:
+42
@@ -0,0 +1,42 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*.pyo
|
||||
*.pyd
|
||||
*.egg
|
||||
*.egg-info/
|
||||
dist/
|
||||
build/
|
||||
.eggs/
|
||||
|
||||
# Virtual environment
|
||||
venv/
|
||||
.venv/
|
||||
env/
|
||||
.env
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.*
|
||||
|
||||
# pytest
|
||||
.pytest_cache/
|
||||
.cache/
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
logs/
|
||||
|
||||
# Distribution / packaging
|
||||
*.whl
|
||||
*.tar.gz
|
||||
@@ -0,0 +1,69 @@
|
||||
import random
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.responses import HTMLResponse
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI(title="MileageDraw")
|
||||
|
||||
templates = Jinja2Templates(directory="templates")
|
||||
|
||||
# Prize Probabilities:
|
||||
# 1st Prize: 20%
|
||||
# 2nd Prize: 30%
|
||||
# 3rd Prize: 50%
|
||||
PRIZES = [
|
||||
{"rank": 1, "name": "1st Prize", "miles": 10000, "probability": 0.10},
|
||||
{"rank": 2, "name": "2nd Prize", "miles": 5000, "probability": 0.30},
|
||||
{"rank": 3, "name": "3rd Prize", "miles": 2000, "probability": 0.60},
|
||||
]
|
||||
|
||||
class DrawResult(BaseModel):
|
||||
rank: int
|
||||
name: str
|
||||
miles: int
|
||||
|
||||
@app.get("/", response_class=HTMLResponse)
|
||||
async def index(request: Request):
|
||||
return templates.TemplateResponse(
|
||||
request=request, name="index.html"
|
||||
)
|
||||
|
||||
@app.post("/api/draw", response_model=DrawResult)
|
||||
async def draw_prize():
|
||||
rand_val = random.random()
|
||||
cumulative = 0.0
|
||||
for prize in PRIZES:
|
||||
cumulative += prize["probability"]
|
||||
if rand_val <= cumulative:
|
||||
return DrawResult(
|
||||
rank=prize["rank"],
|
||||
name=prize["name"],
|
||||
miles=prize["miles"]
|
||||
)
|
||||
|
||||
# Fallback in case of floating point precision issues
|
||||
last = PRIZES[-1]
|
||||
return DrawResult(
|
||||
rank=last["rank"],
|
||||
name=last["name"],
|
||||
miles=last["miles"]
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run("main:app", host="0.0.0.0", port=10000, reload=True)
|
||||
|
||||
# import random
|
||||
# def sum(L, n):
|
||||
# if n == 0:
|
||||
# return L[0]
|
||||
# else:
|
||||
# return L[n] + sum(L, n-1)
|
||||
|
||||
# L = [random.randint(1, 100) for _ in range(10)]
|
||||
# print(L)
|
||||
|
||||
# s = sum(L, len(L)-1)
|
||||
# print(s)
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="dark" lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>MileageDraw - Win Big Today</title>
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Spline+Sans:wght@300;400;500;600;700&display=swap" rel="stylesheet"/>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"primary": "#2b4bee",
|
||||
"accent": "#fbbf24",
|
||||
"background-light": "#f6f6f8",
|
||||
"background-dark": "#101322",
|
||||
},
|
||||
fontFamily: {
|
||||
"display": ["Spline Sans", "sans-serif"]
|
||||
},
|
||||
borderRadius: {"DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px"},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark font-display text-slate-900 dark:text-slate-100 min-h-screen">
|
||||
<div class="relative flex h-auto min-h-screen w-full flex-col bg-background-light dark:bg-background-dark overflow-x-hidden">
|
||||
<div class="layout-container flex h-full grow flex-col">
|
||||
<!-- Navigation Bar -->
|
||||
<header class="flex items-center justify-between whitespace-nowrap border-b border-solid border-slate-200 dark:border-slate-800 px-6 lg:px-20 py-4 bg-background-light dark:bg-background-dark sticky top-0 z-50">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="text-primary size-8">
|
||||
<span class="material-symbols-outlined text-4xl">redeem</span>
|
||||
</div>
|
||||
<h2 class="text-slate-900 dark:text-white text-xl font-bold leading-tight tracking-tight">MileageDraw</h2>
|
||||
</div>
|
||||
<div class="flex flex-1 justify-end items-center gap-6 lg:gap-10">
|
||||
<nav class="hidden md:flex items-center gap-8">
|
||||
<a class="text-slate-600 dark:text-slate-300 hover:text-primary dark:hover:text-primary text-sm font-semibold transition-colors" href="#">Home</a>
|
||||
<a class="text-slate-600 dark:text-slate-300 hover:text-primary dark:hover:text-primary text-sm font-semibold transition-colors" href="#">My Prizes</a>
|
||||
<a class="text-slate-600 dark:text-slate-300 hover:text-primary dark:hover:text-primary text-sm font-semibold transition-colors" href="#">How to Play</a>
|
||||
</nav>
|
||||
<div class="flex items-center gap-4">
|
||||
<button class="flex min-w-[120px] cursor-pointer items-center justify-center rounded-xl h-10 px-5 bg-primary/10 border border-primary/20 text-primary text-sm font-bold">
|
||||
<span class="material-symbols-outlined text-sm mr-2">account_balance_wallet</span>
|
||||
<span class="truncate" id="user-miles">15,400 Miles</span>
|
||||
</button>
|
||||
<div class="bg-center bg-no-repeat aspect-square bg-cover rounded-full size-10 border-2 border-primary/30" data-alt="User profile avatar circle" style='background-image: url("https://lh3.googleusercontent.com/aida-public/AB6AXuASf-yBhfIyds7eDugHWDN-bVo-aoZM14xRSjRn1GNH4vvCCYuu6gLziV5Evf5W0hqHxLrhmsM7tMWPhL-PjDqctgWRBCEnW3zELC5v2BZrvEhgo7NB55Oo3YJ0-2C3fZmMgCxSC5SuwkcGmCvlEJiijE0RYtDZ7XenI3RD5Lt1VaEmPQ82FSB26oCxEJJ5I-hy02TTYa_npKImAXIOfm-x5Mh8evuGz0MoqoPTOSTuU3LxrHouNtN65FJ4KP4YUzBeSvC1b60St8_D");'></div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="flex-1 flex flex-col items-center px-4 lg:px-20 py-10 max-w-7xl mx-auto w-full">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8 w-full items-center">
|
||||
<!-- Left Side: Prize Board -->
|
||||
<div class="lg:col-span-3 flex flex-col gap-4 order-2 lg:order-1">
|
||||
<div class="bg-slate-50 dark:bg-slate-900/50 p-6 rounded-2xl border border-slate-200 dark:border-slate-800 backdrop-blur-sm">
|
||||
<h3 class="text-lg font-bold mb-6 flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-accent">military_tech</span>
|
||||
Prize Pool
|
||||
</h3>
|
||||
<div class="space-y-6">
|
||||
<div class="relative pl-4 border-l-4 border-accent">
|
||||
<p class="text-xs uppercase tracking-wider text-slate-500 dark:text-slate-400 font-bold">1st Prize</p>
|
||||
<p class="text-2xl font-black text-slate-900 dark:text-white">10,000 <span class="text-sm font-normal text-slate-500">Miles</span></p>
|
||||
</div>
|
||||
<div class="relative pl-4 border-l-4 border-slate-400">
|
||||
<p class="text-xs uppercase tracking-wider text-slate-500 dark:text-slate-400 font-bold">2nd Prize</p>
|
||||
<p class="text-2xl font-black text-slate-900 dark:text-white">5,000 <span class="text-sm font-normal text-slate-500">Miles</span></p>
|
||||
</div>
|
||||
<div class="relative pl-4 border-l-4 border-orange-400">
|
||||
<p class="text-xs uppercase tracking-wider text-slate-500 dark:text-slate-400 font-bold">3rd Prize</p>
|
||||
<p class="text-2xl font-black text-slate-900 dark:text-white">2,000 <span class="text-sm font-normal text-slate-500">Miles</span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-primary/5 p-6 rounded-2xl border border-primary/20">
|
||||
<p class="text-sm text-slate-600 dark:text-slate-400 leading-relaxed italic">
|
||||
"Thousands of users have already claimed their rewards this month. Will you be next?"
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Center: Mystery Box -->
|
||||
<div class="lg:col-span-6 flex flex-col items-center justify-center gap-8 order-1 lg:order-2">
|
||||
<div class="text-center">
|
||||
<h1 class="text-4xl lg:text-5xl font-black text-slate-900 dark:text-white mb-2 tracking-tight">Try Your Luck!</h1>
|
||||
<p class="text-slate-600 dark:text-slate-400 text-lg">Open the Mystery Box to win huge rewards</p>
|
||||
</div>
|
||||
<div class="relative group w-full max-w-md aspect-square flex items-center justify-center">
|
||||
<!-- Background Glow Effect -->
|
||||
<div class="absolute inset-0 bg-primary/20 blur-[100px] rounded-full scale-75 group-hover:bg-primary/30 transition-all duration-500" id="box-glow"></div>
|
||||
<!-- Mystery Box Container -->
|
||||
<div class="relative w-full h-full bg-gradient-to-br from-slate-800 to-slate-950 rounded-3xl border-4 border-accent/30 shadow-2xl flex flex-col items-center justify-center overflow-hidden transition-all duration-300" id="mystery-box-container">
|
||||
<!-- Box Illustration -->
|
||||
<div class="flex flex-col items-center transition-all duration-500" id="mystery-box-content">
|
||||
<span class="material-symbols-outlined text-[160px] text-accent drop-shadow-[0_0_20px_rgba(251,191,36,0.5)]">featured_seasonal_and_gifts</span>
|
||||
<div class="mt-4 flex gap-2">
|
||||
<div class="w-3 h-3 rounded-full bg-accent animate-pulse"></div>
|
||||
<div class="w-3 h-3 rounded-full bg-accent/50 animate-pulse delay-75"></div>
|
||||
<div class="w-3 h-3 rounded-full bg-accent/20 animate-pulse delay-150"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Sparkle elements -->
|
||||
<span class="material-symbols-outlined absolute top-10 left-10 text-accent/40 text-2xl" id="sparkle-1">auto_awesome</span>
|
||||
<span class="material-symbols-outlined absolute bottom-12 right-12 text-accent/40 text-4xl" id="sparkle-2">auto_awesome</span>
|
||||
<span class="material-symbols-outlined absolute top-20 right-16 text-accent/40 text-xl" id="sparkle-3">auto_awesome</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center gap-4 w-full">
|
||||
<button id="draw-btn" class="w-full max-w-xs flex cursor-pointer items-center justify-center rounded-2xl h-16 px-8 bg-primary hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed text-white text-xl font-black shadow-lg shadow-primary/40 transition-all active:scale-95 group">
|
||||
<span class="mr-3" id="draw-btn-text">DRAW NOW</span>
|
||||
<span class="material-symbols-outlined group-hover:translate-x-1 transition-transform" id="draw-btn-icon">arrow_forward</span>
|
||||
</button>
|
||||
<p class="text-xs text-slate-500 font-medium">Cost: 500 Miles per draw</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Right Side: Recent Winners -->
|
||||
<div class="lg:col-span-3 flex flex-col gap-4 order-3">
|
||||
<div class="bg-slate-50 dark:bg-slate-900/50 p-6 rounded-2xl border border-slate-200 dark:border-slate-800">
|
||||
<h3 class="text-sm font-bold text-slate-500 uppercase tracking-widest mb-4">Live Winners</h3>
|
||||
<div class="space-y-4" id="recent-winners-list">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center overflow-hidden">
|
||||
<img alt="" class="w-full h-full object-cover" src="https://lh3.googleusercontent.com/aida-public/AB6AXuCNyWQdRGCg_-tNwAu4-0oRfpGbiWSPp5prILJ1oalpRniDZ1DQL7yiiiDxVsiNuFMgCiKBVvFQRXrjlinRU-iZI_YM0XcDO2BuaK6YVIUwvn7DWhqUMcYYSA9EDn9vknhh9Sii2sb8KQkpoNsJdu25N8vJIcRuFAAioW3NFk-UPNLBfIPsRe1LxmgaxR6s_EIO6RfaV49lqaDiNOODXxKWtL-kl6oczKoBh7P0-DRwgdVJ2hjHlY3Dt33RCg91dSaBBPffcqIO8Qky"/>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-bold">Alice W.</p>
|
||||
<p class="text-xs text-primary font-bold">+2,000 Miles</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center overflow-hidden">
|
||||
<img alt="" class="w-full h-full object-cover" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBTj1uufe8nMOFogBsc_4yK_47l2_5Pry-ZcyRdCdSMrBSxqOL13JewG1pyncXBAvV1zv1JDdfvampMOylwjHEwwIbgF4W2yFQas-Ra0mjUk0g62ExYQTtgxXeE5wGFAMYHCBjg56C-y2Os4yh2oKfsTKeQzpoDZc9IYaaALg2ACfWKFZtsV_XAXShAntlb5IOji7F7p7jxcGRhnY9fvN6mOYHcGLriek1Ql4tOh6aNQMjOIeOQ_UiUjeGsfKC5Sn7iP3Z7oyyh5da7"/>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-bold">James K.</p>
|
||||
<p class="text-xs text-accent font-bold">+10,000 Miles</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center overflow-hidden">
|
||||
<img alt="" class="w-full h-full object-cover" src="https://lh3.googleusercontent.com/aida-public/AB6AXuCAB6XTgSBN_5iUE-8cN8bDKhHWZa8Vpo7NWgd8yJQmRnp_WjwCWbviTPKsDs2VpkPSSlUI9msh7kPgUx7UAxd9sGwy9XnRrqDeVtmVDFWWzXHBMmEr5Vh6UWS_L6ziv3CrZXf1_uFGYHrQusuJAX9Z_vpPq7cn7FgdUvlgBrcpBsqNT8VpGtRAHHhHhCi4QLX_lhvEdW5sXf9DILmez-bjHHv__qMEq0irhH1VAX2ve5ZejhD7cSt3362RekobZa3U0DRpS3wVKLSj"/>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-bold">Elena R.</p>
|
||||
<p class="text-xs text-slate-400 font-bold">+500 Miles</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gradient-to-br from-primary to-blue-700 p-6 rounded-2xl text-white shadow-xl">
|
||||
<h4 class="font-bold text-lg mb-1">Double Odds!</h4>
|
||||
<p class="text-sm text-white/80">Active for the next 24 minutes. Draw now to increase your chances.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Footer Info -->
|
||||
<div class="mt-20 w-full border-t border-slate-200 dark:border-slate-800 pt-8 flex flex-col md:flex-row justify-between items-center gap-6">
|
||||
<div class="flex gap-12 text-sm text-slate-500 font-medium">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary">verified_user</span>
|
||||
Provably Fair
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary">speed</span>
|
||||
Instant Payouts
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary">support_agent</span>
|
||||
24/7 Support
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs text-slate-400">© 2024 MileageDraw Games. Please play responsibly.</p>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const drawBtn = document.getElementById("draw-btn");
|
||||
const drawBtnText = document.getElementById("draw-btn-text");
|
||||
const drawBtnIcon = document.getElementById("draw-btn-icon");
|
||||
const mysteryBoxContent = document.getElementById("mystery-box-content");
|
||||
const boxContainer = document.getElementById("mystery-box-container");
|
||||
const userMilesDisplay = document.getElementById("user-miles");
|
||||
|
||||
let userMiles = 15400; // Starting fake balance
|
||||
|
||||
const originalBoxHtml = `
|
||||
<span class="material-symbols-outlined text-[160px] text-accent drop-shadow-[0_0_20px_rgba(251,191,36,0.5)]">featured_seasonal_and_gifts</span>
|
||||
<div class="mt-4 flex gap-2">
|
||||
<div class="w-3 h-3 rounded-full bg-accent animate-pulse"></div>
|
||||
<div class="w-3 h-3 rounded-full bg-accent/50 animate-pulse delay-75"></div>
|
||||
<div class="w-3 h-3 rounded-full bg-accent/20 animate-pulse delay-150"></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
function updateMilesDisplay(miles) {
|
||||
userMilesDisplay.textContent = miles.toLocaleString() + " Miles";
|
||||
}
|
||||
|
||||
drawBtn.addEventListener("click", async () => {
|
||||
if (userMiles < 500) {
|
||||
alert("Not enough miles!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Deduct cost and update UI
|
||||
userMiles -= 500;
|
||||
updateMilesDisplay(userMiles);
|
||||
|
||||
// Reset UI if it was previously revealing a prize
|
||||
mysteryBoxContent.innerHTML = originalBoxHtml;
|
||||
|
||||
// Disable button while drawing
|
||||
drawBtn.disabled = true;
|
||||
drawBtnText.textContent = "DRAWING...";
|
||||
drawBtnIcon.textContent = "refresh";
|
||||
drawBtnIcon.classList.add("animate-spin");
|
||||
drawBtnIcon.classList.remove("group-hover:translate-x-1");
|
||||
|
||||
// Add some animation to the box
|
||||
boxContainer.classList.add("animate-pulse");
|
||||
mysteryBoxContent.classList.add("animate-bounce");
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/draw", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Network error");
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
// Wait for a short fake delay to build suspense
|
||||
await new Promise(r => setTimeout(r, 1200));
|
||||
|
||||
// Stop animations
|
||||
boxContainer.classList.remove("animate-pulse");
|
||||
mysteryBoxContent.classList.remove("animate-bounce");
|
||||
|
||||
// Display result in the box with a pop-in effect
|
||||
let prizeColorClass = "text-slate-400"; // 3rd prize fallback
|
||||
let bgGlow = "from-slate-700 to-slate-900";
|
||||
if (result.rank === 1) {
|
||||
prizeColorClass = "text-accent";
|
||||
bgGlow = "from-yellow-900 via-slate-900 to-slate-950";
|
||||
} else if (result.rank === 2) {
|
||||
prizeColorClass = "text-slate-200";
|
||||
bgGlow = "from-slate-600 via-slate-800 to-slate-900";
|
||||
} else if (result.rank === 3) {
|
||||
prizeColorClass = "text-orange-400";
|
||||
bgGlow = "from-orange-900 via-slate-900 to-slate-950";
|
||||
}
|
||||
|
||||
// Update user balance
|
||||
userMiles += result.miles;
|
||||
updateMilesDisplay(userMiles);
|
||||
|
||||
mysteryBoxContent.innerHTML = `
|
||||
<div class="flex flex-col items-center text-center animate-[pulse_1s_ease-in-out]">
|
||||
<span class="material-symbols-outlined text-[100px] ${prizeColorClass} drop-shadow-[0_0_20px_rgba(255,255,255,0.2)]">emoji_events</span>
|
||||
<h2 class="text-4xl font-black text-white mt-4 tracking-tighter">${result.name}</h2>
|
||||
<p class="text-2xl font-bold ${prizeColorClass} mt-3">+${result.miles.toLocaleString()} Miles</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Change box container background conditionally
|
||||
boxContainer.className = `relative w-full h-full bg-gradient-to-br ${bgGlow} rounded-3xl border-4 border-${result.rank === 1 ? 'accent' : (result.rank === 2 ? 'slate-400' : 'orange-400')}/40 shadow-2xl flex flex-col items-center justify-center overflow-hidden transition-all duration-500`;
|
||||
|
||||
// Setup button for "DRAW AGAIN"
|
||||
drawBtnText.textContent = "DRAW AGAIN";
|
||||
drawBtnIcon.textContent = "replay";
|
||||
drawBtnIcon.classList.remove("animate-spin");
|
||||
drawBtnIcon.classList.add("group-hover:-rotate-180");
|
||||
} catch (error) {
|
||||
console.error("Error drawing prize:", error);
|
||||
alert("An error occurred while drawing the prize. Please try again.");
|
||||
|
||||
// Reset button
|
||||
drawBtnText.textContent = "DRAW NOW";
|
||||
drawBtnIcon.textContent = "arrow_forward";
|
||||
drawBtnIcon.classList.remove("animate-spin");
|
||||
drawBtnIcon.classList.add("group-hover:translate-x-1");
|
||||
|
||||
boxContainer.classList.remove("animate-pulse");
|
||||
mysteryBoxContent.classList.remove("animate-bounce");
|
||||
} finally {
|
||||
// Re-enable button
|
||||
drawBtn.disabled = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,5 @@
|
||||
import datetime
|
||||
|
||||
print(datetime.date.today())
|
||||
print(datetime.time().hour)
|
||||
print(datetime.datetime.now())
|
||||
@@ -0,0 +1,27 @@
|
||||
import random
|
||||
|
||||
PRIZES = [
|
||||
{"rank": 1, "name": "1st Prize", "miles": 10000, "probability": 0.20},
|
||||
{"rank": 2, "name": "2nd Prize", "miles": 5000, "probability": 0.30},
|
||||
{"rank": 3, "name": "3rd Prize", "miles": 2000, "probability": 0.50},
|
||||
]
|
||||
|
||||
def draw_prize():
|
||||
rand_val = random.random()
|
||||
cumulative = 0.0
|
||||
for prize in PRIZES:
|
||||
cumulative += prize["probability"]
|
||||
if rand_val <= cumulative:
|
||||
return prize
|
||||
return PRIZES[-1]
|
||||
|
||||
counts = {1: 0, 2: 0, 3: 0}
|
||||
trials = 100000
|
||||
|
||||
for _ in range(trials):
|
||||
res = draw_prize()
|
||||
counts[res["rank"]] += 1
|
||||
|
||||
print("Results for 100,000 trials:")
|
||||
for rank, count in counts.items():
|
||||
print(f"Rank {rank}: {count/trials*100:.2f}%")
|
||||
@@ -0,0 +1,182 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html class="dark" lang="en"><head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>MileageDraw - Win Big Today</title>
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Spline+Sans:wght@300;400;500;600;700&display=swap" rel="stylesheet"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
||||
<script id="tailwind-config">
|
||||
tailwind.config = {
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
"primary": "#2b4bee",
|
||||
"accent": "#fbbf24",
|
||||
"background-light": "#f6f6f8",
|
||||
"background-dark": "#101322",
|
||||
},
|
||||
fontFamily: {
|
||||
"display": ["Spline Sans", "sans-serif"]
|
||||
},
|
||||
borderRadius: {"DEFAULT": "0.25rem", "lg": "0.5rem", "xl": "0.75rem", "full": "9999px"},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="bg-background-light dark:bg-background-dark font-display text-slate-900 dark:text-slate-100 min-h-screen">
|
||||
<div class="relative flex h-auto min-h-screen w-full flex-col bg-background-light dark:bg-background-dark overflow-x-hidden">
|
||||
<div class="layout-container flex h-full grow flex-col">
|
||||
<!-- Navigation Bar -->
|
||||
<header class="flex items-center justify-between whitespace-nowrap border-b border-solid border-slate-200 dark:border-slate-800 px-6 lg:px-20 py-4 bg-background-light dark:bg-background-dark sticky top-0 z-50">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="text-primary size-8">
|
||||
<span class="material-symbols-outlined text-4xl">redeem</span>
|
||||
</div>
|
||||
<h2 class="text-slate-900 dark:text-white text-xl font-bold leading-tight tracking-tight">MileageDraw</h2>
|
||||
</div>
|
||||
<div class="flex flex-1 justify-end items-center gap-6 lg:gap-10">
|
||||
<nav class="hidden md:flex items-center gap-8">
|
||||
<a class="text-slate-600 dark:text-slate-300 hover:text-primary dark:hover:text-primary text-sm font-semibold transition-colors" href="#">Home</a>
|
||||
<a class="text-slate-600 dark:text-slate-300 hover:text-primary dark:hover:text-primary text-sm font-semibold transition-colors" href="#">My Prizes</a>
|
||||
<a class="text-slate-600 dark:text-slate-300 hover:text-primary dark:hover:text-primary text-sm font-semibold transition-colors" href="#">How to Play</a>
|
||||
</nav>
|
||||
<div class="flex items-center gap-4">
|
||||
<button class="flex min-w-[120px] cursor-pointer items-center justify-center rounded-xl h-10 px-5 bg-primary/10 border border-primary/20 text-primary text-sm font-bold">
|
||||
<span class="material-symbols-outlined text-sm mr-2">account_balance_wallet</span>
|
||||
<span class="truncate">15,400 Miles</span>
|
||||
</button>
|
||||
<div class="bg-center bg-no-repeat aspect-square bg-cover rounded-full size-10 border-2 border-primary/30" data-alt="User profile avatar circle" style='background-image: url("https://lh3.googleusercontent.com/aida-public/AB6AXuASf-yBhfIyds7eDugHWDN-bVo-aoZM14xRSjRn1GNH4vvCCYuu6gLziV5Evf5W0hqHxLrhmsM7tMWPhL-PjDqctgWRBCEnW3zELC5v2BZrvEhgo7NB55Oo3YJ0-2C3fZmMgCxSC5SuwkcGmCvlEJiijE0RYtDZ7XenI3RD5Lt1VaEmPQ82FSB26oCxEJJ5I-hy02TTYa_npKImAXIOfm-x5Mh8evuGz0MoqoPTOSTuU3LxrHouNtN65FJ4KP4YUzBeSvC1b60St8_D");'></div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="flex-1 flex flex-col items-center px-4 lg:px-20 py-10 max-w-7xl mx-auto w-full">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8 w-full items-center">
|
||||
<!-- Left Side: Prize Board -->
|
||||
<div class="lg:col-span-3 flex flex-col gap-4 order-2 lg:order-1">
|
||||
<div class="bg-slate-50 dark:bg-slate-900/50 p-6 rounded-2xl border border-slate-200 dark:border-slate-800 backdrop-blur-sm">
|
||||
<h3 class="text-lg font-bold mb-6 flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-accent">military_tech</span>
|
||||
Prize Pool
|
||||
</h3>
|
||||
<div class="space-y-6">
|
||||
<div class="relative pl-4 border-l-4 border-accent">
|
||||
<p class="text-xs uppercase tracking-wider text-slate-500 dark:text-slate-400 font-bold">1st Prize</p>
|
||||
<p class="text-2xl font-black text-slate-900 dark:text-white">10,000 <span class="text-sm font-normal text-slate-500">Miles</span></p>
|
||||
</div>
|
||||
<div class="relative pl-4 border-l-4 border-slate-400">
|
||||
<p class="text-xs uppercase tracking-wider text-slate-500 dark:text-slate-400 font-bold">2nd Prize</p>
|
||||
<p class="text-2xl font-black text-slate-900 dark:text-white">5,000 <span class="text-sm font-normal text-slate-500">Miles</span></p>
|
||||
</div>
|
||||
<div class="relative pl-4 border-l-4 border-orange-400">
|
||||
<p class="text-xs uppercase tracking-wider text-slate-500 dark:text-slate-400 font-bold">3rd Prize</p>
|
||||
<p class="text-2xl font-black text-slate-900 dark:text-white">2,000 <span class="text-sm font-normal text-slate-500">Miles</span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-primary/5 p-6 rounded-2xl border border-primary/20">
|
||||
<p class="text-sm text-slate-600 dark:text-slate-400 leading-relaxed italic">
|
||||
"Thousands of users have already claimed their rewards this month. Will you be next?"
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Center: Mystery Box -->
|
||||
<div class="lg:col-span-6 flex flex-col items-center justify-center gap-8 order-1 lg:order-2">
|
||||
<div class="text-center">
|
||||
<h1 class="text-4xl lg:text-5xl font-black text-slate-900 dark:text-white mb-2 tracking-tight">Try Your Luck!</h1>
|
||||
<p class="text-slate-600 dark:text-slate-400 text-lg">Open the Mystery Box to win huge rewards</p>
|
||||
</div>
|
||||
<div class="relative group cursor-pointer w-full max-w-md aspect-square flex items-center justify-center">
|
||||
<!-- Background Glow Effect -->
|
||||
<div class="absolute inset-0 bg-primary/20 blur-[100px] rounded-full scale-75 group-hover:bg-primary/30 transition-all duration-500"></div>
|
||||
<!-- Mystery Box Container -->
|
||||
<div class="relative w-full h-full bg-gradient-to-br from-slate-800 to-slate-950 rounded-3xl border-4 border-accent/30 shadow-2xl flex flex-col items-center justify-center overflow-hidden">
|
||||
<!-- Box Illustration (Simulated with Material Symbols and Gradients) -->
|
||||
<div class="flex flex-col items-center">
|
||||
<span class="material-symbols-outlined text-[160px] text-accent drop-shadow-[0_0_20px_rgba(251,191,36,0.5)]">featured_seasonal_and_gifts</span>
|
||||
<div class="mt-4 flex gap-2">
|
||||
<div class="w-3 h-3 rounded-full bg-accent animate-pulse"></div>
|
||||
<div class="w-3 h-3 rounded-full bg-accent/50 animate-pulse delay-75"></div>
|
||||
<div class="w-3 h-3 rounded-full bg-accent/20 animate-pulse delay-150"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Sparkle elements -->
|
||||
<span class="material-symbols-outlined absolute top-10 left-10 text-accent/40 text-2xl">auto_awesome</span>
|
||||
<span class="material-symbols-outlined absolute bottom-12 right-12 text-accent/40 text-4xl">auto_awesome</span>
|
||||
<span class="material-symbols-outlined absolute top-20 right-16 text-accent/40 text-xl">auto_awesome</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center gap-4 w-full">
|
||||
<button class="w-full max-w-xs flex cursor-pointer items-center justify-center rounded-2xl h-16 px-8 bg-primary hover:bg-primary/90 text-white text-xl font-black shadow-lg shadow-primary/40 transition-all active:scale-95 group">
|
||||
<span class="mr-3">DRAW NOW</span>
|
||||
<span class="material-symbols-outlined group-hover:translate-x-1 transition-transform">arrow_forward</span>
|
||||
</button>
|
||||
<p class="text-xs text-slate-500 font-medium">Cost: 500 Miles per draw</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Right Side: Recent Winners -->
|
||||
<div class="lg:col-span-3 flex flex-col gap-4 order-3">
|
||||
<div class="bg-slate-50 dark:bg-slate-900/50 p-6 rounded-2xl border border-slate-200 dark:border-slate-800">
|
||||
<h3 class="text-sm font-bold text-slate-500 uppercase tracking-widest mb-4">Live Winners</h3>
|
||||
<div class="space-y-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center overflow-hidden">
|
||||
<img alt="" class="w-full h-full object-cover" data-alt="User avatar of Alice" src="https://lh3.googleusercontent.com/aida-public/AB6AXuCNyWQdRGCg_-tNwAu4-0oRfpGbiWSPp5prILJ1oalpRniDZ1DQL7yiiiDxVsiNuFMgCiKBVvFQRXrjlinRU-iZI_YM0XcDO2BuaK6YVIUwvn7DWhqUMcYYSA9EDn9vknhh9Sii2sb8KQkpoNsJdu25N8vJIcRuFAAioW3NFk-UPNLBfIPsRe1LxmgaxR6s_EIO6RfaV49lqaDiNOODXxKWtL-kl6oczKoBh7P0-DRwgdVJ2hjHlY3Dt33RCg91dSaBBPffcqIO8Qky"/>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-bold">Alice W.</p>
|
||||
<p class="text-xs text-primary font-bold">+2,000 Miles</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center overflow-hidden">
|
||||
<img alt="" class="w-full h-full object-cover" data-alt="User avatar of Bob" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBTj1uufe8nMOFogBsc_4yK_47l2_5Pry-ZcyRdCdSMrBSxqOL13JewG1pyncXBAvV1zv1JDdfvampMOylwjHEwwIbgF4W2yFQas-Ra0mjUk0g62ExYQTtgxXeE5wGFAMYHCBjg56C-y2Os4yh2oKfsTKeQzpoDZc9IYaaALg2ACfWKFZtsV_XAXShAntlb5IOji7F7p7jxcGRhnY9fvN6mOYHcGLriek1Ql4tOh6aNQMjOIeOQ_UiUjeGsfKC5Sn7iP3Z7oyyh5da7"/>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-bold">James K.</p>
|
||||
<p class="text-xs text-accent font-bold">+10,000 Miles</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-10 h-10 rounded-full bg-primary/20 flex items-center justify-center overflow-hidden">
|
||||
<img alt="" class="w-full h-full object-cover" data-alt="User avatar of Carla" src="https://lh3.googleusercontent.com/aida-public/AB6AXuCAB6XTgSBN_5iUE-8cN8bDKhHWZa8Vpo7NWgd8yJQmRnp_WjwCWbviTPKsDs2VpkPSSlUI9msh7kPgUx7UAxd9sGwy9XnRrqDeVtmVDFWWzXHBMmEr5Vh6UWS_L6ziv3CrZXf1_uFGYHrQusuJAX9Z_vpPq7cn7FgdUvlgBrcpBsqNT8VpGtRAHHhHhCi4QLX_lhvEdW5sXf9DILmez-bjHHv__qMEq0irhH1VAX2ve5ZejhD7cSt3362RekobZa3U0DRpS3wVKLSj"/>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm font-bold">Elena R.</p>
|
||||
<p class="text-xs text-slate-400 font-bold">+500 Miles</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gradient-to-br from-primary to-blue-700 p-6 rounded-2xl text-white shadow-xl">
|
||||
<h4 class="font-bold text-lg mb-1">Double Odds!</h4>
|
||||
<p class="text-sm text-white/80">Active for the next 24 minutes. Draw now to increase your chances.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Footer Info -->
|
||||
<div class="mt-20 w-full border-t border-slate-200 dark:border-slate-800 pt-8 flex flex-col md:flex-row justify-between items-center gap-6">
|
||||
<div class="flex gap-12 text-sm text-slate-500 font-medium">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary">verified_user</span>
|
||||
Provably Fair
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary">speed</span>
|
||||
Instant Payouts
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary">support_agent</span>
|
||||
24/7 Support
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs text-slate-400">© 2024 MileageDraw Games. Please play responsibly.</p>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 360 KiB |
Reference in New Issue
Block a user