anycoder-f5ad2bba / index.html
JWGKnight's picture
Upload folder using huggingface_hub
aa7df61 verified
Raw
History Blame Contribute Delete
32.4 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>Eco — 1:1:1:1 Exact Equality Meal Planner</title>
<style>
:root {
--primary: #2563eb;
--primary-dark: #1d4ed8;
--accent: #eab308;
--success: #22c55e;
--bg-gradient: linear-gradient(135deg, #1e40af 0%, #2563eb 100%);
--card-bg: #ffffff;
--text-main: #1e293b;
--text-sub: #475569;
--border-radius: 24px;
}
* { box-sizing: border-box; transition: all 0.2s ease; }
body {
background: var(--bg-gradient);
font-family: 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
margin: 0;
padding: 24px 16px;
min-height: 100vh;
color: var(--text-main);
}
.container {
max-width: 1400px;
margin: 0 auto;
background: var(--card-bg);
border-radius: var(--border-radius);
box-shadow: 0 30px 50px -12px rgba(0, 0, 0, 0.4);
overflow: hidden;
display: flex;
flex-direction: column;
}
header {
padding: 24px 32px;
border-bottom: 1px solid #e2e8f0;
background: #f8fafc;
}
h1 { font-size: 1.8rem; margin: 0; color: var(--text-main); display: flex; align-items: center; gap: 12px; }
h1 small { font-size: 0.85rem; font-weight: normal; color: var(--text-sub); text-transform: uppercase; letter-spacing: 1px; }
.footer-link {
margin-left: auto;
font-size: 0.75rem;
color: var(--text-sub);
text-decoration: none;
font-weight: 600;
}
.footer-link:hover { color: var(--primary); text-decoration: underline; }
.main-content {
display: grid;
grid-template-columns: 380px 1fr;
gap: 0;
min-height: 600px;
}
/* Sidebar Inputs */
.sidebar {
background: #f1f5f9;
padding: 24px;
border-right: 1px solid #e2e8f0;
overflow-y: auto;
height: 100%;
}
.input-group { margin-bottom: 20px; }
.input-group h3 { font-size: 0.85rem; text-transform: uppercase; color: var(--text-sub); margin-bottom: 12px; letter-spacing: 0.5px; }
.control-row { margin-bottom: 16px; }
label { display: block; font-size: 0.8rem; font-weight: 700; margin-bottom: 6px; color: var(--text-main); }
input[type="number"], select {
width: 100%;
padding: 10px 12px;
border: 1px solid #cbd5e1;
border-radius: 12px;
font-size: 0.9rem;
background: white;
outline: none;
}
input[type="number"]:focus, select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(37,99,235,0.1); }
.checkbox-wrapper { display: flex; align-items: center; gap: 10px; margin-top: 8px; cursor: pointer; }
.checkbox-wrapper input { width: auto; accent-color: var(--primary); transform: scale(1.2); }
.checkbox-wrapper span { font-size: 0.85rem; color: var(--text-sub); }
.btn-group { display: flex; flex-direction: column; gap: 12px; margin-top: 30px; border-top: 2px solid #e2e8f0; padding-top: 20px; }
button {
width: 100%;
padding: 14px;
border: none;
border-radius: 14px;
font-weight: 700;
font-size: 0.95rem;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
transition: transform 0.1s, box-shadow 0.2s;
}
.btn-primary { background: var(--primary); color: white; box-shadow: 0 4px 12px rgba(37,99,235,0.3); }
.btn-primary:hover { background: var(--primary-dark); transform: translateY(-1px); }
.btn-secondary { background: white; color: var(--text-main); border: 2px solid #cbd5e1; }
.btn-secondary:hover { background: #f1f5f9; border-color: var(--text-sub); }
.btn-success { background: var(--success); color: white; box-shadow: 0 4px 12px rgba(34,197,94,0.3); }
.btn-success:hover { background: #16a34a; transform: translateY(-1px); }
/* Main Results Area */
.dashboard {
padding: 32px;
display: flex;
flex-direction: column;
gap: 24px;
}
.stats-bar {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
background: #fff;
padding: 20px;
border-radius: 20px;
border: 1px solid #e2e8f0;
text-align: center;
}
.stat-box h4 { font-size: 0.75rem; text-transform: uppercase; color: var(--text-sub); margin: 0; }
.stat-box .val { font-size: 2rem; font-weight: 800; margin: 8px 0; }
.stat-carbs { color: #ef4444; border-bottom: 3px solid #ef4444; }
.stat-protein { color: #f97316; border-bottom: 3px solid #f97316; }
.stat-fat { color: #eab308; border-bottom: 3px solid #eab308; }
.stat-vitamins { color: #22c55e; border-bottom: 3px solid #22c55e; }
.chart-section {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
align-items: center;
}
.chart-panel {
background: white;
padding: 20px;
border-radius: 24px;
box-shadow: 0 4px 6px -1px rgba(0,0,0,0.05);
text-align: center;
}
.chart-title { font-weight: 700; margin-bottom: 16px; color: var(--text-main); }
canvas { max-width: 100%; height: auto; }
.meal-planner {
background: #fefce8;
border: 2px solid #fde047;
border-radius: 24px;
padding: 24px;
position: relative;
}
.meal-planner::before {
content: "🎯 OPTIMAL 1:1:1:1 MEAL PLAN";
position: absolute;
top: -16px;
left: 20px;
background: #fde047;
padding: 0 12px;
font-weight: 800;
font-size: 0.8rem;
color: #854d0e;
border-radius: 12px;
}
.meal-list {
display: flex;
flex-direction: column;
gap: 12px;
max-height: 300px;
overflow-y: auto;
padding-right: 8px;
}
.meal-item {
background: white;
padding: 12px 16px;
border-radius: 16px;
display: flex;
justify-content: space-between;
align-items: center;
border-left: 4px solid var(--primary);
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.meal-details { display: flex; flex-direction: column; gap: 4px; }
.meal-name { font-weight: 700; font-size: 1.1rem; color: var(--text-main); }
.meal-nutrients { font-size: 0.8rem; font-family: monospace; color: var(--text-sub); }
.meal-count { font-weight: 700; background: var(--primary); color: white; padding: 4px 10px; border-radius: 20px; font-size: 0.85rem; }
.math-note {
background: #eef2ff;
padding: 16px;
border-radius: 16px;
font-family: 'Courier New', monospace;
font-size: 0.9rem;
color: #3730a3;
margin-top: 10px;
border-left: 5px solid var(--primary);
}
.math-note strong { color: var(--primary-dark); }
/* Food Selector Panel */
.food-panel {
position: sticky;
bottom: 0;
left: 0;
width: 100%;
background: white;
border-top: 1px solid #cbd5e1;
padding: 16px;
display: none; /* Hidden by default */
animation: slideUp 0.3s ease;
}
.food-panel.active { display: block; }
@keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
.food-header { display: flex; justify-content: space-between; margin-bottom: 12px; }
.food-search { display: flex; gap: 10px; margin-bottom: 12px; }
.food-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 8px; max-height: 200px; overflow-y: auto; padding: 8px; background: #f8fafc; border-radius: 12px; }
.food-item { display: flex; align-items: center; gap: 8px; padding: 6px; background: white; border-radius: 8px; border: 1px solid #e2e8f0; font-size: 0.8rem; }
.food-item input { width: auto; margin: 0; }
@media (max-width: 900px) {
.main-content { grid-template-columns: 1fr; }
.sidebar { border-right: none; border-bottom: 1px solid #e2e8f0; }
.stats-bar { grid-template-columns: 1fr 1fr; }
.chart-section { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>
🌾 ECO Planner
<small>1:1:1:1 Exact Equality Engine</small>
</h1>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="footer-link">Built with anycoder</a>
</header>
<div class="main-content">
<!-- Sidebar Controls -->
<aside class="sidebar">
<div class="input-group">
<h3>👤 Player Status</h3>
<div class="control-row">
<label>Current Calories</label>
<input type="number" id="curCalories" value="1200" min="0">
</div>
<div class="control-row">
<label>Max Calories Capacity</label>
<input type="number" id="maxCalories" value="3000" min="1000">
</div>
<div class="checkbox-wrapper">
<input type="checkbox" id="ignoreCalorieLimit">
<span>Ignore Calorie Limit (Unlimited Mode)</span>
</div>
</div>
<div class="input-group">
<h3>⚖️ Current Nutrients (Base)</h3>
<div class="control-row">
<label>🍞 Carbs (C)</label>
<input type="number" id="carbs" value="8" step="1">
</div>
<div class="control-row">
<label>🍗 Protein (P)</label>
<input type="number" id="protein" value="12" step="1">
</div>
<div class="control-row">
<label>🧈 Fat (F)</label>
<input type="number" id="fat" value="6" step="1">
</div>
<div class="control-row">
<label>🥕 Vitamins (V)</label>
<input type="number" id="vitamins" value="14" step="1">
</div>
</div>
<div class="input-group">
<h3>🍽️ Filters</h3>
<div class="control-row">
<label>Player Tier / Skill</label>
<select id="tier">
<option value="all">🌟 All Foods Available</option>
<option value="starter">🌱 Starter (Easy)</option>
<option value="campfire">🔥 Campfire Cook</option>
<option value="gatherer">🍄 Gatherer (Raw/Basic)</option>
<option value="baked">🍞 Baked Specialist</option>
<option value="cooked">🍲 Cooked Specialist</option>
<option value="advanced">🏆 Advanced Chef</option>
</select>
</div>
<div class="control-row">
<label>Preferred Biome</label>
<select id="biomeFilter">
<option value="all">🌍 Any Biome</option>
<option value="forest">🌲 Forest</option>
<option value="grassland">🌾 Grassland</option>
<option value="desert">🏜️ Desert</option>
<option value="rainforest">🌧️ Rainforest</option>
<option value="aquatic">💧 Aquatic</option>
</select>
</div>
<div class="checkbox-wrapper">
<input type="checkbox" id="disableTierFilter" checked>
<span>Disable Tier Filter</span>
</div>
<div class="checkbox-wrapper">
<input type="checkbox" id="disableBiomeFilter" checked>
<span>Disable Biome Filter</span>
</div>
</div>
<div class="btn-group">
<button id="toggleFoodPanelBtn" class="btn-secondary">📋 Edit Food Database</button>
<button id="randomizeBtn" class="btn-secondary">🎲 Random Balanced Plan</button>
<button id="calculateBtn" class="btn-primary">⚖️ CALCULATE PERFECT BALANCE</button>
</div>
</aside>
<!-- Main Dashboard -->
<main class="dashboard">
<!-- Current Stats Header -->
<div class="stats-bar">
<div class="stat-box stat-carbs">
<h4>Current Carbs</h4>
<div class="val" id="dispCurC">8</div>
</div>
<div class="stat-box stat-protein">
<h4>Current Protein</h4>
<div class="val" id="dispCurP">12</div>
</div>
<div class="stat-box stat-fat">
<h4>Current Fat</h4>
<div class="val" id="dispCurF">6</div>
</div>
<div class="stat-box stat-vitamins">
<h4>Current Vitamins</h4>
<div class="val" id="dispCurV">14</div>
</div>
</div>
<!-- Charts Section -->
<div class="chart-section">
<div class="chart-panel">
<div class="chart-title">Current Nutrient Status</div>
<canvas id="beforeChart" width="300" height="300"></canvas>
</div>
<div class="chart-panel">
<div class="chart-title">Target: 1:1:1:1 Equality</div>
<canvas id="afterChart" width="300" height="300"></canvas>
</div>
</div>
<!-- Meal Plan Output -->
<div class="meal-planner">
<h3 style="margin-top:0; font-size:1.2rem;">Generated Meal Plan</h3>
<div id="mealListContainer" class="meal-list">
<div style="text-align:center; padding: 40px 0; color: #94a3b8;">
Click "Calculate Perfect Balance" to generate a meal plan that equalizes all nutrients exactly.
</div>
</div>
<div id="mathNote" class="math-note">
<strong>🧮 ALGORITHM STATUS:</strong> <br>
Waiting for calculation...
</div>
<div style="display:flex; justify-content:space-between; margin-top:10px; font-size:0.9rem; color:var(--text-sub);">
<span id="calorieSummary">Calorie Budget: 1200 / 3000</span>
<span id="planCounter" style="font-weight:bold; color:var(--primary);">Plan 1 of 1</span>
</div>
</div>
</main>
</div>
<!-- Food Selector Panel -->
<div id="foodPanel" class="food-panel">
<div class="food-header">
<h3>🍽️ Active Food Database</h3>
<button onclick="document.getElementById('foodPanel').classList.remove('active')" style="padding: 4px 12px; font-size: 0.8rem;">Close</button>
</div>
<div class="food-search">
<input type="text" id="foodSearch" placeholder="Search food by name..." style="flex:1;">
<button id="selectAllBtn" style="padding: 8px 16px; font-size: 0.8rem; background: #cbd5e1;">Select All</button>
</div>
<div id="foodListContainer" class="food-list">
<!-- Food items injected here -->
</div>
</div>
</div>
<script>
// ==================== DATA & CONSTANTS ====================
const RAW_FOODS = [
{ name: "Heart Of Palm", carbs:4, protein:2, fat:0, vitamins:2, cal:100, tier:"gatherer", biomes:["rainforest","forest"] },
{ name: "Bolete Mushrooms", carbs:2, protein:4, fat:1, vitamins:1, cal:200, tier:"gatherer", biomes:["forest"] },
{ name: "Leavened Dough", carbs:6, protein:18, fat:13, vitamins:5, cal:10, tier:"advanced", biomes:["any"] },
{ name: "Charred Taro", carbs:10, protein:1, fat:0, vitamins:1, cal:350, tier:"campfire", biomes:["rainforest","forest"] },
{ name: "Taro Root", carbs:6, protein:1, fat:0, vitamins:1, cal:250, tier:"gatherer", biomes:["rainforest","forest"] },
{ name: "Baked Agave", carbs:14, protein:2, fat:4, vitamins:8, cal:700, tier:"baked", biomes:["desert"] },
{ name: "Huckleberries", carbs:2, protein:0, fat:0, vitamins:6, cal:150, tier:"gatherer", biomes:["forest"] },
{ name: "Pupusas", carbs:6, protein:11, fat:9, vitamins:14, cal:900, tier:"advanced", biomes:["any"] },
{ name: "Vegetable Medley", carbs:8, protein:4, fat:7, vitamins:17, cal:900, tier:"cooked", biomes:["any"] },
{ name: "Huckleberry Fritter", carbs:16, protein:0, fat:20, vitamins:8, cal:900, tier:"baked", biomes:["forest"] },
{ name: "Baked Heart Of Palm", carbs:12, protein:6, fat:4, vitamins:6, cal:700, tier:"baked", biomes:["rainforest"] },
{ name: "Camas Bulb Bake", carbs:12, protein:7, fat:5, vitamins:4, cal:700, tier:"baked", biomes:["grassland"] },
{ name: "Pineapple", carbs:6, protein:0, fat:0, vitamins:2, cal:200, tier:"gatherer", biomes:["rainforest"] },
{ name: "Basic Salad", carbs:18, protein:6, fat:4, vitamins:10, cal:800, tier:"starter", biomes:["any"] },
{ name: "Scrap Meat", carbs:0, protein:5, fat:5, vitamins:0, cal:50, tier:"starter", biomes:["any"] },
{ name: "Charred Sausage", carbs:0, protein:10, fat:14, vitamins:0, cal:700, tier:"campfire", biomes:["any"] },
{ name: "Clam Chowder", carbs:16, protein:15, fat:3, vitamins:11, cal:800, tier:"cooked", biomes:["aquatic"] },
{ name: "Wild Stew", carbs:10, protein:2, fat:6, vitamins:12, cal:1100, tier:"cooked", biomes:["forest"] },
{ name: "Fried Vegetables", carbs:11, protein:3, fat:8, vitamins:2, cal:560, tier:"cooked", biomes:["any"] },
{ name: "Tasty Tropical Pizza", carbs:21, protein:6, fat:12, vitamins:11, cal:1200, tier:"advanced", biomes:["rainforest"] },
{ name: "Meat Pie", carbs:18, protein:4, fat:20, vitamins:2, cal:1300, tier:"baked", biomes:["any"] },
{ name: "Fireweed Shoots", carbs:3, protein:1, fat:0, vitamins:4, cal:150, tier:"gatherer", biomes:["grassland"] },
{ name: "Crimson Salad", carbs:13, protein:7, fat:8, vitamins:28, cal:1200, tier:"advanced", biomes:["any"] },
{ name: "Baked Tomato", carbs:16, protein:1, fat:5, vitamins:6, cal:700, tier:"baked", biomes:["grassland"] },
{ name: "Corn Fritters", carbs:13, protein:4, fat:22, vitamins:8, cal:500, tier:"cooked", biomes:["grassland"] },
{ name: "Baked Meat", carbs:0, protein:17, fat:13, vitamins:0, cal:700, tier:"baked", biomes:["any"] },
{ name: "Bison Chow Fun", carbs:16, protein:13, fat:20, vitamins:8, cal:1450, tier:"advanced", biomes:["grassland"] },
{ name: "Pineapple Friend Rice", carbs:20, protein:9, fat:12, vitamins:12, cal:720, tier:"cooked", biomes:["rainforest"] },
{ name: "Baked Roast", carbs:4, protein:16, fat:10, vitamins:4, cal:1000, tier:"baked", biomes:["any"] },
{ name: "Camas Bread", carbs:13, protein:5, fat:11, vitamins:7, cal:800, tier:"baked", biomes:["grassland"] },
{ name: "Elk Taco", carbs:15, protein:8, fat:22, vitamins:6, cal:700, tier:"cooked", biomes:["forest"] },
{ name: "Flaxseed Oil", carbs:0, protein:0, fat:15, vitamins:0, cal:120, tier:"starter", biomes:["grassland"] },
{ name: "Sugar", carbs:15, protein:0, fat:0, vitamins:0, cal:50, tier:"starter", biomes:["any"] },
{ name: "Papaya", carbs:2, protein:1, fat:0, vitamins:5, cal:200, tier:"gatherer", biomes:["rainforest"] },
{ name: "Infused Oil", carbs:0, protein:0, fat:12, vitamins:3, cal:120, tier:"advanced", biomes:["any"] },
{ name: "Wilted Fiddleheads", carbs:4, protein:1, fat:0, vitamins:7, cal:350, tier:"gatherer", biomes:["forest"] },
{ name: "Wild Mix", carbs:15, protein:6, fat:4, vitamins:21, cal:800, tier:"cooked", biomes:["any"] },
{ name: "Elk Wellington", carbs:10, protein:26, fat:22, vitamins:4, cal:1450, tier:"advanced", biomes:["forest"] },
{ name: "Wheat", carbs:6, protein:2, fat:0, vitamins:0, cal:150, tier:"gatherer", biomes:["grassland"] },
{ name: "Bear S U P R E M E", carbs:6, protein:22, fat:23, vitamins:9, cal:1250, tier:"advanced", biomes:["forest"] },
{ name: "Vegetable Stock", carbs:11, protein:1, fat:2, vitamins:11, cal:700, tier:"cooked", biomes:["any"] },
{ name: "Vegetable Soup", carbs:12, protein:4, fat:7, vitamins:19, cal:1200, tier:"cooked", biomes:["any"] },
{ name: "Autumn Stew", carbs:13, protein:8, fat:5, vitamins:12, cal:1200, tier:"cooked", biomes:["forest"] },
{ name: "Bean Paste", carbs:3, protein:5, fat:7, vitamins:0, cal:40, tier:"starter", biomes:["any"] },
{ name: "Bearclaw", carbs:14, protein:4, fat:21, vitamins:7, cal:850, tier:"baked", biomes:["forest"] },
{ name: "Pirozhok", carbs:14, protein:19, fat:10, vitamins:4, cal:850, tier:"advanced", biomes:["any"] },
{ name: "Bread", carbs:23, protein:6, fat:4, vitamins:2, cal:750, tier:"baked", biomes:["any"] },
{ name: "Seared Meat", carbs:4, protein:19, fat:17, vitamins:7, cal:600, tier:"cooked", biomes:["any"] },
{ name: "Prickly Pear Fruit", carbs:2, protein:1, fat:1, vitamins:4, cal:190, tier:"gatherer", biomes:["desert"] },
{ name: "Phad Thai", carbs:9, protein:11, fat:19, vitamins:5, cal:1200, tier:"advanced", biomes:["any"] },
{ name: "Camas Bulb", carbs:1, protein:2, fat:5, vitamins:0, cal:150, tier:"gatherer", biomes:["grassland"] },
{ name: "Topped Porridge", carbs:10, protein:4, fat:0, vitamins:10, cal:700, tier:"cooked", biomes:["any"] },
{ name: "Dried Meat", carbs:1, protein:14, fat:4, vitamins:0, cal:550, tier:"campfire", biomes:["any"] },
{ name: "Tomato", carbs:5, protein:1, fat:0, vitamins:2, cal:240, tier:"gatherer", biomes:["grassland"] },
{ name: "Campfire Stew", carbs:5, protein:10, fat:9, vitamins:4, cal:1200, tier:"campfire", biomes:["any"] },
{ name: "Taro Fries", carbs:10, protein:2, fat:20, vitamins:0, cal:600, tier:"cooked", biomes:["rainforest"] },
{ name: "Tallow", carbs:0, protein:0, fat:8, vitamins:0, cal:200, tier:"starter", biomes:["any"] },
{ name: "Sweet Salad", carbs:18, protein:9, fat:7, vitamins:22, cal:1200, tier:"advanced", biomes:["any"] },
{ name: "Raw Fish", carbs:0, protein:7, fat:3, vitamins:0, cal:200, tier:"gatherer", biomes:["aquatic"] },
{ name: "Sweet Deer Jerky", carbs:4, protein:22, fat:6, vitamins:3, cal:600, tier:"campfire", biomes:["forest"] },
{ name: "Beet Greens", carbs:3, protein:1, fat:0, vitamins:4, cal:100, tier:"gatherer", biomes:["grassland"] },
{ name: "Sun Cheese", carbs:2, protein:4, fat:12, vitamins:0, cal:250, tier:"advanced", biomes:["any"] },
{ name: "Worldly Donut", carbs:15, protein:2, fat:17, vitamins:2, cal:750, tier:"baked", biomes:["any"] },
{ name: "Stuffed Turkey", carbs:17, protein:24, fat:16, vitamins:7, cal:1600, tier:"advanced", biomes:["forest"] },
{ name: "Spiky Roll", carbs:20, protein:17, fat:7, vitamins:2, cal:1300, tier:"advanced", biomes:["desert"] },
{ name: "Baked Corn", carbs:12, protein:3, fat:2, vitamins:11, cal:700, tier:"baked", biomes:["grassland"] },
{ name: "Jungle Campfire Salad", carbs:11, protein:4, fat:3, vitamins:10, cal:900, tier:"campfire", biomes:["rainforest"] },
{ name: "Simmered Meat", carbs:6, protein:18, fat:13, vitamins:5, cal:900, tier:"cooked", biomes:["any"] },
{ name: "Beet Campfire Salad", carbs:8, protein:4, fat:3, vitamins:13, cal:900, tier:"campfire", biomes:["grassland"] },
{ name: "Sensuous Sea Pizza", carbs:28, protein:11, fat:7, vitamins:4, cal:1200, tier:"advanced", biomes:["aquatic"] },
{ name: "Seeded Camas Roll", carbs:20, protein:2, fat:13, vitamins:16, cal:1400, tier:"baked", biomes:["grassland"] },
{ name: "Beet", carbs:2, protein:0, fat:2, vitamins:4, cal:230, tier:"gatherer", biomes:["grassland"] },
{ name: "Meaty Stew", carbs:6, protein:13, fat:10, vitamins:1, cal:1100, tier:"cooked", biomes:["any"] },
{ name: "Roast Pumpkin", carbs:23, protein:2, fat:2, vitamins:7, cal:1400, tier:"baked", biomes:["grassland"] },
{ name: "Fried Hare Haunches", carbs:6, protein:15, fat:27, vitamins:4, cal:750, tier:"cooked", biomes:["forest"] },
{ name: "Tortilla", carbs:20, protein:10, fat:0, vitamins:0, cal:350, tier:"baked", biomes:["any"] },
{ name: "Dried Fish", carbs:1, protein:16, fat:2, vitamins:0, cal:450, tier:"campfire", biomes:["aquatic"] },
{ name: "Charred Beans", carbs:1, protein:8, fat:3, vitamins:0, cal:350, tier:"campfire", biomes:["any"] },
{ name: "Kelpy Crab Roll", carbs:22, protein:13, fat:11, vitamins:5, cal:1350, tier:"advanced", biomes:["aquatic"] },
{ name: "Rice", carbs:7, protein:1, fat:0, vitamins:0, cal:150, tier:"gatherer", biomes:["any"] },
{ name: "Charred Beet", carbs:3, protein:0, fat:3, vitamins:6, cal:350, tier:"campfire", biomes:["grassland"] },
{ name: "Pumpkin", carbs:5, protein:1, fat:0, vitamins:2, cal:340, tier:"gatherer", biomes:["grassland"] },
{ name: "Milk", carbs:3, protein:10, fat:7, vitamins:0, cal:120, tier:"gatherer", biomes:["any"] },
{ name: "Fish N Chips", carbs:20, protein:10, fat:20, vitamins:0, cal:1000, tier:"cooked", biomes:["aquatic"] },
{ name: "Raw Meat", carbs:0, protein:4, fat:8, vitamins:0, cal:250, tier:"gatherer", biomes:["any"] },
{ name: "Agouti Enchiladas", carbs:20, protein:8, fat:27, vitamins:3, cal:800, tier:"advanced", biomes:["rainforest"] },
{ name: "Baked Taro", carbs:8, protein:6, fat:2, vitamins:12, cal:700, tier:"baked", biomes:["rainforest"] },
{ name: "Campfire Roast", carbs:0, protein:16, fat:12, vitamins:0, cal:1000, tier:"campfire", biomes:["any"] },
{ name: "Boiled Sausage", carbs:0, protein:27, fat:22, vitamins:0, cal:600, tier:"cooked", biomes:["any"] },
{ name: "Mochi", carbs:25, protein:0, fat:0, vitamins:5, cal:750, tier:"baked", biomes:["any"] },
{ name: "Root Campfire Stew", carbs:8, protein:5, fat:12, vitamins:5, cal:1100, tier:"campfire", biomes:["any"] },
{ name: "Macarons", carbs:20, protein:7, fat:14, vitamins:16, cal:1000, tier:"advanced", biomes:["any"] },
{ name: "Fruit Salad", carbs:12, protein:4, fat:3, vitamins:19, cal:900, tier:"starter", biomes:["any"] },
{ name: "Flatbread", carbs:17, protein:8, fat:3, vitamins:2, cal:500, tier:"baked", biomes:["any"] },
{ name: "Charred Fish", carbs:0, protein:11, fat:4, vitamins:0, cal:400, tier:"campfire", biomes:["aquatic"] },
{ name: "Poke Bowl", carbs:21, protein:10, fat:11, vitamins:7, cal:1100, tier:"advanced", biomes:["aquatic"] },
{ name: "Crispy Bacon", carbs:0, protein:18, fat:26, vitamins:0, cal:800, tier:"cooked", biomes:["any"] },
{ name: "Corn", carbs:4, protein:1, fat:0, vitamins:3, cal:230, tier:"gatherer", biomes:["grassland"] },
{ name: "Millionaires Salad", carbs:18, protein:6, fat:6, vitamins:26, cal:1000, tier:"advanced", biomes:["any"] },
{ name: "Banh Xeo", carbs:26, protein:17, fat:10, vitamins:4, cal:1550, tier:"advanced", biomes:["any"] },
{ name: "Charred Pineapple", carbs:8, protein:1, fat:0, vitamins:3, cal:350, tier:"campfire", biomes:["rainforest"] },
{ name: "Charred Mushrooms", carbs:3, protein:6, fat:2, vitamins:1, cal:350, tier:"campfire", biomes:["forest"] },
{ name: "Fern Campfire Salad", carbs:9, protein:5, fat:1, vitamins:13, cal:900, tier:"campfire", biomes:["forest"] },
{ name: "Boiled Grains", carbs:9, protein:2, fat:0, vitamins:1, cal:350, tier:"starter", biomes:["any"] },
{ name: "Baked Beet", carbs:10, protein:1, fat:2, vitamins:15, cal:700, tier:"baked", biomes:["grassland"] },
{ name: "Rice Noodles", carbs:10, protein:0, fat:0, vitamins:0, cal:200, tier:"starter", biomes:["any"] },
{ name: "Huckleberry Pie", carbs:13, protein:5, fat:10, vitamins:16, cal:1300, tier:"baked", biomes:["forest"] },
{ name: "Fruit Muffin", carbs:10, protein:5, fat:4, vitamins:16, cal:800, tier:"baked", biomes:["any"] }
];
// State
let enabledFoods = new Set(RAW_FOODS.map(f => f.name));
let currentPlanPool = [];
let currentPlanIndex = 0;
// ==================== UTILITIES ====================
function getFilter() {
const tier = document.getElementById('tier').value;
const disableTier = document.getElementById('disableTierFilter').checked;
const biome = document.getElementById('biomeFilter').value;
const disableBiome = document.getElementById('disableBiomeFilter').checked;
return (food) => {
if (!enabledFoods.has(food.name)) return false;
if (!disableTier && tier !== 'all' && food.tier !== tier) return false;
if (!disableBiome && biome !== 'all' && !food.biomes.includes(biome) && !food.biomes.includes('any')) return false;
return true;
};
}
function drawPieChart(canvasId, c, p, f, v) {
const canvas = document.getElementById(canvasId);
if (!canvas) return;
const ctx = canvas.getContext('2d');
const w = canvas.width;
const h = canvas.height;
ctx.clearRect(0, 0, w, h);
const total = c + p + f + v;
if (total === 0) {
ctx.fillStyle = '#cbd5e1';
ctx.beginPath();
ctx.arc(w/2, h/2, 100, 0, Math.PI*2);
ctx.fill();
ctx.fillStyle = '#64748b';
ctx.font = '20px Arial';
ctx.textAlign = 'center';
ctx.fillText("No Data", w/2, h/2 + 7);
return;
}
const vals = [c, p, f, v];
const colors = ["#ef4444", "#f97316", "#eab308", "#22c55e"];
let startAngle = -Math.PI / 2;
const cx = w/2, cy = h/2, r = 110;
vals.forEach((val, i) => {
if (val <= 0) return;
const sliceAngle = (val / total) * 2 * Math.PI;
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.arc(cx, cy, r, startAngle, startAngle + sliceAngle);
ctx.closePath();
ctx.fillStyle = colors[i];
ctx.fill();
startAngle += sliceAngle;
});
// Inner circle for donut effect
ctx.beginPath();
ctx.arc(cx, cy, r * 0.55, 0, 2 * Math.PI);
ctx.fillStyle = "#ffffff";
ctx.fill();
// Text in center
ctx.fillStyle = "#334155";
ctx.font = "bold 24px Segoe UI";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(total.toFixed(1), cx, cy);
}
// ==================== CORE ALGORITHM (The Balance Logic) ====================
function calculatePerfectBalance() {
// 1. Get Inputs
const c = parseFloat(document.getElementById('carbs').value) || 0;