'); paymentWindow.document.close(); } } catch (e) { console.warn('Failed to open payment window:', e); }bbShowLoading('Reserving slots with ranger...');const tourTypeMap = { 'private-town': 'private_town_tour', 'living-lake': 'living_at_the_lake', 'twilight': 'twilight_tour', 'large-group': 'large_group_tour', 'mines': 'mines_mills_tour' };const payload = { date: bbState.selectedDate, time: bbState.selectedTime, party_size: partySize, tour_type: tourTypeMap[tourKey] || 'large_group_tour', vehicle_acknowledgment: tourKey === 'mines' ? (document.getElementById('mines-vehicle-ack') ? document.getElementById('mines-vehicle-ack').checked : false) : false, guest: { name: name, email: email, phone: phone } };try { let csrfToken = ''; let recaptchaSiteKey = '';try { const csrfResponse = await fetchWithTimeout(BOOKING_API, { method: 'GET', credentials: 'include', timeout: 10000 });if (csrfResponse.ok) { const csrfData = await csrfResponse.json(); csrfToken = csrfData.csrf_token; recaptchaSiteKey = csrfData.recaptcha_site_key; } } catch (csrfErr) { console.warn('Could not retrieve CSRF token or site key:', csrfErr); }let recaptchaToken = '';if (recaptchaSiteKey) { try { await Promise.race([ loadRecaptchaScript(recaptchaSiteKey), new Promise(function(_, reject) { setTimeout(function() { reject(new Error('reCAPTCHA script load timeout')); }, 5000); }) ]);if (typeof grecaptcha !== 'undefined') { recaptchaToken = await Promise.race([ grecaptcha.execute(recaptchaSiteKey, { action: 'submit_booking' }), new Promise(function(_, reject) { setTimeout(function() { reject(new Error('reCAPTCHA execution timeout')); }, 4000); }) ]); } } catch (err) { console.warn('reCAPTCHA execution failed, proceeding without token:', err); } }payload.recaptcha_token = recaptchaToken;const response = await fetchWithTimeout(BOOKING_API, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrfToken }, credentials: 'include', body: JSON.stringify(payload), timeout: 10000 });let result = {};try { result = await response.json(); } catch (jsonErr) { console.warn('Could not parse response JSON:', jsonErr); }if (response.ok && result.status === 'success') { const totalPrice = tour ? tour.calcPrice(partySize) : partySize * 25.00;document.getElementById('bb-amount-display').textContent = '$' + totalPrice.toFixed(2) + ' DUE'; document.getElementById('bb-confirm-id').textContent = result.booking_id || '--'; document.getElementById('bb-confirm-party').textContent = partySize + ' Guest(s)';const displayDate = new Date(bbState.selectedDate + 'T12:00:00').toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });document.getElementById('bb-confirm-datetime').textContent = tourName + ' on ' + displayDate + ' @ ' + bbState.selectedTime;const invoiceLink = document.getElementById('bb-invoice-link'); const countdownEl = document.getElementById('bb-redirect-countdown');if (invoiceLink && result.payment_link && isTrustedRedirectUrl(result.payment_link)) { invoiceLink.href = result.payment_link; invoiceLink.style.display = 'inline-flex'; } else if (invoiceLink) { invoiceLink.style.display = 'none'; }const cancelLink = document.getElementById('bb-cancel-link');if (cancelLink && result.booking_id && result.token) { cancelLink.href = 'https://us-west2-bodie-tours-prod.cloudfunctions.net/cancel-tour?booking_id=' + encodeURIComponent(result.booking_id) + '&token=' + encodeURIComponent(result.token); }let openedInNewTab = false;if (paymentWindow) { try { if (!paymentWindow.closed) { if (result.payment_link && isTrustedRedirectUrl(result.payment_link)) { paymentWindow.location.href = result.payment_link; openedInNewTab = true; } else { paymentWindow.close(); } } } catch (e) { console.warn('Failed to set payment window location:', e); } }if (countdownEl) { if (openedInNewTab) { countdownEl.innerHTML = 'Your invoice has been opened in a new tab. If it did not open, click Pay Your Invoice Now above.'; } else { countdownEl.innerHTML = 'Please click the Pay Your Invoice Now button above to complete your secure payment.'; } }bbGoTo(4); } else { if (paymentWindow) { try { paymentWindow.close(); } catch (e) {} }if (response.status === 400) { errMsg.textContent = result.message || 'Validation error. Please check your inputs.'; } else if (response.status === 409) { errMsg.textContent = result.message || 'The requested slot is already booked. Please choose another slot.'; } else if (response.status === 429) { errMsg.textContent = 'Too many booking attempts. Please wait a moment and try again.'; } else if (response.status === 500) { errMsg.textContent = 'A temporary server error occurred. Please try again shortly.'; } else { errMsg.textContent = result.message || 'The slot is no longer available. Please select another time.'; }errBox.style.display = 'flex'; } } catch (err) { if (paymentWindow) { try { paymentWindow.close(); } catch (e) {} }console.error('Booking failed:', err); errMsg.textContent = 'Network or connection error. Please try again.'; errBox.style.display = 'flex'; } finally { bbState.isSubmitting = false;if (confirmBtn) { confirmBtn.disabled = false; }bbHideLoading(); } }function bbAnnounce(message) { const announcer = document.getElementById('bb-announcer');if (announcer) { announcer.textContent = '';setTimeout(function() { announcer.textContent = message; }, 50); } }function bbGoTo(step) { if (step < 4) { bbClearTimers(); }document.querySelectorAll('.bb-step').forEach(function(pane) { pane.classList.remove('active'); });document.getElementById('step-pane-' + step).classList.add('active');document.getElementById('bb-progress-bar').style.width = (step / 4) * 100 + '%';const progressContainer = document.getElementById('bb-progress-container');if (progressContainer) { progressContainer.setAttribute('aria-valuenow', step + 1); }document.querySelectorAll('.bb-progress-step').forEach(function(dot, index) { if (index < step) { dot.className = 'bb-progress-step completed'; dot.removeAttribute('aria-current'); } else if (index === step) { dot.className = 'bb-progress-step active'; dot.setAttribute('aria-current', 'step'); } else { dot.className = 'bb-progress-step'; dot.removeAttribute('aria-current'); } });if (step === 1) { bbFetchMonthAvailability(bbState.currentYear, bbState.currentMonth).then(function() { bbRenderCalendar(); }); }if (step === 2) { bbPopulateSlots(); }if (step === 3) { bbUpdateStep3Fields(); }const heading = document.getElementById('bb-step-heading-' + step);if (heading) { heading.focus({ preventScroll: true }); bbAnnounce('Step ' + (step + 1) + ' of 5: ' + heading.textContent.trim()); }const widget = document.getElementById('bodie-booking-widget');if (widget) { window.scrollTo({ top: widget.offsetTop - 30, behavior: 'smooth' }); } }function bbSelectTour(tourKey) { bbState.selectedTour = tourKey;document.querySelectorAll('.bb-tour-card').forEach(function(card) { const isSelected = card.getAttribute('data-tour') === tourKey;if (isSelected) { card.classList.add('selected'); card.setAttribute('aria-checked', 'true'); card.setAttribute('aria-pressed', 'true'); card.setAttribute('tabindex', '0'); } else { card.classList.remove('selected'); card.setAttribute('aria-checked', 'false'); card.setAttribute('aria-pressed', 'false'); card.setAttribute('tabindex', '-1'); } });const tourName = TOURS[tourKey] ? TOURS[tourKey].name : 'Tour';bbAnnounce('Selected tour: ' + tourName);document.getElementById('bb-to-step-1').disabled = false;bbState.selectedDate = null; bbState.selectedTime = null;document.getElementById('bb-to-step-2').disabled = true; document.getElementById('bb-to-step-3').disabled = true; }function bbUpdateStep3Fields() { const tourKey = bbState.selectedTour; const tour = TOURS[tourKey];const ackGroup = document.getElementById('mines-vehicle-ack-group'); const ackInput = document.getElementById('mines-vehicle-ack'); const partyInput = document.getElementById('guest-party'); const partyLabel = document.querySelector('label[for="guest-party"]');if (tourKey === 'mines') { ackGroup.style.display = 'block'; ackInput.required = true; } else { ackGroup.style.display = 'none'; ackInput.required = false; ackInput.checked = false; }const maxParty = tour ? tour.maxParty : 20;partyInput.max = maxParty; partyInput.placeholder = 'e.g., 4 (maximum ' + maxParty + ')'; partyLabel.textContent = 'Number of Guests (Required, max ' + maxParty + ')'; }async function bbRetryCalendarFetch() { await bbFetchMonthAvailability(bbState.currentYear, bbState.currentMonth); bbRenderCalendar(); }function bbStartOver() { bbClearTimers();bbState = { selectedTour: null, currentYear: new Date().getFullYear(), currentMonth: new Date().getMonth(), selectedDate: null, selectedTime: null, availableDates: {}, redirectTimeout: null, redirectInterval: null, calendarFetchFailed: false, isSubmitting: false };const form = document.getElementById('bb-booking-form');if (form) { form.reset(); }const errBox = document.getElementById('bb-error-box');if (errBox) { errBox.style.display = 'none'; }document.getElementById('bb-to-step-1').disabled = true; document.getElementById('bb-to-step-2').disabled = true; document.getElementById('bb-to-step-3').disabled = true;document.querySelectorAll('.bb-tour-card').forEach(function(card) { card.classList.remove('selected'); card.setAttribute('aria-checked', 'false'); card.setAttribute('aria-pressed', 'false'); });bbGoTo(0); }function bbShowLoading(text) { const loading = document.getElementById('bb-loading'); const loadingText = document.getElementById('bb-loading-text');if (loadingText) { loadingText.textContent = text; }if (loading) { loading.setAttribute('aria-hidden', 'false'); loading.classList.add('active'); } }function bbHideLoading() { const loading = document.getElementById('bb-loading');if (loading) { loading.setAttribute('aria-hidden', 'true'); loading.classList.remove('active'); } }window.bbSelectTour = bbSelectTour; window.bbRetryCalendarFetch = bbRetryCalendarFetch; window.bbStartOver = bbStartOver; window.bbChangeMonth = bbChangeMonth; window.bbGoTo = bbGoTo; window.bbSubmitBooking = bbSubmitBooking; window.bbInit = bbInit;function bbSafeInit() { if (!document.getElementById('bodie-booking-widget')) { return; }bbInit(); }if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', bbSafeInit); } else { bbSafeInit(); } })();

Bodie is named the Largest Gold-Mining Ghost Town by Guiness World Records

We are so excited to share that a recent addition of Guiness World Records identifies Bodie as the Largest Gold-Mining Ghost Town. Their website now features an account of Bodie’s history and significance as gold mining ghost town. This is a profound acknowledgement of Bodie’s contribution to history and culture worldwide.

This recognition comes on the heels of another significant milestone for Bodie. In May an update to our National Historic Landmark designation was presented to the committee for approval. This update significantly increases the area considered under the designation as well as expands the criteria under which Bodie is considered significant. While the committee voted unanimously to update the designation, it is still awaiting signature from the Interior Secretary and when that is complete, we will we share more information.

A summer of exciting news for Bodie!

Join our mailing list

Love Bodie State Historic Park? Stay connected for information on Bodie and the Foundation’s work.