{"version":3,"file":"main.a46e44a53014a7e23bdb.js","mappings":"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","sources":["webpack://leaguelooper/./web/static/js/modules/utils.js","webpack://leaguelooper/./web/static/js/modules/filters.js","webpack://leaguelooper/./web/static/js/modules/nearbyTeams.js","webpack://leaguelooper/./web/static/js/modules/travelSettings.js","webpack://leaguelooper/./web/static/js/modules/resultsViewer.js","webpack://leaguelooper/./web/static/js/main.js"],"sourcesContent":["// utils.js - Utility functions that can be used across modules\n\n/**\n * Helper function to create elements with attributes and properties\n * @param {string} tag - The HTML tag name\n * @param {Object} attributes - Key-value pairs of attributes to set\n * @param {string|Node} content - Text content or child node to append\n * @returns {HTMLElement} The created element\n */\nexport function createElement(tag, attributes = {}, content = '') {\n const element = document.createElement(tag);\n \n // Set attributes\n Object.entries(attributes).forEach(([key, value]) => {\n if (key === 'className') {\n element.className = value;\n } else if (key === 'innerHTML') {\n element.innerHTML = value;\n } else if (key === 'textContent') {\n element.textContent = value;\n } else if (key.startsWith('on') && typeof value === 'function') {\n // Event listeners\n const eventName = key.substring(2).toLowerCase();\n element.addEventListener(eventName, value);\n } else {\n element.setAttribute(key, value);\n }\n });\n \n // Add content\n if (content) {\n if (typeof content === 'string') {\n element.textContent = content;\n } else {\n element.appendChild(content);\n }\n }\n \n return element;\n}\n\n/**\n * Format a date as a string\n * @param {Date} date - The date to format\n * @param {string} format - Optional format string\n * @returns {string} Formatted date string\n */\nexport function formatDateString(date, format = 'MM/DD/YYYY') {\n if (!(date instanceof Date)) {\n date = new Date(date);\n }\n \n const day = String(date.getDate()).padStart(2, '0');\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const year = date.getFullYear();\n \n return format\n .replace('DD', day)\n .replace('MM', month)\n .replace('YYYY', year);\n}\n\n/**\n * Format currency number as string\n * @param {number} amount - The amount to format\n * @param {string} currency - The currency symbol\n * @returns {string} Formatted currency string\n */\nexport function formatCurrency(amount, currency = '$') {\n return `${currency}${parseFloat(amount).toFixed(2)}`;\n}\n\n/**\n * Debounce function to limit how often a function can be called\n * @param {Function} func - The function to debounce\n * @param {number} wait - The debounce wait time in milliseconds\n * @returns {Function} Debounced function\n */\nexport function debounce(func, wait = 300) {\n let timeout;\n return function(...args) {\n clearTimeout(timeout);\n timeout = setTimeout(() => func.apply(this, args), wait);\n };\n}","// filters.js - Handle form filters like blackout dates and day selection\nimport { createElement } from './utils.js';\n\nlet blackoutDateCounter = 0;\n\nexport function initFilters() {\n console.log('Initializing filters module...');\n\n const filtersForm = document.getElementById('filters-form');\n \n // Cache DOM elements\n const leagueSelect = document.getElementById('league-select');\n const blackoutDatesContainer = document.getElementById('blackout-dates-container');\n const addBlackoutDateBtn = document.getElementById('add-blackout-date');\n const addBlackoutRangeBtn = document.getElementById('add-blackout-range');\n \n // Templates\n const blackoutDateTemplate = document.getElementById('blackout-date-template');\n const blackoutRangeTemplate = document.getElementById('blackout-range-template');\n\n // Add this to your filters.js module\n const logoDisplay = document.getElementById('selected-league-logo');\n\n if (leagueSelect && logoDisplay) {\n leagueSelect.addEventListener('change', function() {\n const selectedOption = this.options[this.selectedIndex];\n const logoUrl = selectedOption.getAttribute('data-logo');\n \n if (logoUrl) {\n logoDisplay.innerHTML = `\"League`;\n logoDisplay.style.display = 'block';\n } else {\n logoDisplay.innerHTML = '';\n logoDisplay.style.display = 'none';\n }\n });\n }\n \n // Initial setup for league select\n if (leagueSelect) {\n leagueSelect.addEventListener('change', function() {\n const leagueId = this.value;\n if (!leagueId) {\n // No league selected\n const nearbyTeamsContainer = document.getElementById('nearby-teams-container');\n \n // Use createElement utility instead of direct DOM manipulation\n nearbyTeamsContainer.innerHTML = '';\n const message = createElement('p', { \n id: 'no-teams-message',\n textContent: 'Please select a league to see available teams'\n });\n nearbyTeamsContainer.appendChild(message);\n }\n // The real work happens in the htmx:afterSwap event handler\n });\n }\n\n // Add single blackout date\n if (addBlackoutDateBtn) {\n addBlackoutDateBtn.addEventListener('click', function() {\n addBlackoutDate(blackoutDateTemplate, blackoutDatesContainer);\n });\n }\n\n // Add blackout date range\n if (addBlackoutRangeBtn) {\n addBlackoutRangeBtn.addEventListener('click', function() {\n addBlackoutRange(blackoutRangeTemplate, blackoutDatesContainer);\n });\n }\n\n if (filtersForm) {\n filtersForm.addEventListener('submit', function(e) {\n // Find all blackout date inputs\n const blackoutDateInputs = document.querySelectorAll('input[name^=\"blackout_dates\"]');\n \n // Check each input and remove it if it's empty\n blackoutDateInputs.forEach(input => {\n if (!input.value) {\n input.closest('.blackout-date, .blackout-range').remove();\n }\n });\n \n // Do the same for nearby teams selects\n const nearbyTeamSelects = document.querySelectorAll('select[name^=\"nearby_teams\"]');\n nearbyTeamSelects.forEach(select => {\n if (!select.value) {\n // Find the parent pair container and remove it\n const pairContainer = select.closest('.nearby-teams-pair');\n if (pairContainer) {\n pairContainer.remove();\n }\n }\n });\n });\n }\n\n initLoadingExperience();\n \n console.log('Filters module initialized.');\n}\n\n// Add this new function to your file\nfunction initLoadingExperience() {\n // Find the filters form and loading indicator\n const filtersForm = document.getElementById('filters-form');\n const loadingIndicator = document.getElementById('loading');\n const resultsContainer = document.getElementById('results-container');\n \n if (filtersForm) {\n // Track the state of the request\n let requestStartTime;\n let timeUpdateInterval;\n let requestInProgress = false;\n \n // Update the loading message with elapsed time\n function updateLoadingMessage() {\n const elapsedSeconds = Math.floor((Date.now() - requestStartTime) / 1000);\n const minutes = Math.floor(elapsedSeconds / 60);\n const seconds = elapsedSeconds % 60;\n \n const timeDisplay = `${minutes}:${seconds.toString().padStart(2, '0')}`;\n const loadingText = document.querySelector('#loading p');\n \n if (loadingText) {\n if (elapsedSeconds < 10) {\n loadingText.textContent = 'Generating schedules...';\n } else if (elapsedSeconds < 30) {\n loadingText.textContent = `Generating schedules... (${timeDisplay})`;\n } else {\n loadingText.textContent = `Still working on it... (${timeDisplay})\\nComplex scheduling may take a few minutes.`;\n }\n }\n }\n \n // Listen for the htmx:beforeSend event\n filtersForm.addEventListener('htmx:beforeSend', function(event) {\n // Save the start time\n requestStartTime = Date.now();\n requestInProgress = true;\n \n // Clear any previous content in the results container\n if (resultsContainer) {\n resultsContainer.innerHTML = '';\n }\n \n // Set up the interval to update the loading message\n timeUpdateInterval = setInterval(updateLoadingMessage, 1000);\n });\n \n // Listen for the htmx:afterSwap event\n filtersForm.addEventListener('htmx:afterSwap', function(event) {\n // Request completed successfully\n requestInProgress = false;\n clearInterval(timeUpdateInterval);\n });\n \n // Listen for the htmx:responseError event\n filtersForm.addEventListener('htmx:responseError', function(event) {\n requestInProgress = false;\n clearInterval(timeUpdateInterval);\n \n // Explicitly hide the loading indicator\n if (loadingIndicator) {\n loadingIndicator.style.display = 'none';\n loadingIndicator.classList.add('htmx-error');\n }\n \n // Handle error response\n const errorMessage = event.detail.xhr.responseText || 'An error occurred while generating schedules.';\n \n // Create a formatted error message\n resultsContainer.innerHTML = `\n
\n

Error Generating Schedules

\n

${errorMessage}

\n

Try simplifying your constraints or try again later.

\n \n
\n `;\n });\n \n // Handle network timeouts and other connection errors\n filtersForm.addEventListener('htmx:timeout', function(event) {\n requestInProgress = false;\n clearInterval(timeUpdateInterval);\n \n // Explicitly hide the loading indicator\n if (loadingIndicator) {\n loadingIndicator.style.display = 'none';\n }\n \n resultsContainer.innerHTML = `\n
\n

Request Timeout

\n

The schedule generation is taking longer than expected.

\n

You can try again with simpler constraints.

\n \n
\n `;\n });\n\n // General error handler\n window.addEventListener('error', function(event) {\n if (requestInProgress) {\n requestInProgress = false;\n clearInterval(timeUpdateInterval);\n \n // Explicitly hide the loading indicator\n if (loadingIndicator) {\n loadingIndicator.style.display = 'none';\n }\n \n resultsContainer.innerHTML = `\n
\n

An Error Occurred

\n

Something went wrong while generating your schedule.

\n

Please try again with simpler constraints.

\n \n
\n `;\n }\n });\n }\n}\n\n// Function to add a single blackout date\nfunction addBlackoutDate(blackoutDateTemplate, blackoutDatesContainer) {\n const clone = document.importNode(blackoutDateTemplate.content, true);\n \n // Update the index in the input name\n const input = clone.querySelector('input');\n input.name = input.name.replace('INDEX', blackoutDateCounter);\n \n // Add remove button functionality\n const removeButton = clone.querySelector('.remove-button');\n removeButton.addEventListener('click', function() {\n this.closest('.blackout-date').remove();\n });\n \n blackoutDatesContainer.appendChild(clone);\n blackoutDateCounter++;\n}\n\n// Function to add a blackout date range\nfunction addBlackoutRange(blackoutRangeTemplate, blackoutDatesContainer) {\n const clone = document.importNode(blackoutRangeTemplate.content, true);\n \n // Update the indices in the input names\n const inputs = clone.querySelectorAll('input');\n inputs.forEach(input => {\n input.name = input.name.replace('INDEX', blackoutDateCounter);\n });\n \n // Add remove button functionality\n const removeButton = clone.querySelector('.remove-button');\n removeButton.addEventListener('click', function() {\n this.closest('.blackout-range').remove();\n });\n \n blackoutDatesContainer.appendChild(clone);\n blackoutDateCounter++;\n}\n\n","// nearbyTeams.js - Handle nearby teams management\nimport { createElement } from './utils.js';\n\nlet nearbyTeamsCounter = 0;\n\nexport function initNearbyTeams() {\n console.log('Initializing nearby teams module...');\n \n // Cache DOM elements\n const addNearbyTeamsBtn = document.getElementById('add-nearby-teams');\n const autoDetectCheckbox = document.getElementById('auto-detect-nearby');\n \n // Toggle nearby teams visibility based on auto-detect\n if (autoDetectCheckbox) {\n autoDetectCheckbox.addEventListener('change', function() {\n const nearbyTeamsContainer = document.getElementById('nearby-teams-container');\n \n if (this.checked) {\n // Auto-detect enabled\n if (addNearbyTeamsBtn) {\n addNearbyTeamsBtn.textContent = \"Add Additional Nearby Teams\";\n }\n // Show a message about auto-detection\n if (nearbyTeamsContainer) {\n const message = createElement('p', {\n className: 'auto-detect-message',\n textContent: 'Teams will be automatically grouped based on geographic proximity.'\n });\n \n // Remove old message if it exists\n const oldMessage = nearbyTeamsContainer.querySelector('.auto-detect-message');\n if (oldMessage) {\n oldMessage.remove();\n }\n \n nearbyTeamsContainer.insertBefore(message, nearbyTeamsContainer.firstChild);\n }\n } else {\n // Auto-detect disabled\n if (addNearbyTeamsBtn) {\n addNearbyTeamsBtn.textContent = \"Add Nearby Teams\";\n }\n // Remove auto-detect message\n if (nearbyTeamsContainer) {\n const message = nearbyTeamsContainer.querySelector('.auto-detect-message');\n if (message) {\n message.remove();\n }\n }\n }\n });\n \n // Trigger the change event to initialize the UI\n autoDetectCheckbox.dispatchEvent(new Event('change'));\n }\n \n // Add handler for add nearby teams button\n if (addNearbyTeamsBtn) {\n addNearbyTeamsBtn.addEventListener('click', function() {\n const editContainer = document.getElementById('nearby-teams-edit');\n const nearbyTeamsTemplate = document.getElementById('nearby-teams-template');\n \n // Get the template from the response\n const teamPairTemplate = nearbyTeamsTemplate.querySelector('.nearby-teams-pair');\n \n if (!teamPairTemplate) {\n console.error(\"Could not find team pair template\");\n return;\n }\n \n // Get the current number of pairs\n const currentPairs = editContainer ? editContainer.querySelectorAll('.nearby-teams-pair').length : 0;\n \n // Clone the template\n const newPair = teamPairTemplate.cloneNode(true);\n \n // Update the indices\n const selects = newPair.querySelectorAll('select');\n selects.forEach(select => {\n select.name = select.name.replace('INDEX', currentPairs);\n select.value = \"\"; // Clear selection\n });\n \n // Add remove button functionality\n const removeButton = newPair.querySelector('.remove-button');\n if (removeButton) {\n removeButton.addEventListener('click', function() {\n newPair.remove();\n });\n }\n \n // Add to the container\n if (editContainer) {\n editContainer.appendChild(newPair);\n } else {\n const nearbyTeamsContainer = document.getElementById('nearby-teams-container');\n if (nearbyTeamsContainer) {\n // Create an edit container if it doesn't exist\n const newEditContainer = createElement('div', {\n id: 'nearby-teams-edit',\n className: 'nearby-teams-edit'\n });\n \n nearbyTeamsContainer.appendChild(newEditContainer);\n newEditContainer.appendChild(newPair);\n }\n }\n });\n }\n \n console.log('Nearby teams module initialized.');\n}\n\n// Function to display predefined teams in read-only view\nexport function displayPredefinedTeams() {\n console.log(\"Displaying predefined teams\");\n \n const nearbyTeamsContainer = document.getElementById('nearby-teams-container');\n const addNearbyTeamsBtn = document.getElementById('add-nearby-teams');\n const autoDetectCheckbox = document.getElementById('auto-detect-nearby');\n \n // Early exit if container not found\n if (!nearbyTeamsContainer) {\n console.error(\"Nearby teams container not found\");\n return;\n }\n \n // Remove no-teams message if it exists\n const noTeamsMessage = document.getElementById('no-teams-message');\n if (noTeamsMessage) {\n noTeamsMessage.remove();\n }\n \n // Clear the container except for the auto-detect message\n const autoDetectMessage = nearbyTeamsContainer.querySelector('.auto-detect-message');\n nearbyTeamsContainer.innerHTML = '';\n if (autoDetectMessage) {\n nearbyTeamsContainer.appendChild(autoDetectMessage);\n }\n \n const leagueSelect = document.getElementById('league-select');\n const leagueId = leagueSelect ? leagueSelect.value : null;\n \n if (!leagueId) {\n // No league selected\n const message = createElement('p', {\n id: 'no-teams-message',\n textContent: 'Please select a league to see available teams'\n });\n nearbyTeamsContainer.appendChild(message);\n return;\n }\n \n // Get the hidden data from the DOM\n const hiddenDataDiv = document.getElementById('predefined-nearby-teams-data');\n if (!hiddenDataDiv) {\n console.error(\"Couldn't find predefined nearby teams data\");\n return;\n }\n \n // Parse the predefined teams data\n const rawData = hiddenDataDiv.getAttribute('data-nearby-teams');\n const predefinedTeams = parseNearbyTeamsData(rawData);\n console.log(\"Parsed predefined teams:\", predefinedTeams);\n \n // Check if auto-detect is enabled\n const isAutoDetectEnabled = autoDetectCheckbox && autoDetectCheckbox.checked;\n \n if (predefinedTeams.length === 0 && !isAutoDetectEnabled) {\n // If no predefined teams and auto-detect is disabled\n const message = createElement('p', {\n textContent: 'No predefined nearby teams for this league. Add teams manually or enable auto-detection.'\n });\n nearbyTeamsContainer.appendChild(message);\n } else if (predefinedTeams.length > 0) {\n // Display predefined teams\n const viewContainer = createElement('div', {\n className: 'nearby-teams-view',\n id: 'nearby-teams-view'\n });\n \n // Add the predefined teams to the view container\n predefinedTeams.forEach((team, index) => {\n // Create hidden inputs for form submission\n const hiddenInput1 = createElement('input', {\n type: 'hidden',\n name: `nearby_teams[${index}][0]`,\n value: team.team1_id\n });\n \n const hiddenInput2 = createElement('input', {\n type: 'hidden',\n name: `nearby_teams[${index}][1]`,\n value: team.team2_id\n });\n \n // Create description text\n const descText = createElement('span', {\n textContent: team.description\n });\n \n // Create the team item\n const teamItem = createElement('div', {\n className: 'nearby-teams-item'\n });\n \n teamItem.appendChild(hiddenInput1);\n teamItem.appendChild(hiddenInput2);\n teamItem.appendChild(descText);\n viewContainer.appendChild(teamItem);\n });\n \n // Create edit button (only show if auto-detect is disabled)\n if (!isAutoDetectEnabled) {\n const editButton = createElement('button', {\n type: 'button',\n className: 'edit-nearby-teams-btn',\n textContent: 'Customize Nearby Teams',\n onclick: function() {\n switchToEditMode(predefinedTeams);\n }\n });\n nearbyTeamsContainer.appendChild(editButton);\n }\n \n // Add the view container\n nearbyTeamsContainer.appendChild(viewContainer);\n \n // Create edit container (initially hidden)\n const editContainer = createElement('div', {\n className: 'nearby-teams-edit hidden',\n id: 'nearby-teams-edit'\n });\n nearbyTeamsContainer.appendChild(editContainer);\n }\n \n // Update the add button text based on auto-detect\n if (addNearbyTeamsBtn) {\n if (isAutoDetectEnabled) {\n addNearbyTeamsBtn.textContent = \"Add Additional Nearby Teams\";\n addNearbyTeamsBtn.style.display = 'block';\n } else if (predefinedTeams.length > 0) {\n addNearbyTeamsBtn.textContent = \"Add Nearby Teams\";\n addNearbyTeamsBtn.style.display = 'none'; // Hide initially when showing predefined teams\n } else {\n addNearbyTeamsBtn.textContent = \"Add Nearby Teams\";\n addNearbyTeamsBtn.style.display = 'block';\n }\n }\n}\n\n// Function to parse the nearby teams data from the data attribute\nfunction parseNearbyTeamsData(rawData) {\n const teams = [];\n \n if (rawData && rawData.trim() !== '') {\n // Split by the separator ||| to get each team pair\n const pairs = rawData.split('|||');\n \n pairs.forEach(pair => {\n // Split each pair by :: to get team1ID, team2ID, and description\n const parts = pair.trim().split('::');\n if (parts.length === 3) {\n teams.push({\n team1_id: parts[0],\n team2_id: parts[1],\n description: parts[2]\n });\n }\n });\n }\n \n return teams;\n}\n\n// Function to switch to edit mode\nfunction switchToEditMode(predefinedTeams) {\n console.log(\"Switching to edit mode with\", predefinedTeams.length, \"predefined teams\");\n \n // Get the containers\n const viewContainer = document.getElementById('nearby-teams-view');\n const editButton = document.querySelector('.edit-nearby-teams-btn');\n const editContainer = document.getElementById('nearby-teams-edit');\n const addNearbyTeamsBtn = document.getElementById('add-nearby-teams');\n const nearbyTeamsTemplate = document.getElementById('nearby-teams-template');\n \n if (!viewContainer || !editButton || !editContainer) {\n console.error(\"Missing required elements\");\n return;\n }\n \n // Hide view container and edit button\n viewContainer.classList.add('hidden');\n editButton.classList.add('hidden');\n \n // Show edit container\n editContainer.classList.remove('hidden');\n \n // Clear existing content in edit container\n editContainer.innerHTML = '';\n \n // Create cancel button using createElement utility\n const cancelButton = createElement('button', {\n type: 'button',\n className: 'cancel-nearby-teams-btn',\n textContent: 'Cancel Nearby Changes',\n onclick: function() {\n switchToViewMode();\n }\n });\n \n const buttonContainer = createElement('div', {\n className: 'nearby-teams-buttons'\n });\n \n buttonContainer.appendChild(cancelButton);\n editContainer.appendChild(buttonContainer);\n \n // Get the template for the team pairs\n const teamPairTemplate = nearbyTeamsTemplate.querySelector('.nearby-teams-pair');\n \n if (!teamPairTemplate) {\n console.error(\"Could not find team pair template in response target\");\n return;\n }\n \n console.log(\"Creating editable team pairs using template:\", teamPairTemplate);\n \n // Add a pair row for each predefined team\n predefinedTeams.forEach((team, index) => {\n // Clone the template\n const teamPairElement = teamPairTemplate.cloneNode(true);\n teamPairElement.style.display = 'flex'; // Make sure it's visible\n \n // Update the names to use the correct index\n const selects = teamPairElement.querySelectorAll('select');\n selects.forEach(select => {\n select.name = select.name.replace('INDEX', index);\n });\n \n // Set the selected values in the dropdowns\n if (selects.length >= 2) {\n // Get references to the team select elements\n const team1Select = selects[0];\n const team2Select = selects[1];\n \n // Try to select the teams - make sure we're comparing the same types\n // The data from the attribute comes as strings, so ensure proper comparison\n let team1Found = false;\n let team2Found = false;\n \n // Find and select team 1\n for (let i = 0; i < team1Select.options.length; i++) {\n if (team1Select.options[i].value === team.team1_id) {\n team1Select.selectedIndex = i;\n team1Found = true;\n break;\n }\n }\n \n // Find and select team 2\n for (let i = 0; i < team2Select.options.length; i++) {\n if (team2Select.options[i].value === team.team2_id) {\n team2Select.selectedIndex = i;\n team2Found = true;\n break;\n }\n }\n \n console.log(`Team pair ${index}: ${team.team1_id} (found: ${team1Found}) & ${team.team2_id} (found: ${team2Found})`);\n \n if (!team1Found || !team2Found) {\n console.warn(`Couldn't find options for team1_id=${team.team1_id} or team2_id=${team.team2_id}`);\n }\n } else {\n console.error(\"Missing select elements in template\");\n }\n \n // Add remove button functionality\n const removeButton = teamPairElement.querySelector('.remove-button');\n if (removeButton) {\n removeButton.addEventListener('click', function() {\n teamPairElement.remove();\n });\n }\n \n // Add to the edit container\n editContainer.appendChild(teamPairElement);\n });\n \n // Show the add button\n if (addNearbyTeamsBtn) {\n addNearbyTeamsBtn.disabled = false;\n addNearbyTeamsBtn.style.display = 'block';\n }\n}\n\n// Function to switch back to view mode\nfunction switchToViewMode() {\n console.log(\"Switching back to view mode\");\n \n // Get the containers\n const viewContainer = document.getElementById('nearby-teams-view');\n const editButton = document.querySelector('.edit-nearby-teams-btn');\n const editContainer = document.getElementById('nearby-teams-edit');\n const addNearbyTeamsBtn = document.getElementById('add-nearby-teams');\n \n if (!viewContainer || !editButton || !editContainer) {\n console.error(\"Missing required elements\");\n return;\n }\n \n // Hide edit container\n editContainer.classList.add('hidden');\n \n // Show view container and edit button\n viewContainer.classList.remove('hidden');\n editButton.classList.remove('hidden');\n \n // Hide the add button\n if (addNearbyTeamsBtn) {\n addNearbyTeamsBtn.style.display = 'none';\n }\n}","// travelSettings.js - Handle travel settings including costs and airport selection\nimport { formatCurrency, debounce } from './utils.js';\n\nexport function initTravelSettings() {\n console.log('Initializing travel settings module...');\n \n // Cache DOM elements\n const homeAirportSelect = document.getElementById('home-airport-select');\n const flightCostInput = document.getElementById('flight-cost');\n const hotelCostInput = document.getElementById('hotel-cost');\n const toggleTravelCostSettings = document.getElementById('toggle-travel-cost-settings');\n const travelCostSettings = document.getElementById('travel-cost-settings');\n const autoDetectCheckbox = document.getElementById('auto-detect-nearby');\n \n // Toggle travel cost settings\n if (toggleTravelCostSettings && travelCostSettings) {\n toggleTravelCostSettings.addEventListener('click', function(e) {\n e.preventDefault();\n if (travelCostSettings.classList.contains('hidden')) {\n travelCostSettings.classList.remove('hidden');\n toggleTravelCostSettings.textContent = 'Hide Cost Settings';\n } else {\n travelCostSettings.classList.add('hidden');\n toggleTravelCostSettings.textContent = 'Show Cost Settings';\n }\n });\n }\n \n // Format currency inputs\n if (flightCostInput && hotelCostInput) {\n [flightCostInput, hotelCostInput].forEach(input => {\n input.addEventListener('blur', function() {\n const value = parseFloat(this.value);\n if (!isNaN(value)) {\n // Use formatCurrency utility but remove the $ since the input doesn't need it\n this.value = formatCurrency(value, '').substring(1);\n }\n });\n \n // Add input event to recalculate travel estimate using debounce to avoid excessive calculations\n input.addEventListener('input', debounce(calculateTravelEstimate, 300));\n input.addEventListener('change', calculateTravelEstimate);\n });\n }\n \n // Update travel estimate when home airport changes\n if (homeAirportSelect) {\n homeAirportSelect.addEventListener('change', calculateTravelEstimate);\n }\n \n // Update travel estimate when auto-detect changes\n if (autoDetectCheckbox) {\n autoDetectCheckbox.addEventListener('change', calculateTravelEstimate);\n }\n \n // Calculate initial travel estimate\n calculateTravelEstimate();\n \n console.log('Travel settings module initialized.');\n}\n\n// Calculate travel estimate based on current filters\nexport function calculateTravelEstimate() {\n const flightCostInput = document.getElementById('flight-cost');\n const hotelCostInput = document.getElementById('hotel-cost');\n const autoDetectCheckbox = document.getElementById('auto-detect-nearby');\n \n if (!flightCostInput || !hotelCostInput) return;\n \n // Get values\n const flightCost = parseFloat(flightCostInput.value) || 300;\n const hotelCost = parseFloat(hotelCostInput.value) || 150;\n const autoDetectEnabled = autoDetectCheckbox ? autoDetectCheckbox.checked : false;\n \n // Get nearby teams (count both manual and predefined)\n const nearbyTeamsPairs = document.querySelectorAll('.nearby-teams-pair').length;\n const predefinedPairs = document.querySelectorAll('.nearby-teams-item').length;\n let totalNearbyPairs = nearbyTeamsPairs + predefinedPairs;\n \n // If auto-detect is enabled, estimate more nearby pairs\n if (autoDetectEnabled) {\n // Assume approximately 15% of teams are nearby in a league (educated guess)\n const teamOptions = document.querySelectorAll('#nearby-teams-template select:first-child option').length;\n if (teamOptions > 1) { // Account for the placeholder option\n const teamCount = teamOptions - 1;\n const estimatedAutoPairs = Math.ceil(teamCount * 0.15);\n totalNearbyPairs = Math.max(totalNearbyPairs, estimatedAutoPairs);\n } else {\n // Default if we can't determine the team count\n totalNearbyPairs = Math.max(totalNearbyPairs, 4);\n }\n }\n \n // Estimate team count\n const teamOptions = document.querySelectorAll('#nearby-teams-template select:first-child option').length;\n let totalTeams = teamOptions > 1 ? teamOptions - 1 : 30; // Default to 30 if we can't determine\n \n // Calculate estimated flights\n // Formula: One flight per team group (nearby teams count as one group)\n // Each nearby pair reduces flights by 1 (but we need at least 1 flight)\n const estimatedFlights = Math.max(1, totalTeams - totalNearbyPairs);\n \n // Calculate estimated hotel nights\n // Formula: 1-2 nights per flight depending on nearby team grouping\n const avgNightsPerFlight = totalNearbyPairs > 0 ? 2 : 1; // More nights if we have nearby teams to visit\n const estimatedHotelNights = estimatedFlights * avgNightsPerFlight;\n \n // Calculate total cost\n const estimatedCost = (estimatedFlights * flightCost) + (estimatedHotelNights * hotelCost);\n \n // Update the estimate display using formatCurrency utility\n const estimateElement = document.getElementById('travel-estimate');\n if (estimateElement) {\n const formattedCost = formatCurrency(estimatedCost);\n estimateElement.textContent = `Estimated Cost: ${formattedCost} (${estimatedFlights} flights, ${estimatedHotelNights} hotel nights)`;\n }\n}","// resultsCards.js - JS for results page with HTMX awareness\nexport function initResultsCards() {\n console.log('Initializing results cards...');\n \n // Get all schedule cards\n const cards = document.querySelectorAll('.schedule-card');\n console.log(`Found ${cards.length} schedule cards`);\n \n // Remove any existing click handlers first (in case of re-initialization)\n cards.forEach(card => {\n // Clone node to remove all event listeners\n const newCard = card.cloneNode(true);\n card.parentNode.replaceChild(newCard, card);\n });\n \n // Get fresh references after cloning\n const freshCards = document.querySelectorAll('.schedule-card');\n \n // Add click handler to each card\n freshCards.forEach(card => {\n card.addEventListener('click', function(event) {\n console.log('Card clicked');\n \n // Check if we're clicking on a link inside the card details\n const isLink = event.target.tagName === 'A';\n if (isLink) return;\n \n // Toggle expanded state\n this.classList.toggle('expanded');\n \n // Toggle details visibility\n const details = this.querySelector('.card-details');\n if (details) {\n details.classList.toggle('hidden');\n \n // If expanding, scroll to ensure the card is fully visible\n if (!details.classList.contains('hidden')) {\n setTimeout(() => {\n this.scrollIntoView({ \n behavior: 'smooth', \n block: 'nearest'\n });\n }, 10);\n }\n }\n });\n });\n}\n\n// Listen for HTMX events - this is the key to working with HTMX!\ndocument.body.addEventListener('htmx:afterSwap', function(event) {\n console.log('HTMX content swapped, checking for results...');\n \n // Check if the swapped content contains schedule cards\n if (document.querySelector('.schedules-list')) {\n console.log('Found results page content, initializing cards...');\n initResultsCards();\n }\n});\n\n// Regular DOM ready initialization as well (for non-HTMX loading)\ndocument.addEventListener('DOMContentLoaded', function() {\n // Only initialize if we're on the results page\n if (document.querySelector('.schedules-list')) {\n console.log('Page loaded normally with results, initializing cards...');\n initResultsCards();\n }\n});","// main.js - Main entry point for League Looper JavaScript\nimport { initFilters } from './modules/filters.js';\nimport { initNearbyTeams, displayPredefinedTeams } from './modules/nearbyTeams.js';\nimport { initTravelSettings } from './modules/travelSettings.js';\nimport { initResultsCards } from './modules/resultsViewer.js';\nimport { debounce } from './modules/utils.js';\nimport '../css/main.css';\n\ndocument.addEventListener('DOMContentLoaded', function() {\n console.log('League Looper JavaScript initializing...');\n \n // Initialize all modules\n initFilters();\n initNearbyTeams();\n initTravelSettings();\n if (document.querySelector('.schedules-list')) {\n initResultsCards();\n } else {\n console.log('Did not initialize Results Card module!');\n }\n \n // Listen for the htmx:afterSwap event (after HTMX updates the DOM)\n document.body.addEventListener('htmx:afterSwap', debounce(function(event) {\n // Only process if this was a teams endpoint response\n if (event.detail.requestConfig && \n event.detail.requestConfig.path === '/teams') {\n \n console.log(\"HTMX response received from /teams\");\n // After HTMX updates the DOM with the teams, process the nearby teams\n displayPredefinedTeams();\n\n if (document.querySelector('.schedules-list')) {\n initResultsCards();\n } else {\n console.log('Did not initialize Results Card module!');\n }\n }\n }, 100));\n \n console.log('League Looper JavaScript initialized successfully.');\n});"],"names":["createElement","tag","attributes","arguments","length","undefined","content","element","document","Object","entries","forEach","_ref","_ref2","_slicedToArray","key","value","className","innerHTML","textContent","startsWith","eventName","substring","toLowerCase","addEventListener","setAttribute","appendChild","formatCurrency","amount","concat","parseFloat","toFixed","debounce","func","timeout","wait","_this","_len","args","Array","_key","clearTimeout","setTimeout","apply","blackoutDateCounter","initFilters","console","log","filtersForm","getElementById","leagueSelect","blackoutDatesContainer","addBlackoutDateBtn","addBlackoutRangeBtn","blackoutDateTemplate","blackoutRangeTemplate","logoDisplay","logoUrl","this","options","selectedIndex","getAttribute","style","display","nearbyTeamsContainer","message","id","clone","importNode","input","querySelector","name","replace","closest","remove","addBlackoutDate","querySelectorAll","addBlackoutRange","e","select","pairContainer","loadingIndicator","resultsContainer","requestStartTime","timeUpdateInterval","updateLoadingMessage","elapsedSeconds","Math","floor","Date","now","minutes","seconds","timeDisplay","toString","padStart","loadingText","requestInProgress","event","setInterval","clearInterval","classList","add","errorMessage","detail","xhr","responseText","window","initLoadingExperience","displayPredefinedTeams","addNearbyTeamsBtn","autoDetectCheckbox","noTeamsMessage","autoDetectMessage","hiddenDataDiv","predefinedTeams","rawData","teams","trim","split","pair","parts","push","team1_id","team2_id","description","parseNearbyTeamsData","isAutoDetectEnabled","checked","viewContainer","team","index","hiddenInput1","type","hiddenInput2","descText","teamItem","editButton","onclick","editContainer","nearbyTeamsTemplate","error","cancelButton","switchToViewMode","buttonContainer","teamPairTemplate","teamPairElement","cloneNode","selects","team1Select","team2Select","team1Found","team2Found","i","warn","removeButton","disabled","switchToEditMode","calculateTravelEstimate","flightCostInput","hotelCostInput","flightCost","hotelCost","autoDetectEnabled","totalNearbyPairs","teamOptions","teamCount","estimatedAutoPairs","ceil","max","totalTeams","estimatedFlights","estimatedHotelNights","estimatedCost","estimateElement","formattedCost","initResultsCards","cards","card","newCard","parentNode","replaceChild","target","tagName","toggle","details","contains","scrollIntoView","behavior","block","body","oldMessage","insertBefore","firstChild","dispatchEvent","Event","currentPairs","newPair","newEditContainer","initNearbyTeams","homeAirportSelect","toggleTravelCostSettings","travelCostSettings","preventDefault","isNaN","initTravelSettings","requestConfig","path"],"sourceRoot":""}