<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
/* FIX: Ensure the root elements are set for responsive height */
body, html { height: 100%; margin: 0; padding: 0; }
/* FIX: Removed max-width restriction. Use width: 100% to fill the embed block. */
.stats-container {
padding: 10px;
width: 100%; /* Ensures it takes up the full width of the Google Sites embed element */
margin: auto;
font-family: sans-serif;
/* min-height: 100vh ensures the page is at least full height, minimizing external scrolling */
min-height: 100vh;
box-sizing: border-box;
}
#runner-search { width: 100%; padding: 10px; margin-bottom: 15px; border: 1px solid #ccc; border-radius: 8px; box-sizing: border-box; }
#search-results-list { list-style: none; padding: 0; margin: 0 0 20px 0; border: 1px solid #eee; border-radius: 8px; max-height: 250px; overflow-y: auto; }
#search-results-list li { padding: 10px; cursor: pointer; border-bottom: 1px solid #eee; }
#search-results-list li:last-child { border-bottom: none; }
#search-results-list li:hover { background-color: #f5f5f5; }
#runner-profile { padding: 20px; border: 2px solid #007bff; border-radius: 12px; background-color: #f9f9ff; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); }
.metric-value { font-size: 2em; font-weight: bold; color: #007bff; display: block; margin: 5px 0 15px 0; }
.gap-metric { padding: 12px; margin-top: 15px; border-radius: 8px; font-weight: bold; }
.gap-ahead { background-color: #d4edda; color: #155724; }
.gap-behind { background-color: #f8d7da; color: #721c24; }
.chart-container { padding: 15px; background: white; border-radius: 8px; height: 300px; position: relative; }
</style>
<div class="stats-container">
<div id="runner-app-container">
<p id="loading-message">Loading data... Please wait a moment.</p>
</div>
</div>
<script>
// --- Configuration ---
const CSV_URL = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vTyuiKwOaG-FhTHE03NfRN2wnURSt5RUxIQhNzcP71iKwjJAKb_8cELc0TIteDKoyMIQqYzMTnGJ02n/pub?gid=1534010301&single=true&output=tsv';
const GENDER_COLUMN = 'Gender';
const NAME_COLUMN = 'Name';
const MILEAGE_COLUMN = 'Total Miles Run';
const OVERALL_RANK_COLUMN = 'Overall Rank';
const GENDER_RANK_COLUMN = 'Gender Rank';
const DISTANCE_COLUMNS = ['50k', '50 Mile', '100k', '100 Mile', '150 Mile'];
let allRunners = [];
let raceChart;
function setupHTML() {
const container = document.getElementById('runner-app-container');
if (!container) return;
container.innerHTML = `
<div class="app-content">
<h1>THZ Runner Stats Lookup 🏃♀️💨</h1>
<input type="text" id="runner-search" placeholder="Start typing first or last name..." onkeyup="filterRunners()">
<ul id="search-results-list"></ul>
<div id="runner-profile" style="display: none;">
<h2 id="profile-name"></h2>
<h3>Your Current Achievements</h3>
<p>Total Lifetime Mileage:</p>
<span id="total-miles" class="metric-value"></span>
<p>Overall Mileage Rank: <strong id="overall-rank"></strong></p>
<p>Gender-Specific Rank: <strong id="gender-rank"></strong></p>
<div id="gap-ahead" class="gap-metric gap-behind"></div>
<div id="gap-behind" class="gap-metric gap-ahead"></div>
<h3>Race Completions Breakdown:</h3>
<div class="chart-container">
<canvas id="raceChartCanvas"></canvas>
</div>
</div>
</div>
`;
const loadingMsg = document.getElementById('loading-message');
if (loadingMsg) loadingMsg.style.display = 'none';
}
function parseAndProcessData(tsv) {
const lines = tsv.split('\n').filter(line => line.trim() !== '');
if (lines.length < 2) return [];
const headers = lines[0].split('\t').map(header => header.trim().replace(/"/g, ''));
const data = [];
for (let i = 1; i < lines.length; i++) {
const values = lines[i].split('\t').map(v => v.trim().replace(/"/g, ''));
const runner = {};
headers.forEach((header, index) => {
runner[header] = values[index];
});
runner[MILEAGE_COLUMN] = parseFloat(runner[MILEAGE_COLUMN]) || 0;
runner[OVERALL_RANK_COLUMN] = parseInt(runner[OVERALL_RANK_COLUMN]) || 0;
runner[GENDER_RANK_COLUMN] = parseInt(runner[GENDER_RANK_COLUMN]) || 0;
if (runner[NAME_COLUMN]) {
const parts = runner[NAME_COLUMN].split(',');
if (parts.length === 2) {
runner.lastName = parts[0].trim();
runner.firstName = parts[1].trim();
runner.fullName = `${runner.firstName} ${runner.lastName}`;
} else {
runner.fullName = runner[NAME_COLUMN].replace(/"/g, '').trim();
runner.firstName = runner.fullName.split(' ')[0];
}
} else {
runner.fullName = "Unknown Runner";
runner.firstName = "Unknown";
}
data.push(runner);
}
data.sort((a, b) => b[MILEAGE_COLUMN] - a[MILEAGE_COLUMN]);
return data;
}
async function initApp() {
try {
const response = await fetch(CSV_URL);
const tsvText = await response.text();
allRunners = parseAndProcessData(tsvText);
setupHTML();
} catch (error) {
console.error("Error loading data:", error);
const loadingMsg = document.getElementById('loading-message');
if (loadingMsg) loadingMsg.innerText = 'Error loading data. Check console for details.';
}
}
window.filterRunners = function() {
const searchInput = document.getElementById('runner-search').value.toLowerCase();
const resultsList = document.getElementById('search-results-list');
const profileDiv = document.getElementById('runner-profile');
if (!resultsList || !profileDiv) return;
profileDiv.style.display