/* JNP Home SEO Copy v25.0.18 — separate IIFE so it still runs if hamburger early-returns */ (function () { if ( window.__jnpHomeSeoCopyV18 ) return; window.__jnpHomeSeoCopyV18 = true; if ( ! document.body || ! ( document.body.classList.contains( 'home' ) || document.body.classList.contains( 'page-id-1993' ) ) ) { return; } var TITLE = 'Custom Photo Merch & Apparel in Bali | J&P Bali'; var DESC = 'Custom photo merch in Bali: upload a trip photo, we print premium apparel and deliver to your hotel. Group kits, corporate merch, and affiliate partnerships — J&P Bali.'; var MAP = [ [ 'Turn Your Bali Memories Into Wearable Art', 'Custom Photo Merch Delivered to Your Bali Hotel' ], [ 'Custom Photo Merch • Group Apparel • Affiliate Partnerships', 'J&P Bali · Photo Merch · Hotel Delivery' ], [ 'CUSTOM PHOTO MERCH • GROUP APPAREL • AFFILIATE PARTNERSHIPS', 'J&P BALI · PHOTO MERCH · HOTEL DELIVERY' ], [ 'Send us your favorite photo from Bali. We turn it into premium apparel and deliver it to your hotel before you fly home.', 'Upload a trip photo — we print premium apparel and deliver it to your hotel before you fly home.', ], [ 'Welcome to J&P Bali—the official heartbeat of custom apparel and affiliate solutions. Driven by our core philosophy, DHB (Double Helix Brothers), we believe at the most fundamental level, we are all part of the same human tribe, completely wired together.', 'J&P Bali makes custom photo apparel and merch in Bali — from trip souvenirs to crew kits and partner branding.', ], [ 'Born on the streets of Bali, we blend premium apparel production with forward-thinking tech solutions—turning your adventure into wearables that tell your story.', 'Born in Bali: premium apparel production that turns your adventure into wearables that tell your story.', ], [ 'Upload a photo from your trip and we turn it into premium wearable art — t-shirts, hoodies, mugs, canvas prints, and more — delivered to your hotel.', 'Turn a trip photo into t-shirts, hoodies, mugs, and prints — delivered to your hotel.', ], [ 'Premium gear for trips, hens/bucks weeks, and action sports crews—from concept to final print.', 'Premium gear for trips, hens/bucks weeks, and crews — from concept to print.', ], [ 'Clean, professional uniforms and promotional merch to elevate your brand identity.', 'Professional uniforms and promo merch for teams and brands.', ], [ 'Pull-up banners, flyers, business cards, and display setups for local businesses and launches.', 'Banners, flyers, cards, and display kits for local businesses.', ], [ 'Coming soon: ID-registered proximity tags built into our apparel, bridging digital data and real-world connection.', 'Coming soon: proximity tags built into apparel.', ], [ 'Got a photo, an event, or a brand in mind?', 'Ready for custom Bali merch?' ], [ 'Turn it into wearable art, or become a partner and earn on every referral.', 'Order photo merch or become a partner.' ], [ "Questions about your order or a custom quote? We're here to help.", 'Need a quote or order help? Message us.' ], [ 'Questions about your order or a custom quote? We’re here to help.', 'Need a quote or order help? Message us.' ], [ 'One Tribe. Same Vibe. Premium apparel, corporate kits, and affiliate branding — built in Bali.', 'Premium apparel & partner branding — built in Bali.', ], ]; function setMeta() { document.title = TITLE; var desc = document.querySelector( 'meta[name="description"]' ); if ( desc ) desc.setAttribute( 'content', DESC ); var ogt = document.querySelector( 'meta[property="og:title"]' ); if ( ogt ) ogt.setAttribute( 'content', TITLE ); var ogd = document.querySelector( 'meta[property="og:description"]' ); if ( ogd ) ogd.setAttribute( 'content', DESC ); } function replaceInTextNodes( root ) { var walker = document.createTreeWalker( root, NodeFilter.SHOW_TEXT, null ); var nodes = []; var n; while ( ( n = walker.nextNode() ) ) nodes.push( n ); for ( var i = 0; i < nodes.length; i++ ) { var node = nodes[ i ]; var parent = node.parentElement; if ( ! parent ) continue; var tag = parent.tagName; if ( tag === 'SCRIPT' || tag === 'STYLE' || tag === 'NOSCRIPT' ) continue; var val = node.nodeValue; if ( ! val || ! val.trim() ) continue; var next = val; for ( var j = 0; j < MAP.length; j++ ) { if ( next.indexOf( MAP[ j ][ 0 ] ) !== -1 ) next = next.split( MAP[ j ][ 0 ] ).join( MAP[ j ][ 1 ] ); } if ( next !== val ) node.nodeValue = next; } } function promoteHeroH1() { var heroes = [ 'Custom Photo Merch Delivered to Your Bali Hotel', 'Turn Your Bali Memories Into Wearable Art' ]; var headings = document.querySelectorAll( 'h2.elementor-heading-title, h2' ); for ( var i = 0; i < headings.length; i++ ) { var el = headings[ i ]; var t = ( el.textContent || '' ).replace( /\s+/g, ' ' ).trim(); if ( heroes.indexOf( t ) === -1 ) continue; if ( el.tagName === 'H1' ) return; var h1 = document.createElement( 'h1' ); for ( var a = 0; a < el.attributes.length; a++ ) { h1.setAttribute( el.attributes[ a ].name, el.attributes[ a ].value ); } while ( el.firstChild ) h1.appendChild( el.firstChild ); el.parentNode.replaceChild( h1, el ); return; } } function run() { setMeta(); replaceInTextNodes( document.body ); promoteHeroH1(); } if ( document.readyState === 'loading' ) document.addEventListener( 'DOMContentLoaded', run ); else run(); setTimeout( run, 400 ); setTimeout( run, 1200 ); })(); (function () { /** * Sole hamburger binder. Sets V10 flag immediately so the mu-plugin footer * (which used to boot twice and stack document listeners) exits early. */ window.__jnpHamburgerFixV10 = true; if ( window.__jnpHamburgerFixV11 ) { return; } window.__jnpHamburgerFixV11 = true; var bound = false; function boot() { if ( bound ) { return; } var header = document.getElementById( 'jnp-header' ); var ham = document.querySelector( '.jnp-hamburger' ); var menu = document.getElementById( 'jnp-mobile-menu' ); if ( header ) { var toggleScrolled = function () { if ( window.scrollY > 10 ) { header.classList.add( 'is-scrolled' ); } else { header.classList.remove( 'is-scrolled' ); } }; toggleScrolled(); window.addEventListener( 'scroll', toggleScrolled, { passive: true } ); } if ( ! ham || ! menu || ! ham.parentNode ) { return; } bound = true; var fresh = ham.cloneNode( true ); ham.parentNode.replaceChild( fresh, ham ); ham = fresh; if ( menu.parentElement !== document.body ) { document.body.appendChild( menu ); } ham.setAttribute( 'type', 'button' ); if ( ! ham.getAttribute( 'aria-expanded' ) ) { ham.setAttribute( 'aria-expanded', 'false' ); } menu.setAttribute( 'aria-hidden', menu.classList.contains( 'is-open' ) ? 'false' : 'true' ); var ignoreUntil = 0; var lockY = 0; function setOpen( open ) { ham.setAttribute( 'aria-expanded', open ? 'true' : 'false' ); ham.setAttribute( 'aria-label', open ? 'Close menu' : 'Open menu' ); menu.classList.toggle( 'is-open', open ); menu.setAttribute( 'aria-hidden', open ? 'false' : 'true' ); document.body.classList.toggle( 'jnp-menu-open', open ); if ( open ) { lockY = window.scrollY || 0; document.body.style.position = 'fixed'; document.body.style.top = '-' + lockY + 'px'; document.body.style.left = '0'; document.body.style.right = '0'; document.body.style.width = '100%'; document.body.style.overflow = 'hidden'; } else { document.body.style.position = ''; document.body.style.top = ''; document.body.style.left = ''; document.body.style.right = ''; document.body.style.width = ''; document.body.style.overflow = ''; window.scrollTo( 0, lockY ); } } ham.addEventListener( 'click', function ( e ) { e.preventDefault(); e.stopPropagation(); if ( e.stopImmediatePropagation ) { e.stopImmediatePropagation(); } var open = ham.getAttribute( 'aria-expanded' ) === 'true'; setOpen( ! open ); if ( ! open ) { ignoreUntil = Date.now() + 500; } }, true ); document.addEventListener( 'click', function ( e ) { if ( Date.now() < ignoreUntil ) { return; } if ( ! menu.classList.contains( 'is-open' ) ) { return; } var t = e.target; if ( t && ( menu.contains( t ) || ham.contains( t ) ) ) { return; } setOpen( false ); }, true ); document.addEventListener( 'keydown', function ( e ) { if ( e.key === 'Escape' && menu.classList.contains( 'is-open' ) ) { setOpen( false ); ham.focus(); } } ); window.addEventListener( 'resize', function () { if ( window.innerWidth > 1024 && menu.classList.contains( 'is-open' ) ) { setOpen( false ); } }, { passive: true } ); } if ( document.readyState === 'loading' ) { document.addEventListener( 'DOMContentLoaded', boot ); } else { boot(); } })(); (function () { var WA_HREF = 'https://wa.me/6287740098436?text=' + encodeURIComponent( 'Hi J&P Bali! I would like to ask about custom trip apparel.' ); var PAYMENT_LINE = 'Payment: PayPal, Credit Card, or Bank Transfer (IDR/AUD)'; function rewriteWhatsApp() { document.querySelectorAll( 'a[href*="wa.me"], a[href*="api.whatsapp.com"], a[href*="whatsapp.com"], a.jnp-wa' ).forEach( function ( a ) { var href = a.getAttribute( 'href' ) || ''; if ( href.indexOf( '6287740098436' ) !== -1 ) { return; } var textMatch = href.match( /[?&]text=([^&]*)/ ); a.setAttribute( 'href', textMatch ? ( 'https://wa.me/6287740098436?text=' + textMatch[ 1 ] ) : WA_HREF ); } ); document.querySelectorAll( 'a[href^="tel:"]' ).forEach( function ( a ) { var href = ( a.getAttribute( 'href' ) || '' ).replace( /\s/g, '' ); if ( /6281234567890|1234567890/.test( href ) ) { a.setAttribute( 'href', 'tel:+6287740098436' ); } } ); } function rewritePaymentLine() { document.querySelectorAll( '.elementor-icon-list-text, .jnp-payment-note' ).forEach( function ( el ) { var t = ( el.textContent || '' ).replace( /\s+/g, ' ' ).trim(); if ( /^Payment:/i.test( t ) && t !== PAYMENT_LINE ) { el.textContent = PAYMENT_LINE; } } ); } function blockSyntheticGalleryClicks() { document.addEventListener( 'click', function ( e ) { var raw = e.target; var el = raw && raw.nodeType === 1 ? raw : ( raw && raw.parentElement ); var modal = el && el.closest && el.closest( '.js-product-modal, .woocommerce-product-gallery__image a' ); if ( ! modal ) { return; } if ( e.isTrusted ) { return; } e.preventDefault(); e.stopImmediatePropagation(); }, true ); } function improveCartLinks() { document.querySelectorAll( 'a[href*="/cart"]' ).forEach( function ( link ) { var text = ( link.textContent || '' ).replace( /\s+/g, ' ' ).trim(); var countMatch = text.match( /^(\d+)$/ ); if ( ! countMatch ) { return; } var count = countMatch[ 1 ]; var label = count === '1' ? 'Cart, 1 item' : 'Cart, ' + count + ' items'; link.setAttribute( 'aria-label', label ); } ); var floatBtn = document.querySelector( '.jnp-float-cart__btn' ); if ( floatBtn ) { var countEl = floatBtn.querySelector( '.jnp-float-cart__count' ); var n = countEl ? parseInt( countEl.getAttribute( 'data-count' ) || countEl.textContent || '0', 10 ) : 0; if ( n > 0 ) { floatBtn.setAttribute( 'aria-label', n === 1 ? 'Open shopping cart, 1 item' : 'Open shopping cart, ' + n + ' items' ); } } } function goToColorSlide( slug ) { var gal = document.querySelector( '.woocommerce-product-gallery' ); if ( ! gal || ! slug ) { return; } var imgs = gal.querySelectorAll( '.woocommerce-product-gallery__image' ); var i; for ( i = 0; i < imgs.length; i++ ) { var im = imgs[ i ].querySelector( 'img' ); var src = im ? ( im.getAttribute( 'src' ) || '' ) : ''; var hay = src.toLowerCase(); if ( hay.indexOf( '-' + slug + '.' ) > -1 || hay.indexOf( '-' + slug + '-' ) > -1 ) { var dots = document.querySelectorAll( '.c-product__slider [aria-label^="Slide"], .js-single-product-carousel .dot' ); if ( dots[ i ] ) { dots[ i ].click(); } break; } } } function bindColorSwatches() { var wrap = document.querySelector( '[data-jnp-color-swatch]' ); if ( ! wrap ) { return; } wrap.querySelectorAll( '.jnp-color-swatch__dot' ).forEach( function ( dot, index ) { dot.setAttribute( 'role', 'button' ); dot.setAttribute( 'tabindex', '0' ); if ( ! dot.getAttribute( 'aria-label' ) ) { var slug = dot.getAttribute( 'data-color-slug' ) || ( 'Color ' + ( index + 1 ) ); dot.setAttribute( 'aria-label', 'Show ' + slug.replace( /-/g, ' ' ) + ' product image' ); } function activateSwatch() { wrap.querySelectorAll( '.jnp-color-swatch__dot' ).forEach( function ( other ) { other.classList.remove( 'is-selected' ); other.setAttribute( 'aria-pressed', 'false' ); } ); dot.classList.add( 'is-selected' ); dot.setAttribute( 'aria-pressed', 'true' ); goToColorSlide( dot.getAttribute( 'data-color-slug' ) ); } dot.addEventListener( 'click', activateSwatch ); dot.addEventListener( 'keydown', function ( e ) { if ( e.key === 'Enter' || e.key === ' ' ) { e.preventDefault(); activateSwatch(); } } ); } ); } function syncHotelFields() { var search = document.getElementById( 'jnp_hotel_search' ); var name = document.getElementById( 'jnp_hotel_name' ); var form = document.querySelector( 'form.checkout' ); if ( ! search || ! name ) { return; } function copy() { if ( search.value && ! name.value ) { name.value = search.value; } } search.addEventListener( 'change', copy ); search.addEventListener( 'blur', copy ); if ( form ) { form.addEventListener( 'submit', copy ); } } function closeCartOnCheckout() { if ( ! document.body.classList.contains( 'woocommerce-checkout' ) ) { return; } var root = document.getElementById( 'jnp-float-cart' ); if ( ! root ) { return; } root.classList.remove( 'is-open' ); var panel = root.querySelector( '.jnp-float-cart__panel' ); var btn = root.querySelector( '.jnp-float-cart__btn' ); if ( panel ) { panel.setAttribute( 'hidden', 'hidden' ); } if ( btn ) { btn.setAttribute( 'aria-expanded', 'false' ); } } function hideHotelDupes() { if ( ! document.body.classList.contains( 'woocommerce-checkout' ) ) { return; } var nameField = document.getElementById( 'jnp_hotel_name_field' ); if ( nameField ) { nameField.style.display = 'none'; } Array.prototype.forEach.call( document.querySelectorAll( '.form-row, p.form-row' ), function ( row ) { var lab = row.querySelector( 'label' ); if ( ! lab ) { return; } var t = ( lab.textContent || '' ).replace( /\s+/g, ' ' ).trim(); if ( ! /Hotel\s*\/\s*Villa/i.test( t ) ) { return; } if ( row.querySelector( '#jnp_hotel_search' ) ) { return; } row.style.display = 'none'; } ); } function hideMugDesignStyle() { if ( ! /mug/i.test( location.pathname + ' ' + document.body.className ) ) { return; } var sel = document.querySelector( '[name="attribute_design-style"], [name="attribute_pa_design-style"]' ); if ( ! sel ) { return; } if ( sel.tagName === 'SELECT' && ! sel.value ) { var i; for ( i = 0; i < sel.options.length; i++ ) { if ( sel.options[ i ].value ) { sel.value = sel.options[ i ].value; sel.dispatchEvent( new Event( 'change', { bubbles: true } ) ); break; } } } var row = sel.closest( 'tr' ); if ( row ) { row.style.display = 'none'; } } function relocateExpressCheckout() { var payment = document.getElementById( 'payment' ); if ( ! payment ) { return; } var anchor = payment.querySelector( '.jnp-checkout-step-badge--pay' ) || payment.firstChild; var selectors = [ '.wc-stripe-express-checkout', '#wc-stripe-express-checkout-element', '.wc-stripe-express-checkout-button-separator', ]; selectors.forEach( function ( sel ) { document.querySelectorAll( sel ).forEach( function ( el ) { var mount = el.closest( '.wc-stripe-express-checkout' ) || el; if ( mount && ! payment.contains( mount ) ) { payment.insertBefore( mount, anchor ); } } ); } ); } function relocateCheckoutChrome() { if ( ! document.body.classList.contains( 'woocommerce-checkout' ) ) { return; } var col1 = document.querySelector( '.c-cart__col-1--checkout' ) || document.querySelector( '.c-cart__col-1' ); var colTarget = col1 && ( col1.querySelector( '.js-sticky-sidebar-nearby' ) || col1 ); var progress = document.querySelector( '.jnp-checkout-progress' ); if ( progress && colTarget && ! colTarget.contains( progress ) ) { colTarget.insertBefore( progress, colTarget.firstChild ); } var payNote = document.querySelector( '.jnp-checkout-payment-note' ); var payment = document.getElementById( 'payment' ); if ( payNote && payment && ! payment.contains( payNote ) ) { payment.insertBefore( payNote, payment.firstChild ); } relocateExpressCheckout(); var fieldWrapper = document.querySelector( '.woocommerce-billing-fields__field-wrapper' ); var step2Badge = document.querySelector( '.jnp-checkout-step-badge[data-jnp-step="2"]' ); if ( fieldWrapper && step2Badge && ! fieldWrapper.contains( step2Badge ) ) { fieldWrapper.insertBefore( step2Badge, fieldWrapper.firstChild ); } } function getCheckoutStep() { var step = parseInt( document.body.getAttribute( 'data-jnp-checkout-step' ), 10 ); return step >= 1 && step <= 3 ? step : 1; } function setSectionHidden( el, hidden ) { if ( ! el ) { return; } if ( hidden ) { el.setAttribute( 'hidden', 'hidden' ); el.setAttribute( 'aria-hidden', 'true' ); el.classList.add( 'jnp-step-hidden' ); el.style.setProperty( 'display', 'none', 'important' ); } else { el.removeAttribute( 'hidden' ); el.setAttribute( 'aria-hidden', 'false' ); el.classList.remove( 'jnp-step-hidden' ); el.style.removeProperty( 'display' ); } } function applyCheckoutStepVisibility( step ) { var billing = document.querySelector( '.woocommerce-billing-fields' ); var chWrap = document.querySelector( '.jnp-ch-wrap' ); var fieldWrapper = billing && billing.querySelector( '.woocommerce-billing-fields__field-wrapper' ); var additional = document.querySelector( '.woocommerce-additional-fields' ); var payment = document.getElementById( 'payment' ); var col2 = document.querySelector( '.c-cart__col-1 .col-2' ); var billingTitle = billing && billing.querySelector( 'h3' ); setSectionHidden( chWrap, step !== 1 ); setSectionHidden( fieldWrapper, step !== 2 ); if ( billing ) { Array.prototype.forEach.call( billing.children, function ( child ) { if ( child.classList.contains( 'jnp-ch-wrap' ) || child.classList.contains( 'woocommerce-billing-fields__field-wrapper' ) || child.classList.contains( 'jnp-checkout-anchor' ) ) { return; } if ( child.classList.contains( 'jnp-checkout-nav' ) ) { var navStep = parseInt( child.getAttribute( 'data-jnp-step' ), 10 ); setSectionHidden( child, navStep !== step ); return; } if ( child.classList.contains( 'jnp-checkout-step-badge' ) ) { var badgeStep = parseInt( child.getAttribute( 'data-jnp-step' ), 10 ); setSectionHidden( badge, badgeStep !== step ); return; } setSectionHidden( child, step !== 2 ); } ); } document.querySelectorAll( '.jnp-checkout-nav[data-jnp-step]' ).forEach( function ( nav ) { var navStep = parseInt( nav.getAttribute( 'data-jnp-step' ), 10 ); setSectionHidden( nav, navStep !== step ); } ); setSectionHidden( additional, step !== 2 ); setSectionHidden( col2, step !== 2 ); /* Show payment method radios from step 2; Place Order stays step 3 via CSS. */ setSectionHidden( payment, step === 1 ); document.querySelectorAll( '.jnp-checkout-step-badge--pay' ).forEach( function ( badge ) { setSectionHidden( badge, step !== 3 ); } ); /* Keep Place Order + terms only on step 3 even when #payment is visible on step 2. */ var placeOrder = document.getElementById( 'place_order' ); var terms = document.querySelector( '.woocommerce-terms-and-conditions-wrapper' ); setSectionHidden( placeOrder, step !== 3 ); setSectionHidden( terms, step !== 3 ); document.querySelectorAll( '.jnp-checkout-nav--step1, .jnp-checkout-nav--step2' ).forEach( function ( nav ) { setSectionHidden( nav, true ); } ); document.querySelectorAll( '.jnp-checkout-nav a[href^="#jnp-step"]' ).forEach( function ( link ) { link.style.display = 'none'; } ); if ( billingTitle ) { billingTitle.textContent = 'How can we reach you?'; setSectionHidden( billingTitle, step !== 2 ); } if ( step !== 3 ) { document.querySelectorAll( '.wc-stripe-express-checkout, #wc-stripe-express-checkout-element, .wc-stripe-express-checkout-button-separator, .ppc-button-wrapper, .c-cart__col-2 .separator, .c-cart__sidebar .separator, .woocommerce-checkout-payment .separator' ).forEach( function ( el ) { setSectionHidden( el, true ); } ); } else { document.querySelectorAll( '.wc-stripe-express-checkout, #wc-stripe-express-checkout-element, .wc-stripe-express-checkout-button-separator' ).forEach( function ( el ) { setSectionHidden( el, false ); } ); relocateExpressCheckout(); } } function setCheckoutStep( step ) { document.body.setAttribute( 'data-jnp-checkout-step', String( step ) ); var progressItems = document.querySelectorAll( '.jnp-checkout-progress__item' ); Array.prototype.forEach.call( progressItems, function ( item, index ) { var num = index + 1; item.classList.toggle( 'is-current', num === step ); item.classList.toggle( 'is-done', num < step ); } ); applyCheckoutStepVisibility( step ); } function clearCheckoutNavError( nav ) { if ( ! nav ) { return; } var err = nav.querySelector( '.jnp-checkout-nav__error' ); if ( err ) { err.remove(); } } function showCheckoutNavError( nav, message ) { clearCheckoutNavError( nav ); if ( ! nav || ! message ) { return; } var err = document.createElement( 'p' ); err.className = 'jnp-checkout-nav__error'; err.setAttribute( 'role', 'alert' ); err.textContent = message; nav.insertBefore( err, nav.firstChild ); } function validateVisibleFields( container ) { if ( ! container ) { return true; } var fields = container.querySelectorAll( 'input, select, textarea' ); for ( var i = 0; i < fields.length; i++ ) { var field = fields[ i ]; if ( field.type === 'hidden' || field.disabled ) { continue; } if ( field.offsetParent === null && field.type !== 'radio' && field.type !== 'checkbox' ) { continue; } if ( typeof field.checkValidity === 'function' && ! field.checkValidity() ) { field.reportValidity(); field.focus(); return false; } } return true; } function ensureCheckoutNav( container, step ) { if ( ! container ) { return null; } var existing = container.querySelector( ':scope > .jnp-checkout-nav[data-jnp-step="' + step + '"]' ); if ( existing ) { return existing; } var nav = document.createElement( 'div' ); nav.className = 'jnp-checkout-nav'; nav.setAttribute( 'data-jnp-step', String( step ) ); if ( step > 1 ) { var back = document.createElement( 'button' ); back.type = 'button'; back.className = 'jnp-checkout-nav__btn jnp-checkout-nav__btn--back jnp-checkout-nav--back'; back.textContent = step === 2 ? 'Back to hotel' : 'Back to contact'; back.addEventListener( 'click', function () { clearCheckoutNavError( nav ); setCheckoutStep( step - 1 ); window.scrollTo( { top: 0, behavior: 'smooth' } ); } ); nav.appendChild( back ); } if ( step < 3 ) { var next = document.createElement( 'button' ); next.type = 'button'; next.className = 'jnp-checkout-nav__btn jnp-checkout-nav--continue'; next.textContent = step === 1 ? 'Continue to contact' : 'Continue to payment'; next.addEventListener( 'click', function () { clearCheckoutNavError( nav ); var valid = step === 1 ? validateVisibleFields( document.querySelector( '.jnp-ch-wrap' ) ) : validateVisibleFields( document.querySelector( '.woocommerce-billing-fields' ) ); if ( ! valid ) { return; } setCheckoutStep( step + 1 ); window.scrollTo( { top: 0, behavior: 'smooth' } ); } ); nav.appendChild( next ); } container.appendChild( nav ); return nav; } function initCheckoutWizard() { if ( ! document.body.classList.contains( 'woocommerce-checkout' ) ) { return; } if ( document.body.classList.contains( 'woocommerce-order-received' ) ) { return; } var firstRun = document.body.dataset.jnpCheckoutWizard !== '1'; if ( firstRun ) { document.body.classList.add( 'jnp-checkout-wizard' ); document.body.dataset.jnpCheckoutWizard = '1'; relocateCheckoutChrome(); ensureCheckoutNav( document.querySelector( '.jnp-ch-wrap' ), 1 ); ensureCheckoutNav( document.querySelector( '.woocommerce-billing-fields' ), 2 ); } setCheckoutStep( getCheckoutStep() || 1 ); } function initTouristCheckout() { if ( ! document.body.classList.contains( 'woocommerce-checkout' ) ) { return; } if ( document.body.classList.contains( 'woocommerce-order-received' ) ) { return; } initCheckoutWizard(); var wrap = document.querySelector( '.jnp-ch-wrap' ); if ( wrap && ! wrap.querySelector( '.jnp-checkout-step-badge[data-jnp-step="1"]' ) ) { var stepBadge = document.createElement( 'p' ); stepBadge.className = 'jnp-checkout-step-badge'; stepBadge.setAttribute( 'data-jnp-step', '1' ); stepBadge.textContent = 'Step 1 of 3'; var title = wrap.querySelector( '.jnp-ch-title' ); if ( title && title.parentNode ) { title.parentNode.insertBefore( stepBadge, title ); } else { wrap.insertBefore( stepBadge, wrap.firstChild ); } } var search = document.getElementById( 'jnp_hotel_search' ); var list = document.querySelector( '.jnp-ch-list' ); if ( search ) { if ( list && ! list.id ) { list.id = 'jnp_hotel_autocomplete'; } search.setAttribute( 'role', 'combobox' ); search.setAttribute( 'aria-autocomplete', 'list' ); search.setAttribute( 'aria-haspopup', 'listbox' ); if ( list ) { search.setAttribute( 'aria-controls', list.id ); list.setAttribute( 'role', 'listbox' ); } function syncExpanded() { var open = list && list.classList.contains( 'is-open' ); search.setAttribute( 'aria-expanded', open ? 'true' : 'false' ); } search.addEventListener( 'input', syncExpanded ); search.addEventListener( 'focus', syncExpanded ); search.addEventListener( 'blur', function () { window.setTimeout( syncExpanded, 200 ); } ); if ( window.MutationObserver && list ) { new MutationObserver( syncExpanded ).observe( list, { attributes: true, attributeFilter: [ 'class' ], } ); } syncExpanded(); } var progressItems = document.querySelectorAll( '.jnp-checkout-progress__item' ); if ( progressItems.length ) { Array.prototype.forEach.call( progressItems, function ( item, index ) { item.style.cursor = 'pointer'; item.addEventListener( 'click', function () { var targetStep = index + 1; var current = getCheckoutStep(); if ( targetStep < current ) { setCheckoutStep( targetStep ); window.scrollTo( { top: 0, behavior: 'smooth' } ); } } ); } ); } } rewriteWhatsApp(); rewritePaymentLine(); blockSyntheticGalleryClicks(); bindColorSwatches(); syncHotelFields(); closeCartOnCheckout(); hideHotelDupes(); hideMugDesignStyle(); initTouristCheckout(); improveCartLinks(); if ( document.readyState === 'loading' ) { document.addEventListener( 'DOMContentLoaded', function () { rewriteWhatsApp(); rewritePaymentLine(); bindColorSwatches(); syncHotelFields(); closeCartOnCheckout(); hideHotelDupes(); hideMugDesignStyle(); initTouristCheckout(); improveCartLinks(); } ); } window.setTimeout( function () { rewriteWhatsApp(); rewritePaymentLine(); relocateCheckoutChrome(); initTouristCheckout(); }, 800 ); if ( window.MutationObserver ) { var waTimer = null; new MutationObserver( function () { window.clearTimeout( waTimer ); waTimer = window.setTimeout( rewriteWhatsApp, 200 ); } ).observe( document.documentElement, { childList: true, subtree: true } ); } })();