jQuery(document).ready(function($){
'use strict';
let currentSlideIndex=0;
let slideTimer;
let banners=[];
let isPlaying=true;
let isMobile=(function(){
var width=window.innerWidth;
if(typeof width==='undefined'){
requestAnimationFrame(function(){
width=window.innerWidth||document.documentElement.clientWidth;
});
width=document.documentElement.clientWidth||768;
}
return width <=768;
})();
let slideStartTime=Date.now();
let currentSlideDuration=5;
let countdownInterval;
const showCountdown=(typeof window.bannerSlideGlobal!=='undefined'&&parseInt(window.bannerSlideGlobal.showCountdown)===1);
const countdownFormat=(typeof window.bannerSlideGlobal!=='undefined'&&window.bannerSlideGlobal.countdownFormat) ? window.bannerSlideGlobal.countdownFormat:'{n}';
const countdownBg=(typeof window.bannerSlideGlobal!=='undefined'&&window.bannerSlideGlobal.countdownBg) ? window.bannerSlideGlobal.countdownBg:'#000000';
let pcHeight=80;
let mobileHeight=60;
if(typeof window.bannerSlideSettings!=='undefined'){
pcHeight=window.bannerSlideSettings.pcHeight||80;
mobileHeight=window.bannerSlideSettings.mobileHeight||60;
}
if(typeof window.bannerSlideData!=='undefined'){
banners=window.bannerSlideData;
}
if(!banners||banners.length===0){
return;
}
const STORAGE_KEY='bannerSlideState';
function saveSlideState(){
if(banners.length <=1) return;
const state={
currentSlideIndex: currentSlideIndex,
slideStartTime: slideStartTime,
slideDuration: currentSlideDuration,
timestamp: Date.now()
};
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
} catch (e){
}}
function loadSlideState(){
if(banners.length <=1) return null;
try {
const stateStr=localStorage.getItem(STORAGE_KEY);
if(!stateStr) return null;
const state=JSON.parse(stateStr);
const now=Date.now();
if(now - state.timestamp > 10 * 60 * 1000){
localStorage.removeItem(STORAGE_KEY);
return null;
}
return state;
} catch (e){
localStorage.removeItem(STORAGE_KEY);
return null;
}}
function checkMobile(){
requestAnimationFrame(function(){
isMobile=window.innerWidth <=768;
setBannerCSSVariables();
updateBannerHeight();
forceBannerHeight();
adjustBodyPadding();
});
}
var resizeTimer;
$(window).on('resize', function(){
clearTimeout(resizeTimer);
resizeTimer=setTimeout(checkMobile, 100);
});
function updateBannerHeight(){
const container=$('.fixed-banner-container');
if(container.length){
const height=isMobile ? mobileHeight:pcHeight;
container.css({
'height': height + 'px !important',
'min-height': height + 'px !important',
'max-height': height + 'px !important'
});
container.find('.banner-slides').css({
'height': height + 'px !important',
'min-height': height + 'px !important',
'max-height': height + 'px !important'
});
container.find('.banner-slide').css({
'height': height + 'px !important',
'min-height': height + 'px !important'
});
container.find('.banner-slide img').css({
'height': height + 'px !important',
'min-height': height + 'px !important'
});
adjustBodyPadding();
}}
function adjustBodyPadding(){
try {
const $container=$('.fixed-banner-container');
if($container.length){
const position=($container.attr('data-position')||'bottom');
const height=isMobile ? mobileHeight:pcHeight;
if(position==='bottom'){
document.body.style.paddingBottom=height + 'px';
}else{
document.body.style.paddingBottom='';
}}else{
document.body.style.paddingBottom='';
}} catch (e){  }}
function initSlider(){
$('.banner-slide').removeClass('active prev');
if(banners.length <=1){
if(banners.length===1){
$('.banner-slide').addClass('active');
startSingleBannerTimer();
}
return;
}
const savedState=loadSlideState();
if(savedState){
const now=Date.now();
const elapsedTime=Math.floor((now - savedState.slideStartTime) / 1000);
const remainingTime=savedState.slideDuration - elapsedTime;
if(remainingTime > 0){
currentSlideIndex=savedState.currentSlideIndex;
currentSlideDuration=savedState.slideDuration;
slideStartTime=savedState.slideStartTime;
showSlide(currentSlideIndex, true);
startAutoSlideWithRemainingTime(remainingTime);
}else{
const skippedSlides=Math.floor(Math.abs(remainingTime) / 5) + 1;
const newIndex=(savedState.currentSlideIndex + skippedSlides) % banners.length;
currentSlideIndex=newIndex;
showSlide(currentSlideIndex);
startAutoSlide();
}}else{
currentSlideIndex=0;
showSlide(0);
startAutoSlide();
}}
function startSingleBannerTimer(){
const duration=parseInt(banners[0].duration)||5;
let timeLeft=duration;
const timerElement=$('.banner-timer .timer-count');
const countdownElement=showCountdown ? $('.banner-countdown'):$();
const countdown=setInterval(function(){
timeLeft--;
if(timerElement.length){
timerElement.text(timeLeft);
}
if(showCountdown&&countdownElement.length){
countdownElement.text(Math.max(0, timeLeft));
}
if(timeLeft <=0){
clearInterval(countdown);
restartSingleBannerTimer();
}}, 1000);
}
function restartSingleBannerTimer(){
setTimeout(function(){
const timerElement=$('.banner-timer .timer-count');
if(timerElement.length){
timerElement.text(banners[0].duration);
}
const countdownElement=showCountdown ? $('.banner-countdown'):$();
if(showCountdown&&countdownElement.length){
countdownElement.text(formatCountdown(parseInt(banners[0].duration)||5));
}
startSingleBannerTimer();
}, 1000);
}
function showSlide(index, skipAnimation=false){
if(!banners[index]) return;
const $slides=$('.banner-slide');
const $currentSlide=$slides.eq(currentSlideIndex);
const $nextSlide=$slides.eq(index);
if(!skipAnimation&&currentSlideIndex!==index){
$currentSlide.removeClass('active').addClass('prev');
$nextSlide.removeClass('prev').addClass('active');
$slides.not($currentSlide).not($nextSlide).removeClass('active prev');
}else{
$slides.removeClass('active prev');
$nextSlide.addClass('active');
}
currentSlideIndex=index;
currentSlideDuration=parseInt(banners[index].duration)||5;
$('.banner-timer .timer-count').text(currentSlideDuration);
if(showCountdown){
const $cd=$('.banner-countdown');
$cd.text(formatCountdown(currentSlideDuration));
try { $cd.css('background', countdownBg); } catch(e){}}
slideStartTime=Date.now();
saveSlideState();
}
function startAutoSlide(){
if(!isPlaying||banners.length <=1) return;
slideTimer=setTimeout(function(){
nextSlide();
}, currentSlideDuration * 1000);
if(showCountdown){
startCountdown(currentSlideDuration);
}}
function startAutoSlideWithRemainingTime(remainingSeconds){
if(!isPlaying||banners.length <=1) return;
let timeLeft=remainingSeconds;
const timerElement=$('.banner-timer .timer-count');
clearInterval(countdownInterval);
const countdown=setInterval(function(){
timeLeft--;
if(timerElement.length){
timerElement.text(Math.max(0, timeLeft));
}
const countdownElement=showCountdown ? $('.banner-countdown'):$();
if(showCountdown&&countdownElement.length){
countdownElement.text(formatCountdown(Math.max(0, timeLeft)));
}
if(timeLeft <=0){
clearInterval(countdown);
}}, 1000);
countdownInterval=countdown;
slideTimer=setTimeout(function(){
clearInterval(countdown);
nextSlide();
}, remainingSeconds * 1000);
}
function startCountdown(seconds){
clearInterval(countdownInterval);
let timeLeft=parseInt(seconds)||0;
const countdownElement=showCountdown ? $('.banner-countdown'):$();
if(showCountdown&&countdownElement.length){
countdownElement.text(formatCountdown(Math.max(0, timeLeft)));
try { countdownElement.css('background', countdownBg); } catch(e){}}
countdownInterval=setInterval(function(){
timeLeft--;
if(showCountdown&&countdownElement.length){
countdownElement.text(formatCountdown(Math.max(0, timeLeft)));
try { countdownElement.css('background', countdownBg); } catch(e){}}
if(timeLeft <=0){
clearInterval(countdownInterval);
}}, 1000);
}
function formatCountdown(n){
try {
return String(countdownFormat).replace('{n}', n);
} catch (e){
return n;
}}
function nextSlide(){
if(banners.length <=1) return;
const nextIndex=(currentSlideIndex + 1) % banners.length;
goToSlide(nextIndex);
}
function prevSlide(){
if(banners.length <=1) return;
const prevIndex=currentSlideIndex===0 ? banners.length - 1:currentSlideIndex - 1;
goToSlide(prevIndex);
}
function goToSlide(index){
if(index===currentSlideIndex||!banners[index]) return;
clearTimeout(slideTimer);
clearInterval(countdownInterval);
showSlide(index);
if(!isHovered){
startAutoSlide();
}}
function togglePlayPause(){
isPlaying = !isPlaying;
if(isPlaying){
startAutoSlide();
}else{
clearTimeout(slideTimer);
clearInterval(countdownInterval);
}}
$(document).on('click', '.banner-nav.banner-prev', function(e){
e.preventDefault();
e.stopPropagation();
prevSlide();
});
$(document).on('click', '.banner-nav.banner-next', function(e){
e.preventDefault();
e.stopPropagation();
nextSlide();
});
$(document).on('touchend', '.banner-nav.banner-prev', function(e){
e.preventDefault();
e.stopPropagation();
prevSlide();
});
$(document).on('touchend', '.banner-nav.banner-next', function(e){
e.preventDefault();
e.stopPropagation();
nextSlide();
});
let isHovered=false;
$(document).on('mouseenter', '.fixed-banner-container, .banner-slider, .banner-slide', function(){
isHovered=true;
if(isPlaying){
clearTimeout(slideTimer);
clearInterval(countdownInterval);
}});
$(document).on('mouseleave', '.fixed-banner-container, .banner-slider, .banner-slide', function(){
isHovered=false;
if(isPlaying&&banners.length > 1){
setTimeout(function(){
if(isPlaying&&banners.length > 1&&!isHovered){
startAutoSlide();
}}, 100);
}});
$('.fixed-banner-container, .banner-slider').on('touchstart', function(){
$(this).addClass('touched');
setTimeout(()=> {
$(this).removeClass('touched');
}, 3000);
});
let touchStartX=0;
let touchEndX=0;
$('.fixed-banner-container').on('touchstart', function(e){
touchStartX=e.originalEvent.changedTouches[0].screenX;
});
$('.fixed-banner-container').on('touchend', function(e){
touchEndX=e.originalEvent.changedTouches[0].screenX;
handleSwipe();
});
function handleSwipe(){
const swipeThreshold=50;
const diff=touchStartX - touchEndX;
if(Math.abs(diff) > swipeThreshold){
if(diff > 0){
nextSlide();
}else{
prevSlide();
}}
}
$(document).on('keydown', function(e){
if(!$('.fixed-banner-container').is(':visible')) return;
switch(e.key){
case 'ArrowLeft':
prevSlide();
break;
case 'ArrowRight':
nextSlide();
break;
case ' ':
e.preventDefault();
togglePlayPause();
break;
}});
$(window).on('beforeunload', function(){
saveSlideState();
});
setInterval(function(){
if(banners.length > 1&&isPlaying){
saveSlideState();
}}, 5000);
window.goToSlide=goToSlide;
window.nextSlide=nextSlide;
window.prevSlide=prevSlide;
window.togglePlayPause=togglePlayPause;
function setBannerCSSVariables(){
const root=document.documentElement;
root.style.setProperty('--banner-height', pcHeight + 'px');
root.style.setProperty('--banner-mobile-height', mobileHeight + 'px');
}
function forceBannerHeight(){
setBannerCSSVariables();
const containers=document.querySelectorAll('.fixed-banner-container');
const currentIsMobile=isMobile;
containers.forEach(container=> {
const height=currentIsMobile ? mobileHeight:pcHeight;
container.classList.add('loading');
container.style.setProperty('height', height + 'px', 'important');
container.style.setProperty('min-height', height + 'px', 'important');
container.style.setProperty('max-height', height + 'px', 'important');
const slides=container.querySelector('.banner-slides');
if(slides){
slides.style.setProperty('height', height + 'px', 'important');
slides.style.setProperty('min-height', height + 'px', 'important');
slides.style.setProperty('max-height', height + 'px', 'important');
}
const slideElements=container.querySelectorAll('.banner-slide');
slideElements.forEach(slide=> {
slide.style.setProperty('height', height + 'px', 'important');
slide.style.setProperty('min-height', height + 'px', 'important');
});
const images=container.querySelectorAll('.banner-slide img');
images.forEach(img=> {
img.style.setProperty('height', height + 'px', 'important');
img.style.setProperty('min-height', height + 'px', 'important');
});
});
}
(function(){
forceBannerHeight();
if(typeof adjustBodyPadding==='function'){
try { adjustBodyPadding(); } catch (e){}}
if(document.readyState==='loading'){
document.addEventListener('DOMContentLoaded', function(){
forceBannerHeight();
if(typeof adjustBodyPadding==='function'){
try { adjustBodyPadding(); } catch (e){}}
});
}else{
forceBannerHeight();
if(typeof adjustBodyPadding==='function'){
try { adjustBodyPadding(); } catch (e){}}
}})();
$(document).ready(function(){
updateBannerHeight();
forceBannerHeight();
const isDeferred=(typeof window.bannerSlideDeferred!=='undefined') ? window.bannerSlideDeferred:false;
const CACHE_KEY='banner_slide_visited_v1';
const hasVisited=localStorage.getItem(CACHE_KEY);
if(isDeferred){
const delayTime=hasVisited ? 0:5000;
setTimeout(function(){
renderBanners(banners);
initSlider();
$('.fixed-banner-container').addClass('loaded').removeClass('loading');
updateBannerHeight();
forceBannerHeight();
adjustBodyPadding();
try {
localStorage.setItem(CACHE_KEY, 'true');
} catch(e){}
checkVersionAndRefresh();
}, delayTime);
}else{
initSlider();
setTimeout(function(){
$('.fixed-banner-container').addClass('loaded').removeClass('loading');
updateBannerHeight();
forceBannerHeight();
adjustBodyPadding();
}, 500);
checkVersionAndRefresh();
}});
function renderBanners(data){
const $container=$('.fixed-banner-container');
if(!$container.length||!data||data.length===0) return;
let html='';
const height=isMobile ? mobileHeight:pcHeight;
html +=`<div class="banner-slides" style="height: ${height}px !important; min-height: ${height}px !important; max-height: ${height}px !important;">`;
data.forEach((banner, index)=> {
let mobileImg=banner.image_url;
if(banner.updated_at) mobileImg +=(mobileImg.indexOf('?') > -1 ? '&':'?') + 'v=' + encodeURIComponent(banner.updated_at);
let pcImg=banner.pc_image_url ? banner.pc_image_url:banner.image_url;
if(banner.updated_at) pcImg +=(pcImg.indexOf('?') > -1 ? '&':'?') + 'v=' + encodeURIComponent(banner.updated_at);
const linkStart=banner.link_url ? `<a href="${banner.link_url}" target="_parent">`:'';
const linkEnd=banner.link_url ? '</a>':'';
const countdownHtml=showCountdown ? '<div class="banner-countdown" aria-hidden="true"></div>':'';
const loadingAttr=index===0 ? 'eager':'lazy';
const safeTitle=banner.title ? banner.title.replace(/"/g, '&quot;'):'';
html +=`
<div class="banner-slide" data-duration="${banner.duration}" data-index="${index}" style="height: ${height}px !important; min-height: ${height}px !important;">
${linkStart}
<img src="${mobileImg}" alt="${safeTitle}" loading="${loadingAttr}" height="${height}" class="banner-image-mobile" style="height: ${height}px !important; min-height: ${height}px !important;">
<img src="${pcImg}" alt="${safeTitle}" loading="${loadingAttr}" height="${height}" class="banner-image-pc" style="height: ${height}px !important; min-height: ${height}px !important;">
${linkEnd}
${countdownHtml}
</div>
`;
});
html +='</div>';
if(data.length > 1){
html +=`
<button class="banner-nav banner-prev" aria-label="이전 배너" title="이전 배너">‹</button>
<button class="banner-nav banner-next" aria-label="다음 배너" title="다음 배너">›</button>
`;
}
$container.html(html);
}
function checkVersionAndRefresh(){
try {
const ajaxUrl=(window.bannerSlideGlobal&&window.bannerSlideGlobal.ajaxUrl) ? window.bannerSlideGlobal.ajaxUrl:null;
const currentVersion=(window.bannerSlideGlobal&&window.bannerSlideGlobal.contentVersion) ? String(window.bannerSlideGlobal.contentVersion):'0';
if(ajaxUrl){
$.ajax({
url: ajaxUrl,
type: 'GET',
data: { action: 'banner_slide_get_version' },
cache: false
}).done(function(resp){
const remoteV=resp&&resp.success&&resp.v ? String(resp.v):null;
if(!remoteV||remoteV===currentVersion){
return;
}
$.ajax({
url: ajaxUrl,
type: 'GET',
data: { action: 'banner_slide_render_fixed' },
cache: false
}).done(function(r2){
if(r2&&r2.success&&r2.html){
const $wrapper=$('.fixed-banner-container').first();
if($wrapper.length){
$wrapper.replaceWith(r2.html);
setTimeout(function(){
updateBannerHeight();
forceBannerHeight();
adjustBodyPadding();
try {
if(typeof window.bannerSlideData!=='undefined'){
banners=window.bannerSlideData;
currentSlideIndex=0;
$('.banner-slide').removeClass('active prev');
showSlide(0, true);
startAutoSlide();
}} catch (e){  }}, 10);
}}
});
});
}} catch (e){  }}
$(function(){
updateBannerHeight();
forceBannerHeight();
adjustBodyPadding();
});
$(window).on('load', function(){
updateBannerHeight();
forceBannerHeight();
adjustBodyPadding();
});
const bannerObserver=new MutationObserver(function(mutations){
mutations.forEach(function(mutation){
if(mutation.type==='childList'){
mutation.addedNodes.forEach(function(node){
if(node.nodeType===Node.ELEMENT_NODE){
if(node.classList&&node.classList.contains('fixed-banner-container')){
setTimeout(function(){
forceBannerHeight();
updateBannerHeight();
}, 10);
}else if(node.querySelector&&node.querySelector('.fixed-banner-container')){
setTimeout(function(){
forceBannerHeight();
updateBannerHeight();
}, 10);
}}
});
}});
});
bannerObserver.observe(document.body, {
childList: true,
subtree: true
});
if(typeof document.hidden!=="undefined"){
$(document).on('visibilitychange', function(){
if(document.hidden){
clearTimeout(slideTimer);
clearInterval(countdownInterval);
saveSlideState();
}else if(isPlaying){
const savedState=loadSlideState();
if(savedState&&banners.length > 1){
const now=Date.now();
const elapsedTime=Math.floor((now - savedState.slideStartTime) / 1000);
const remainingTime=savedState.slideDuration - elapsedTime;
if(remainingTime > 0){
startAutoSlideWithRemainingTime(remainingTime);
}else{
nextSlide();
}}else{
startAutoSlide();
}}
});
}});