PageSourceSearch

https://olive-tree.shop/ind-script/optimizer_user.php?filename=lZN…6bd9365d746d6185df572bf&t=1787720196&user=T

js olive-tree.shop collected 2026-10-08 14:52:12 UTC 128,481 bytes, 3,506 lines download raw bytes

1// 메인 비주얼 슬라이드
2const visual_A_a = new Swiper('.visual_A_a', {
3    slidesPerView: 'auto',
4    speed: 800,
5    loop: true,
6    observer: true,
7    observeParents: true,
8    autoplay: {
9        delay: 5000,
10        disableOnInteraction: false,
11    },
12    pagination: {
13        el: '.swiper-pagination',
14        clickable: true,
15        renderBullet: function (index, className) {
16            return `<span class="${className}"><span class="progress-bar"></span></span>`;
17        },
18    },
19    navigation: {
20        nextEl: '.swiper-button-next',
21        prevEl: '.swiper-button-prev',
22    },
23});
24
25/*
26수동추가
27디바이스에 따라서 배너 텍스트 색상 변경하기 위해서 색상 변경 로직 추가
28["black", "black", "black"], ["white", "black", "black"] 코드상 치환
29*/
30// 디바이스 타입 감지 함수 (CSS @container 767px 기준)
31function getDeviceType() {
32    return window.innerWidth <= 767 ? 'Mobile' : 'PC';
33}
34
35// 현재 디바이스 타입 추적 변수
36let currentDeviceType = getDeviceType();
37
38// 슬라이드별 텍스트 색상 설정 배열
39const textColorSettings = ["black", "black", ""];
40const mobileTextColorSettings = ["white", "black", "white"];
41
42// 텍스트 색상 클래스 업데이트 함수
43function updateTextColor(slideIndex) {
44    const slides = document.querySelectorAll('.visual_A_a .swiper-slide');
45    slides.forEach((slide) => {
46        const textBox = slide.querySelector('.text_box');
47        const deviceType = getDeviceType();
48        const textColor = deviceType === 'Mobile' ? mobileTextColorSettings : textColorSettings;
49        const slideDataIndex = parseInt(slide.getAttribute('data-swiper-slide-index'));
50
51        if (textBox && slideDataIndex === slideIndex) {
52            // 기존 text_btn_white 클래스 제거
53            textBox.classList.remove('text_btn_white');
54            // 해당 슬라이드가 현재 슬라이드이고 설정이 white인 경우 클래스 추가
55            if (textColor[slideDataIndex] === 'white') {
56                textBox.classList.add('text_btn_white');
57            }
58        }
59    });
60}
61
62// 슬라이드 이동 시마다 현재 슬라이드 번호 추적 및 텍스트 색상 업데이트
63visual_A_a.on('slideChange', function() {
64    // 텍스트 색상 업데이트
65    updateTextColor(this.realIndex);
66});
67
68// 초기 텍스트 색상 설정
69updateTextColor(visual_A_a.realIndex);
70
71// 화면 크기 변경 시 디바이스 타입 변화 감지 및 텍스트 색상 업데이트
72window.addEventListener('resize', function() {
73    const newDeviceType = getDeviceType();
74
75    // 디바이스 타입이 변경된 경우에만 텍스트 색상 업데이트 실행
76    if (newDeviceType !== currentDeviceType) {
77        currentDeviceType = newDeviceType;
78        updateTextColor(visual_A_a.realIndex);
79    }
80});
81const hasLeftArea = document.body.querySelector('.left_area') !== null;
82
83let swiperOptions = {
84    spaceBetween: 14,
85    slidesPerView: 4.1, // 기본 모바일용
86    observer: true,
87    observeParents: true,
88    breakpoints: {
89        1025: {
90            spaceBetween: 45,
91            slidesPerView: 'auto',
92        }
93    },
94    freeMode: {
95        enabled: true,
96        sticky: true,
97    },
98    grabCursor: true,
99};
100
101// 일체형의 .left_area가 있을 때만 breakpoints 적용
102if (hasLeftArea) {
103    swiperOptions.breakpoints = {
104        1025: {
105            spaceBetween: 14,
106            slidesPerView: 'auto',
107        }
108    };
109}
110
111let cateHighlightSwiper = new Swiper(".cate_highlight_B .cate_highlight_swiper", swiperOptions);
112
113// 디바운스 함수 선언
114function debounce(func, wait = 200) {
115    let timeout;
116    return function () {
117        clearTimeout(timeout);
118        timeout = setTimeout(() => func.apply(this, arguments), wait);
119    };
120}
121
122// 리사이즈 시 Swiper 업데이트
123const updateSwiper = debounce(() => {
124    if (cateHighlightSwiper) {
125        cateHighlightSwiper.update();
126    }
127
128    // 모바일일체형에서 1024px 이상일 때 swiper-slide의 width 속성 제거
129    if (hasLeftArea && window.innerWidth > 1024) {
130        const swiperSlides = document.querySelectorAll(".cate_highlight_B .cate_highlight_swiper .swiper-slide");
131        swiperSlides.forEach(slide => {
132            if (slide && slide.style.width) {
133                slide.style.removeProperty("width");
134            }
135        });
136    }
137}, 0);
138
139window.addEventListener("resize", updateSwiper);
140let productSwiper;
141
142function product_list_A_c_swiper() {
143    const container = document.querySelector('#container');
144    const containerWidth = container.offsetWidth;
145
146    let spaceBetween = 10;
147
148    if (containerWidth >= 1025) {
149        spaceBetween = 20;
150    }
151
152    productSwiper = new Swiper('.product_list_A_c .product_swiper', {
153        speed: 800,
154        loop: false,
155        loopAdditionalSlides: 1,
156        observer: true,
157        observeParents: true,
158        resizeObserver: true,
159        scrollbar: {
160            el: ".swiper-scrollbar",
161            draggable: true,
162        },
163        slidesPerView: 'auto',
164        spaceBetween: spaceBetween,
165    });
166}
167
168product_list_A_c_swiper();
169
170window.addEventListener('resize', () => {
171    if (productSwiper) productSwiper.destroy(true, true);
172    product_list_A_c_swiper();
173});
174const prdList_F_a_tabCategory = document.querySelector(".product_list_F_a .tab_category");
175const prdList_F_a_content = document.querySelectorAll(".product_list_F_a .content_box");
176const prdList_F_a_selectBox = document.querySelector(".product_list_F_a #tab_select");
177
178// 탭 & select 초기화
179// prdList_F_a_content.forEach((box, index) => {
180//     const moduleNameEl = box.querySelector(".module_title div");
181//     const moduleName = moduleNameEl ? moduleNameEl.textContent.trim() : `탭 ${index + 1}`;
182
183//     const li = document.createElement("li");
184//     if (index === 0) li.classList.add("active");
185//     const a = document.createElement("a");
186//     a.href = "#";
187//     a.textContent = moduleName;
188//     li.appendChild(a);
189//     prdList_F_a_tabCategory.appendChild(li);
190
191//     const option = document.createElement("option");
192//     option.value = index;
193//     option.textContent = moduleName;
194//     prdList_F_a_selectBox.appendChild(option);
195// });
196
197// 탭 클릭 이벤트 다시 연결
198const prdList_F_a_tabItems = document.querySelectorAll(".product_list_F_a .tab_category li");
199
200prdList_F_a_tabItems.forEach((tab, index) => {
201    tab.addEventListener("click", function (e) {
202        e.preventDefault();
203        prdList_F_a_tabItems.forEach(t => t.classList.remove("active"));
204        tab.classList.add("active");
205
206        prdList_F_a_content.forEach(c => c.classList.remove("active"));
207        prdList_F_a_content[index].classList.add("active");
208
209        prdList_F_a_selectBox.selectedIndex = index;
210    });
211});
212
213// select 박스 변경 시 콘텐츠 전환
214prdList_F_a_selectBox.addEventListener("change", function () {
215    const selectedIndex = parseInt(this.value, 10);
216
217    prdList_F_a_tabItems.forEach(t => t.classList.remove("active"));
218    if (prdList_F_a_tabItems[selectedIndex]) {
219        prdList_F_a_tabItems[selectedIndex].classList.add("active");
220    }
221
222    prdList_F_a_content.forEach(c => c.classList.remove("active"));
223    if (prdList_F_a_content[selectedIndex]) {
224        prdList_F_a_content[selectedIndex].classList.add("active");
225    }
226});
227/**
228 * Banner Jquery Plug-in
229 * @author  cafe24
230 */
231
232(function($){
233
234    $.fn.floatBanner = function(options) {
235        options = $.extend({}, $.fn.floatBanner.defaults , options);
236
237        return this.each(function() {
238            var aPosition = $(this).position();
239            var jbOffset = $(this).offset();
240            var node = this;
241
242            $(window).on('scroll', function() {
243                var _top = $(document).scrollTop();
244                _top = (aPosition.top < _top) ? _top : aPosition.top;
245
246                setTimeout(function () {
247                    var newinit = $(document).scrollTop();
248
249                    if ( newinit > jbOffset.top ) {
250                        _top -= jbOffset.top;
251                        var container_height = $("#wrap").height();
252                        var quick_height = $(node).height();
253                        var cul = container_height - quick_height;
254                        if(_top > cul){
255                            _top = cul;
256                        }
257                    } else {
258                        _top = 0;
259                    }
260
261                    $(node).stop().animate({top: _top}, options.animate);
262                }, options.delay);
263            });
264        });
265    };
266
267    $.fn.floatBanner.defaults = {
268        'animate'  : 500,
269        'delay'    : 500
270    };
271
272})(jQuery);
273
274/**
275 * 문서 구동후 시작
276 */
277$(function(){
278    $('#banner:visible, #quick:visible').floatBanner();
279
280    //placeholder
281    $(".ePlaceholder input, .ePlaceholder textarea").each(function(i){
282        var placeholderName = $(this).parents().attr('title');
283        $(this).attr("placeholder", placeholderName);
284    });
285    /* placeholder ie8, ie9 */
286    $.fn.extend({
287        placeholder : function() {
288            //IE 8 버전에는 hasPlaceholderSupport() 값이 false를 리턴
289           if (hasPlaceholderSupport() === true) {
290                return this;
291            }
292            //hasPlaceholderSupport() 값이 false 일 경우 아래 코드를 실행
293            return this.each(function(){
294                var findThis = $(this);
295                var sPlaceholder = findThis.attr('placeholder');
296                if ( ! sPlaceholder) {
297                   return;
298                }
299                findThis.wrap('<label class="ePlaceholder" />');
300                var sDisplayPlaceHolder = $(this).val() ? ' style="display:none;"' : '';
301                findThis.before('<span' + sDisplayPlaceHolder + '>' + sPlaceholder + '</span>');
302                this.onpropertychange = function(e){
303                    e = event || e;
304                    if (e.propertyName == 'value') {
305                        $(this).trigger('focusout');
306                    }
307                };
308                //공통 class
309                var agent = navigator.userAgent.toLowerCase();
310                if (agent.indexOf("msie") != -1) {
311                    $(".ePlaceholder").css({"position":"relative"});
312                    $(".ePlaceholder span").css({"position":"absolute", "padding":"0 4px", "color":"#878787"});
313                    $(".ePlaceholder label").css({"padding":"0"});
314                }
315            });
316        }
317    });
318
319    $(':input[placeholder]').placeholder(); //placeholder() 함수를 호출
320
321    //클릭하면 placeholder 숨김
322    $('body').on('click', '.ePlaceholder span', function(){
323        $(this).hide();
324    });
325
326    //input창 포커스 인 일때 placeholder 숨김
327    $('body').on('focusin', '.ePlaceholder :input', function(){
328        $(this).prev('span').hide();
329    });
330
331    //input창 포커스 아웃 일때 value 가 true 이면 숨김, false 이면 보여짐
332    $('body').on('focusout', '.ePlaceholder :input', function(){
333        if (this.value) {
334            $(this).prev('span').hide();
335        } else {
336            $(this).prev('span').show();
337        }
338    });
339
340    //input에 placeholder가 지원이 되면 true를 안되면 false를 리턴값으로 던져줌
341    function hasPlaceholderSupport() {
342        if ('placeholder' in document.createElement('input')) {
343            return true;
344        } else {
345            return false;
346        }
347    }
348});
349
350/**
351 *  썸네일 이미지 엑박일경우 기본값 설정
352 */
353$(window).on('load', function() {
354    $("img.thumb,img.ThumbImage,img.BigImage").each(function($i,$item){
355        var $img = new Image();
356        $img.onerror = function () {
357            $item.src="//img.echosting.cafe24.com/thumb/img_product_big.gif";
358        }
359        $img.src = this.src;
360    });
361});
362
363/**
364 *  tooltip
365 */
366$('.eTooltip').each(function(i){
367    $(this).find('.btnClose').attr('tabIndex','-1');
368});
369//tooltip input focus
370$('.eTooltip').find('input').on('focus', function() {
371    var targetName = returnTagetName(this);
372    targetName.siblings('.ec-base-tooltip').show();
373});
374$('.eTooltip').find('input').on('focusout', function() {
375    var targetName = returnTagetName(this);
376    targetName.siblings('.ec-base-tooltip').hide();
377});
378function returnTagetName(_this){
379    var ePlacename = $(_this).parent().attr("class");
380    var targetName;
381    if(ePlacename == "ePlaceholder"){ //ePlaceholder 대응
382        targetName = $(_this).parents();
383    }else{
384        targetName = $(_this);
385    }
386    return targetName;
387}
388
389/**
390 *  eTab
391 */
392$("body").on("click", ".eTab a", function(e){
393    // 클릭한 li 에 selected 클래스 추가, 기존 li에 있는 selected 클래스는 삭제.
394    var _li = $(this).parent("li").addClass("selected").siblings().removeClass("selected"),
395    _target = $(this).attr("href"),
396    _siblings = $(_target).attr("class"),
397    _arr = _siblings.split(" "),
398    _classSiblings = "."+_arr[0];
399
400    //클릭한 탭에 해당하는 요소는 활성화, 기존 요소는 비활성화 함.
401    $(_target).show().siblings(_classSiblings).hide();
402
403
404    //preventDefault 는 a 태그 처럼 클릭 이벤트 외에 별도의 브라우저 행동을 막기 위해 사용됨.
405    e.preventDefault();
406});
407
408
409
410window.addEventListener('load', function(){
411	bottomNav();
412    fixedHeader();
413    handleNav();
414    //quickGoTop(); 사용안함 210805 서정환 수정
415    searchLayer();
416    //toggleClass('.xans-layout-info.info__customer', '.xans-layout-info.info__customer .toggle', 'selected'); 사용안함 210805 서정환 수정
417    //topBanner(); 사용안함 210804 서정환 수정
418	handleScroll();
419});
420
421function handleScroll(){
422	var scrollPosition = 0;
423	var ticking = false;
424	var quickMenu = document.querySelector('#quick');
425	var scrollY = window.scrollY || window.pageYOffset;
426	//setQuickScrollEvent(scrollY, quickMenu); 사용안함 210805 서정환 수정
427	window.addEventListener('scroll', function(e) {
428        scrollPosition = window.scrollY || window.pageYOffset;
429        if (ticking) return;
430        window.requestAnimationFrame(function() {
431            fixedHeader()
432            //setQuickScrollEvent(scrollPosition, quickMenu) 사용안함 210805 서정환 수정
433            ticking = false;
434        });
435        ticking = true;
436	});
437}
438
439function toggleClass(element, handler, className){
440	var _handler = document.querySelector(handler);
441	var _element = document.querySelector(element);
442
443    _handler.addEventListener('click', function(){
444        if ( _element.classList.contains(className) ) {
445            _element.classList.remove( className );
446        } else {
447            _element.classList.add( className );
448        }
449    });
450}
451
452function fixedHeader() { // 210804 서정환 수정
453    let header = document.getElementById("header");
454    let headerL = document.querySelector("header_L");
455    let headerR = document.querySelector("header_R");
456    let fixed_margin = document.getElementById("contents");
457    let topBanner = document.querySelector(".top_banner");
458    let TopBannerHeight = topBanner ? topBanner.offsetHeight : 0;
459    let scrollY = window.pageYOffset || document.documentElement.scrollTop;
460    let header_height = header.offsetHeight;
461	let bottomNav = document.querySelector(".bottom_nav");
462
463	if(bottomNav){ // 모바일 일체형일 경우
464		let logo = document.querySelector("#header .inner .top_nav_box");
465    	let logoHeight = logo ? logo.offsetHeight : 0;
466
467		if (scrollY >
467 TopBannerHeight + logoHeight) {
468			header.classList.add("fixed");
469			header.style.top = '-' + logoHeight + 'px';
470			fixed_margin.style.marginTop = header_height + 'px';
471		} else {
472			header.classList.remove("fixed");
473			header.style.top = '0px';
474			fixed_margin.style.marginTop = '0px';
475		}
476	} else {
477		if (scrollY > TopBannerHeight) {
478			if (!(!(headerL || headerR) && window.innerWidth >= 1024)) { // pc 좌우형일때는 작동하지 않음
479				header.classList.add("fixed");
480				fixed_margin.style.marginTop = header_height + 'px';
481			}
482			
483		} else {
484			header.classList.remove("fixed");
485			fixed_margin.style.marginTop = '0px';
486		}
487	}
488}
489
490function handleNav() {
491    var btnNavs = document.querySelectorAll('.eNavFold');
492    var btnCloses = document.querySelectorAll('#aside .btnClose, #aside + .btnClose');
493    var dimmed = document.querySelector('#layoutDimmed');
494    btnNavs.forEach( function(btnNav) {
495        btnNav.addEventListener('click', function(){
496            document.body.classList.toggle('expand');
497			if(document.body.classList.contains('searchExpand')){
498				document.body.classList.remove('searchExpand');
499			}
500        });
501    });
502	btnCloses.forEach(function(btnClose){
503		btnClose.addEventListener('click', function(){
504			document.body.classList.remove('expand');
505		});
506	});
507    handleDimmed(dimmed, document.body, 'expand');
508}
509
510function searchLayer() {
511    var btnSearchs = document.querySelectorAll('.eSearch');
512    var btnClose = document.querySelector('.xans-layout-searchheader  .btnClose');
513    btnSearchs.forEach( function(btnSearch) {
514        btnSearch.addEventListener('click', function(){
515            document.body.classList.add('searchExpand');
516			if(document.body.classList.contains('expand')){
517				document.body.classList.remove('expand');
518			}
519            var input = document.querySelector('#keyword');
520            //input.focus();
521        });
522    });
523	if(btnClose){
524		btnClose.addEventListener('click', function(){
525			document.body.classList.remove('searchExpand');
526		});
527	}
528    var dimmed = document.querySelector('#layoutDimmed');
529    handleDimmed(dimmed, document.body, 'searchExpand');
530}
531
532function handleDimmed(target, element, className){
533	if(target){
534		target.addEventListener('click', function(){
535			element.classList.remove(className);
536		});
537	}
538}
539
540function bottomScroll(){
541    var lastScrollTop = 0;
542    var delta = 5;
543    var fixBox = document.querySelector('.bottom-nav__top');
544    var fixBoxHeight = fixBox.offsetHeight;
545    var didScroll;
546
547    window.onscroll = function(e) {
548        didScroll = true;
549    };
550
551    setInterval(function(){
552        if(didScroll){
553            hasScrolled();
554            didScroll = false;
555        }
556    }, 250);
557
558    function hasScrolled(){
559        var nowScrollTop = window.scrollY;
560        if(Math.abs(lastScrollTop - nowScrollTop) <= delta){
561            return;
562        }
563        if(nowScrollTop > lastScrollTop && nowScrollTop > fixBoxHeight){
564            //Scroll down
565            var scrollTop = window.scrollTop();
566            var innerHeight = window.innerHeight();
567            var scrollHeight = $('body').prop('scrollHeight');
568            if (scrollTop + innerHeight >= scrollHeight) {
569                fixBox.classList.add('bottom-nav--hide');
570                return true;
571            }
572        }else{
573            if(nowScrollTop + window.innerHeight < document.body.offsetHeight){
574                //Scroll up
575                fixBox.classList.remove('bottom-nav--hide');
576            }
577        }
578        lastScrollTop = nowScrollTop;
579    }
580}
581
582function bottomNav(){
583    var lastScrollTop = 0;
584    var btnTop = document.querySelector('.bottom-nav__top');
585    var fixedButton = document.getElementById("orderFixArea");
586    if(fixedButton){
587        document.body.classList.add("button--fixed");
588    };
589
590	window.addEventListener("scroll", function(){
591		var scroll = window.pageYOffset || document.documentElement.scrollTop;
592        var nav = document.querySelector('.bottom-nav');
593        if(nav){
594            if (scroll > lastScrollTop){
595                nav.classList.add('bottom-nav--hide');
596            } else {
597                nav.classList.remove('bottom-nav--hide');
598            }
599
600			// scroll bottom
601			if(scroll === document.body.scrollHeight - document.documentElement.offsetHeight){
602				nav.classList.remove('bottom-nav--hide');
603			}
604        }
605		lastScrollTop = scroll <= 0 ? 0 : scroll;
606
607        // top button
608        var currentScrollPercentage = getCurrentScrollPercentage();
609        if(btnTop){
610            if(currentScrollPercentage > 30){
611                btnTop.classList.add('bottom-nav__top--show');
612            } else {
613                btnTop.classList.remove('bottom-nav__top--show');
614            }
615        }
616	});
617
618	if(btnTop){
619		btnTop.addEventListener('click', function(){
620			window.scrollTo({
621			  top: 0,
622			  behavior: 'smooth'
623			});
624		});
625	}
626}
627
628function getOffset(element){
629    if (!element.getClientRects().length)
630    {
631      return { top: 0, left: 0 };
632    }
633
634    var rect = element.getBoundingClientRect();
635    var win = element.ownerDocument.defaultView;
636    return (
637    {
638      top: rect.top + win.pageYOffset,
639      left: rect.left + win.pageXOffset
640    });
641}
642
643function getQuickPosition(){
644	var role = document.querySelector("meta[name='path_role']").getAttribute('content');
645	if (role === "MAIN") {
646		return getMainQuickPosition();
647	} else {
648		return getSubQuickPosition();
649	}
650}
651
652function getMainQuickPosition(){
653	var quickMenu = document.querySelector('#quick');
654	var collection = document.querySelector('.collection');
655	var snsItem = document.querySelector('.snsItem');
656
657	var mainTopSpace = 115;
658	var mainFooterSpace = 34;
659
660	var top = collection.offsetTop + collection.clientHeight + mainTopSpace;
661    var footTop = getOffset(snsItem).top + mainFooterSpace;
662	var maxY = footTop - quickMenu.offsetHeight;
663
664	return [top, maxY]
665}
666
667function getSubQuickPosition(){
668	var quickMenu = document.querySelector('#quick');
669	var footer = document.querySelector("#footer");
670
671	var footerSpace = 60;
672	var top = 284;
673    var footTop = getOffset(footer).top;
674	var maxY = footTop - quickMenu.offsetHeight - footerSpace;
675
676	return [top, maxY]
677}
678
679function setQuickScrollEvent(y, quick){
680	var header = document.querySelector('#header');
681	var position = getQuickPosition();
682	var scrollY = y;
683	if (scrollY >= position[0] - header.offsetHeight){
684		if (scrollY < position[1]) {
685			quick.classList.add('fixed');
686			quick.removeAttribute('style');
687        } else {
688			quick.classList.remove('fixed');
689			quick.style.position = 'absolute';
690			quick.style.top = position[1] + 'px';
691        }
692	} else {
693		quick.style.top = position[0] + 'px';
694        quick.classList.remove('fixed');
695    }
696}
697
698function quickGoTop(){
699    var btnTop = document.querySelector('#quick .pageTop');
700	btnTop.addEventListener('click', function(){
701        window.scrollTo({
702          top: 0,
703          behavior: 'smooth'
704        });
705    });
706}
707
708function topBanner(){
709    var banner = document.querySelector('#topBanner');
710    if(!banner) return;
711    var btnClose = banner.querySelector('.btnClose');
712    btnClose.addEventListener('click', function(){
713        banner.classList.add("hidden");
714    });
715}
716
717
718function getCurrentScrollPercentage(){
719	return (window.scrollY + window.innerHeight) / document.body.clientHeight * 100
720}
721
722
723jQuery(document).ready(function() {
724
725	/* 카테고리가 대량일때 나머지 숨김
726	jQuery("#header .inner .top_nav_box .top_category").each(function(){
727		var top_category_length = jQuery(' > ul > li',this).length;
728		if ( top_category_length > 20 ) {
729			jQuery(this).append('<div class="cate_more"></div>');
730		}
731		jQuery(' > ul > li:lt(20)',this).show();
732	}); */
733
734	/* 카테고리가 대량일때 이상일때 출력버튼
735	jQuery("#header .inner .top_nav_box .top_category .cate_more").click(function() {
736		var cate_more_on = jQuery(this).hasClass('on');
737		if ( cate_more_on == false )  {
738			jQuery('#header .inner .top_nav_box .top_category > ul > li').show();
739			jQuery('#header .inner .top_nav_box .top_category .cate_more').addClass("on");
740		} else {
741			jQuery('#header .inner .top_nav_box .top_category .cate_more').removeClass("on");
742			jQuery('#header .inner .top_nav_box .top_category > ul > li').hide();
743			jQuery('#header .inner .top_nav_box .top_category > ul > li:lt(20)').show();
744		}
745	}); */
746
747	/* 최상단배너 하루동안 닫기 - 서정환 */
748    jQuery(".main_top_banner .top_banner_box_inner .top_banner_close .icon").bind("click", function() {
749		if(jQuery("#top_banner_box_cloase").is(":checked")){
750			jQuery(".main_top_banner").slideUp("fast");
751			setCookiem("top_banner_cookie", "top_banner_cookie", 1);
752		 } else {
753			jQuery(".main_top_banner").slideUp("fast");
754		 }
755    });
756	var main_top_banner_diplay = jQuery(".main_top_banner").attr("data-ez-display");
757	if (!getCookiem("top_banner_cookie") && (main_top_banner_diplay == 'visible')) {
758		jQuery(".main_top_banner").slideDown("fast");
759	}
760
761	/* 최상단배너 닫기버튼 없을시 높이 수정 */
762	if(jQuery(".top_banner_close").css("display") == "none"){
763		jQuery(".main_top_banner").addClass('close_none');
764		if (main_top_banner_diplay == 'visible') {
765			jQuery(".main_top_banner").slideDown("fast");
766		}
767	}
768
769	/* 상단 고객센터 - 서정환 */
770	jQuery("#header .inner .toparea .toparea_state .toparea_state_board").click(function() {
771		var theme_cl = jQuery(this).attr('class');
772		jQuery(this).toggleClass('on');
773	});
774
775	/* 로그인폼 placeholder 추가 - 서정환 */
776	if (jQuery('.xans-member-login').val() != undefined) {
777		jQuery('#member_passwd').attr('placeholder', '비밀번호');
778	}
779
780	/* 비회원 주문조회페이지 placeholder 추가 - 서정환 */
781	setTimeout(function(){
782		if (jQuery('.xans-myshop-orderhistorynologin').val() != undefined) {
783			jQuery('#order_name').attr('placeholder', '주문자명');
784			jQuery('#order_id').attr('placeholder', '주문번호(하이픈(-) 포함)');
785			jQuery('#order_password').attr('placeholder', '비회원주문 비밀번호');
786		}
787	}, 100);
788
789	/* 검색페이지 인풋박스에서 텍스트 삭제 - 서정환 */
790	jQuery('#ec-product-searchdata-searchkeyword_form').find('button.btnDelete').bind('click', function() {
791		jQuery('#ec-product-searchdata-keyword').val('').focus();
792	});
793
794	/* 검색페이지 정렬 텍스트 변경 */
795	jQuery("#order_by").each(function(){
796		jQuery('option:first-child', this).text('- 정렬방식 -');
797	});
798
799	/* 멀티샵 없을경우 숨김 */
800	jQuery(".xans-layout-multishoplist").each(function(){
801		var multishoplist_count = jQuery('li', this).length;
802		if ( multishoplist_count == 1 ) {
803			jQuery(this).hide();
804		}
805	});
806
807	/* 하단 에스크로 사용하면 출력 */
808	jQuery("#footer .inner .bt_escrow").each(function(){
809		var bt_escrow = jQuery(this).attr("data-ez-escrow");
810		if ( !bt_escrow == '' ) {
811			var bt_escrow_name = jQuery("a img[data-ez-escrow-id="+ bt_escrow +"]", this).addClass('on');
812			jQuery(this).css('display','flex');
813		}
814	});
815
816	/* 로그인페이지 SNS 사용하면 출력 */
817	jQuery(".xans-member-login .login__sns .wrap_sns_log a").each(function(){
818		var wrap_sns_log = jQuery(this).hasClass('displaynone');
819		if( wrap_sns_log == false){
820			jQuery(".xans-member-login .login__sns").css('display','block');
821		}
822	});
823
824	/* 기획전 레이아웃변경에 따른 타겟고정위치 변경 */
825	var header_height = document.getElementById("header").scrollHeight;
826	jQuery('.xans-project-list h3 span').css('top',-header_height+30);
827
828	/* 모바일에서 쇼핑큐레이션 */
829	jQuery('#shoppQbtn').click(function(){
830		if (jQuery("#searchContent.xans-product-searchdata").is(":hidden")) {
831			jQuery('#searchContent.xans-product-searchdata').slideDown('normal');
832			jQuery(this).text('상세검색 닫기');
833			jQuery(this).css('margin-top','0');
834		} else {
835			jQuery('#searchContent.xans-product-searchdata').slideUp('normal');
836			jQuery(this).text('상세검색');
837		}
838	});
839
840	/* 모바일에서 쇼핑큐레이션 없을시 버튼 숨김 */
841	jQuery("#searchContent").each(function(){
842		var prdCount_count = jQuery("#ec-searchdata-area", this).length;
843		if ( prdCount_count == '0' ) {
844			jQuery('#shoppQbtn').hide();
845		}
846	});
847
848	/* 마이페이지 나의게시글 없을때 메시지 표시 */
849	jQuery(".xans-myshop-boardpackage").each(function(){
850		var boardlist = jQuery(".xans-myshop-boardlist table", this).length;
851		if ( boardlist == '0' ) {
852			jQuery('.myshop_boardlist_empty').css('display','flex');
853		}
854	});
855
856	/* 더보기 클릭시 */
857	jQuery('.btnMore').click(function(){
858		setTimeout(function(){
859			ifmore();
860		},600)
861	});
862	setTimeout(function(){
863		ifmore();
864	},300)
865
866	/* 상단 카테고리 변경 감지 */
867	top_category(); // 상단카테고리
868	observeTopCategory(); // 상단카테고리 변경 감지
869});
870
871/* 상단 카테고리 변경 감지 */
872function observeTopCategory(){
873	var targetNode = jQuery('#header .xans-layout-category > ul')[0];
874
875	// MutationObserver 인스턴스 생성
876	var observer = new MutationObserver(function(mutationsList, observer) {
877			// 변경 감지된 경우 상단카테고리 실행
878			top_category();
879	});
880
881	// 상단 카테고리가 있는 경우 변경 감지
882	if (targetNode) {
883			observer.observe(targetNode, { childList: true, subtree: true });
884	}
885}
886
887/* 상단 카테고리 */
888function top_category() {
889	/* 상단카테고리 */
890	jQuery('#header .top_category li').each(function() {
891		var $li = jQuery(this);
892		var timeoutId;
893
894		$li.on('mouseenter', function() {
895			clearTimeout(timeoutId); // 기존 timeout 제거
896			$li.addClass('on');
897            $li.siblings('li').removeClass('on');
898		});
899
900		$li.on('mouseleave', function() {
901            if ($li.is('.sub_cate01 > li')) {
902                timeoutId = setTimeout(function() {
903                    $li.removeClass('on');
904                }, 300);
905            } else if ($li.is('.sub_cate02 > li')) {
906                timeoutId = setTimeout(function() {
907                    $li.removeClass('on');
908                }, 300);
909            } else {
910                $li.removeClass('on');
911            }
912		});
913	});
914
915	/* 상단카테고리 중분류체크 */
916	jQuery('#header .top_category ul.sub_cate01 li').each(function() {
917		if (jQuery(this).children('ul').length == 0) {
918			jQuery(this).addClass('noChild');
919		}
920	});
921}
922
923/* 최상단배너 쿠키 스크립트 - 서정환 */
924function setCookiem(cookie_name, cookie_value, expire_date) {
925    var today = new Date();
926    var expire = new Date();
927    expire.setTime(today.getTime() + 3600000 * 24 * expire_date);
928    cookies = cookie_name + '=' + cookie_value + '; path=/;';
929    if (expire_date != 0) cookies += 'expires=' + expire.toGMTString();
930    document.cookie = cookies;
931}
932
933function delCookiem(cookie_name) {
934	var _today = new Date();
935	var value = '';
936	_today.setDate(_today.getDate() - 1);
937	document.cookie = cookie_name + "=" + value + '; path=/;' + "; expires=" + _today.toGMTString();
938}
939
940function getCookiem(name) {
941    lims = document.cookie;
942    var index = lims.indexOf(name + "=");
943    if (index == -1) {
944        return null;
945    }
946    index = lims.indexOf("=", index) + 1; // first character
947    var endstr = lims.indexOf(';', index);
948    if (endstr == -1) {
949        endstr = lims.length; // last character
950    }
951    return unescape(lims.substring(index, endstr));
952}
953
954/* 더보기 클릭시 */
955function ifmore(){
956	/* 상품 썸네일 관심상품 출력 & 숨김 */
957	setTimeout(function(){
958		jQuery('.ec-base-product .prdList .wish').each(function(){
959			var isstatus = jQuery(this).children('img').attr('icon_status');
960			if ( isstatus == 'on' ) {
961				jQuery(this).addClass('on');
962			}
963		});
964		jQuery('.ec-base-product .prdList .wish').click(function(){
965			var $img = jQuery(this).children('img');
966        	var isstatus = $img.attr('icon_status');
967
968			if ( isstatus == 'off' ) {
969				jQuery(this).addClass('on');
970			} else {
971				jQuery(this).removeClass('on');
972			}
973		});
974	},200)
975	jQuery('.ec-base-product .prdList > li').each(function(){
976		/* 상품진열 장바구니 사용안할시 숨김 */
977		if (jQuery(".icon__box .cart > .ec-admin-icon", this).length == 1) {
978		} else {
979			jQuery('.icon__box .cart', this).hide();
980		}
981		/* 상품진열 옵션미리보기 사용안할시 숨김 */
982		if (jQuery(".icon__box .option > a", this).length == 1) {
983		} else {
984			jQuery('.icon__box .option', this).hide();
985		}
986		/* 상품진열 관심상품 사용안할시 숨김 */
987		if (jQuery(".icon__box .wish > .ec-product-listwishicon", this).length == 1) {
988		} else {
989			jQuery('.icon__box .wish', this).hide();
990		}
991	});
992}
993/**
994 * 카테고리 마우스 오버 이미지
995 * 카테고리 대,중,소,하위분류까지 출력 - 세로형
996 * 210827 서정환 수정
997 */
998
999$(document).ready(function(){
1000
1001    var methods = {
1002        aCategory    : [],
1003        aSubCategory : {},
1004
1005        get: function()
1006        {
1007             $.ajax({
1008                url : '/exec/front/Product/SubCategory',
1009                dataType: 'json',
1010                success: function(aData) {
1011
1012                    if (aData == null || aData == 'undefined') return;
1013                    for (var i=0; i<aData.length; i++)
1014                    {
1015                        var sParentCateNo = aData[i].parent_cate_no;
1016
1017                        if (!methods.aSubCategory[sParentCateNo]) {
1018                            methods.aSubCategory[sParentCateNo] = [];
1019                        }
1020
1021                        methods.aSubCategory[sParentCateNo].push( aData[i] );
1022                    }
1023                }
1024            });
1025        },
1026
1027        getParam: function(sUrl, sKey) {
1028
1029            var aUrl         = sUrl.split('?');
1030            var sQueryString = aUrl[1];
1031            var aParam       = {};
1032
1033            if (sQueryString) {
1034                var aFields = sQueryString.split("&");
1035                var aField  = [];
1036                for (var i=0; i<aFields.length; i++) {
1037                    aField = aFields[i].split('=');
1038                    aParam[aField[0]] = aField[1];
1039                }
1040            }
1041            return sKey ? aParam[sKey] : aParam;
1042        },
1043
1044        getParamSeo: function(sUrl) {
1045            var aUrl = EC_ROUTE.getCleanUrl(sUrl).split('/');
1046            return aUrl[3] ? aUrl[3] : null;
1047        },
1048
1049        show: function(overNode, iCateNo, index) {
1050            var oParentNode = overNode;
1051            var aHtml = [];
1052            var sMyCateList = localStorage.getItem("myCateList");
1053            if (methods.aSubCategory[iCateNo] != undefined) {
1054                aHtml.push('<ul class="sub-category sub_cate01">');
1055                $(methods.aSubCategory[iCateNo]).each(function() {
1056                    var sNextParentNo = this.cate_no;
1057                    var sCateSelected = (checkInArray(sMyCateList, this.cate_no) == true) ? ' selected' : '';
1058                    if (methods.aSubCategory[sNextParentNo] == undefined) {
1059                        aHtml.push('<li class="noChild" id="cate'+this.cate_no+'">');
1060                        var sHref = '/product/list.html'+this.param;
1061                    } else {
1062                        aHtml.push('<li id="cate'+this.cate_no+'">');
1063                        var sHref = '#none';
1064                    }
1065                    var anchorHtml = '<a href="/product/list.html'+this.param+'" class="view" cate="'+this.param+'" data-i18n="LIST.PRD_CATE_NO_'+this.cate_no+'" onmouseover="subMenuon(this);" data-i18n-new>'+this.name;
1066                    // 1뎁스: 하위 카테고리가 있을 때만 <i> 태그 추가
1067                    if (methods.aSubCategory[sNextParentNo] != undefined) {
1068                        if (
1069                            $('.header_A').length > 0 ||
1070                            $('.header_C_a').length > 0 ||
1071                            $('.header_C_b').length > 0)
1072                            {
1073                            anchorHtml += '<i aria-hidden="true" class="icon icoArrowRight"></i>';
1074                        }
1075                    }
1076                    anchorHtml += '</a>';
1077
1078                    aHtml.push(anchorHtml);
1079
1080                    if (methods.aSubCategory[sNextParentNo] != undefined) {
1081                        aHtml.push('<ul class="sub-category-middle sub_cate02">');
1082                        $(methods.aSubCategory[sNextParentNo]).each(function() {
1083                            var sNextParentNo2 = this.cate_no;
1084                            var sCateSelected = (checkInArray(sMyCateList, this.cate_no) == true) ? ' selected' : '';
1085                            if (methods.aSubCategory[sNextParentNo2] == undefined) {
1086                                aHtml.push('<li class="noChild" id="cate'+this.cate_no+'">');
1087                                var sHref = '/product/list.html'+this.param;
1088                            } else {
1089                                aHtml.push('<li id="cate'+this.cate_no+'">');
1090                                var sHref = '#none';
1091                            }
1092
1093                            var anchorHtml2 = '<a href="/product/list.html'+this.param+'" class="view" cate="'+this.param+'" data-i18n="LIST.PRD_CATE_NO_'+this.cate_no+'" onmouseover="subMenuon(this);" data-i18n-new>'+this.name;
1094                            // 2뎁스: 하위 카테고리가 있을 때만 <i> 태그 추가
1095                            if (methods.aSubCategory[sNextParentNo2] != undefined) {
1096                                if ($('.header_A').length > 0 || $('.header_C_a').length > 0 || $('.header_C_b').length > 0) {
1097                                    anchorHtml2 += '<i aria-hidden="true" class="icon icoArrowRight"></i>';
1098                                }
1099                            }
1100                            anchorHtml2 += '</a>';
1101                            aHtml.push(anchorHtml2);
1102
1103                            if (methods.aSubCategory[sNextParentNo2] != undefined) {
1104                                aHtml.push('<ul class="sub-category-child sub_cate03">');
1105
1106                                $(methods.aSubCategory[sNextParentNo2]).each(function() {
1107                                    aHtml.push('<li class="noChild" id="cate'+this.cate_no+'">');
1108                                    var sCateSelected = (checkInArray(sMyCateList, this.cate_no) == true) ? ' selected' : '';
1109                                    var anchorHtml3 = '<a href="/product/list.html'+this.param+'" class="view" cate="'+this.param+'" onmouseover="subMenuon(this);" data-i18n="LIST.PRD_CATE_NO_'+this.cate_no+'" data-i18n-new>'+this.name+'</a>';
1110                                    // 3뎁스: 하위 카테고리가 없으므로 <i> 태그 추가 로직 삭제
1111                                    aHtml.push(anchorHtml3);
1112                                    aHtml.push('</li>');
1113                                });
1114                                aHtml.push('</ul>');
1115                            }
1116                            aHtml.push('</li>');
1117                        });
1118                        aHtml.push('</ul>');
1119                    }
1120                    aHtml.push('</li>');
1121                });
1122                aHtml.push('</ul>');
1123            }
1124
1125            if($(oParentNode).find('.sub_cate01').length <= 0){
1126                $(oParentNode).append(aHtml.join(''));
1127            }
1128
1129            if ( $('.header_B').length > 0 ) {
1130                let isDuplicate = false;
1131                const aCategory1 = methods.aSubCategory[iCateNo]; // 1depth
1132            
1133                // 2depth 생성
1134                if (!aCategory1) return;
1135
1136                const firstDepthName = overNode.children('a').text().trim();
1137            
1138                aCategory1.forEach(function(category1) {
1139                    const cateNo2 = category1.cate_no;
1140                    const aCategory2 = methods.aSubCategory[cateNo2]; // 3depth
1141            
1142                    if ($(`.cate_list[data-name="${firstDepthName}"]`).length > 0) {
1143                        isDuplicate = true;
1144                    }
1145                });
1146                
1147                // 중복 체크
1148                if (isDuplicate) {
1149                    return;
1150                }
1151
1152                let html = `<div class="sub_cate02">`;
1153            
1154                aCategory1.forEach(function(category1) {
1155                    const cateNo2 = category1.cate_no;
1156                    const aCategory2 = methods.aSubCategory[cateNo2];
1157            
1158                    html += `<ul class="cate_list" data-name="${firstDepthName}">`;
1159                    html += `<li class="cate-name"><a href="/product/list.html${category1.param}">${category1.name}</a></li>`;
1160            
1161                    if (aCategory2 !== undefined) {
1162                        aCategory2.forEach(function(category2) {
1163                            html += `<li><a href="/product/list.html${category2.param}">${category2.name}</a></li>`;
1164                        });
1165                    }
1166            
1167                    html += `</ul>`;
1168                });
1169            
1170                html += `</div>`;
1171                $('#header .gnb_wrap .inner').append(html);
1172            } else if($('.header_D').length > 0) {
1173                $('#header .cate_list').each(function () {
1174                    const $cateListItem = $(this);
1175                
1176                    // 1뎁스 이름 추출
1177                    const cateName = $cateListItem.find('.cate_depth01 .title').text().trim();
1178                    let iCateNo = null;
1179                
1180                    // 1depth name → cate_no 찾기
1181                    let found = false;
1182                    for (let parentNo in methods.aSubCategory) {
1183                        const subList = methods.aSubCategory[parentNo];
1184                        for (let i = 0; i < subList.length; i++) {
1185                            if (subList[i].name === cateName) {
1186                                iCateNo = subList[i].cate_no;
1187                                found = true;
1188                                break;
1189                            }
1190                        }
1191                        if (found) break;
1192                    }
1193                
1194                    if (!iCateNo || !methods.aSubCategory[iCateNo]) return;
1195                
1196                    const depth2List = methods.aSubCategory[iCateNo];
1197                    let depth2Name;
1198                
1199                    // 2depth 생성
1200                    if ($cateListItem.find('.cate_depth02').length === 0) {
1201                        let html2 = ['<ul class="cate_depth02">'];
1202                        depth2List.forEach(function (d2) {
1203                            const selected = checkInArray(sMyCateList, d2.cate_no) ? ' selected' : '';
1204                            depth2Name = d2.name
1205                            html2.push('<li class="' + selected + '"><a href="/product/list.html' + d2.param + '" class="view" cate="' + d2.param + '">' + d2.name + '</a></li>');
1206                        });
1207                        html2.push('</ul>');
1208                        $cateListItem.append(html2.join(''));
1209                    }
1210                
1211                    // 3depth 생성
1212                    if ($cateListItem.find('.cate_depth03').length === 0) {
1213                        let html3 = ['<ul class="cate_depth03">'];
1214                        depth2List.forEach(function (d2) {
1215                            const depth3List = methods.aSubCategory[d2.cate_no];
1216                
1217                            if (depth3List && depth3List.length > 0) {
1218                                html3.push('<li data-name="' + depth2Name + '"><ul>');
1219                                depth3List.forEach(function (d3) {
1220                                    const selected = checkInArray(sMyCateList, d3.cate_no) ? ' selected' : '';
1221                                    html3.push('<li class="' + selected + '"><a href="/product/list.html' + d3.param + '" class="view" cate="' + d3.param + '">' + d3.name + '</a></li>');
1222                                });
1223                                html3.push('</ul></li>');
1224                            }
1225                        });
1226                        html3.push('</ul>');
1227                        $cateListItem.append(html3.join(''));
1228                    }
1229                });       
1230            } else if (
1231                $('.header_search_A').length > 0
1232            ) {
1233                setTimeout(() => {
1234                        let gnbInner = $('.gnb_wrap .depth01');
1235                        let html = [];
1236                        const depth1 = overNode.children('a').text().trim();
1237
1238                        // 중복 체크 (Duplicate check)
1239                        let isDuplicate = false;
1240                        const depth2List = methods.aSubCategory[iCateNo];
1241                        gnbInner.find('a.title').each(function () {
1242                            const existingText = $(this).text().trim();
1243                            if (existingText === depth1) {
1244                                isDuplicate = true;
1245                                return false; // break
1246                            }
1247                        });
1248
1249                    if (isDuplicate) return;
1250                    
1251                    html.push('<li style="order:' + index + '">');
1252
1253                    let depth1Link = '/product/list.html?cate_no=' + iCateNo;
1254                    html.push('<a href="' + depth1Link + '" class="title">' + depth1 + '</a>');
1255    
1256                    // 각 1depth 항목 (Each 1st depth item)
1257                    if (depth2List) {
1258                        html.push('<ul class="depth02">');
1259
1260                        $.each(depth2List, function (_, depth2) {
1261                            html.push('<li>');
1262
1263                            // 3depth 목록 (3rd depth list)
1264                            const depth3List = methods.aSubCategory[depth2.cate_no];
1265
1266                            // <a> 태그 시작 (Start <a> tag)
1267                            let anchorHtml = '<a href="/product/list.html' + depth2.param + '" class="view">' + depth2.name;
1268
1269                            if (depth3List && depth3List.length > 0) {
1270                                anchorHtml += '<i aria-hidden="true" class="icon icoArrowBottom"></i>';
1271                            }
1272
1273                            anchorHtml += '</a>';
1274                            html.push(anchorHtml);
1275
1276                            if (depth3List && depth3List.length > 0) {
1277                                html.push('<ul class="depth03">');
1278
1279                                $.each(depth3List, function (_, depth3) {
1280                                    const depth4List = methods.aSubCategory[depth3.cate_no];
1281
1282                                    let anchorHtml = '<a href="/product/list.html' + depth3.param + '" class="view">' + depth3.name;
1283
1284                                    // 4depth 목록 (4th depth list)
1285                                    if (depth4List && depth4List.length > 0) {
1286                                        anchorHtml += '<i aria-hidden="true" class="icon icoArrowBottom"></i>';
1287                                    }
1288
1289                                    anchorHtml += '</a>';
1290                                    html.push('<li>' + anchorHtml);
1291
1292                                    // 4depth ul 생성 (Create 4th depth ul)
1293                                    if (depth4List && depth4List.length > 0) {
1294                                        html.push('<ul class="depth04">');
1295                                        $.each(depth4List, function (_, depth4) {
1296                                            let depth4Anchor = '<a href="/product/list.html' + depth4.param + '" class="view">' + depth4.name + '</a>';
1297                                            html.push('<li>' + depth4Anchor + '</li>');
1298                                        });
1299                                        html.push('</ul>'); // .depth04
1300                                    }
1301
1302                                    html.push('</li>'); // 3depth li
1303                                });
1304
1305                                html.push('</ul>'); // .depth03
1306                            }
1307
1308                            html.push('</li>'); // 2depth li
1309                        });
1310
1311                        html.push('</ul>'); // .depth02
1312                    }
1313
1314                    // 결과 삽입
1315                    if (html.length > 0) {
1316                        gnbInner.append(html.join(''));
1317                    }
1318                }, 80);
1319            } else if ($('.header_search_B').length > 0) {
1320                const gnbInner = $('.gnb_wrap .depth01');
1321                let html = [];
1322                const depth1Name = overNode.children('a').text().trim();
1323            
1324                const existingTitles = new Set();
1325                gnbInner.find('.title').each(function () {
1326                    existingTitles.add($(this).text().trim());
1327                });
1328            
1329                const depth1List = methods.aSubCategory[iCateNo];
1330                if (!depth1List || depth1List.length === 0) return;
1331            
1332                $.each(depth1List, function (_, depth1) {
1333                    const depth2Name = depth1.name.trim();
1334
1335                    // 중복 체크
1336                    if (existingTitles.has(depth2Name)) {
1337                        return true;
1338                    }
1339            
1340                    const depth1CateNo = depth1.cate_no;
1341                    const depth2List = methods.aSubCategory[depth1CateNo];
1342                    if (!depth2List || depth2List.length === 0) return;
1343            
1344                    html.push('<li data-name="'+depth1Name+'" style="order:' + index + '">');
1345                    html.push('<span class="title">' + depth2Name + '</span>');
1346                    html.push('<ul class="depth02">');
1347            
1348                    $.each(depth2List, function (_, depth2) {
1349                        const depth2CateNo = depth2.cate_no;
1350                        const depth3List = methods.aSubCategory[depth2CateNo];
1351            
1352                        html.push('<li>');
1353                        html.push(
1354                            '<a href="/product/list.html' + depth2.param + '" class="view">' +
1355                            depth2.name +
1356                            '<i aria-hidden="true" class="icon icoArrowBottom"></i>' +
1357                            '</a>'
1358                        );
1359            
1360                        if (depth3List && depth3List.length > 0) {
1361                            html.push('<ul class="depth03">');
1362                            $.each(depth3List, function (_, depth3) {
1363                                html.push(
1364                                    '<li>' +
1365                                    '<a href="/product/list.html' + depth3.param + '" class="view">' +
1366                                    depth3.name +
1367                                    '</a>' +
1368                                    '</li>'
1369                                );
1370                            });
1371                            html.push('</ul>');
1372                        }
1373            
1374                        html.push('</li>');
1375                    });
1376            
1377                    html.push('</ul>');
1378                    html.push('</li>');
1379                });
1380            
1381                if (html.length > 0) {
1382                    gnbInner.append(html.join(''));
1383                }
1384            }
1385                       
1386            if (window.i18nextCafe24) {
1387            	i18nextCafe24.translate('data-i18n-new');
1388            } else if ($('.header_search_C').length > 0) {
1389                const gnbInner = $('.gnb_wrap .inner');
1390                let html = [];
1391                const depth1Name = overNode.children('a').text().trim();
1392            
1393                const depth1List = methods.aSubCategory[iCateNo];
1394                if (!depth1List || depth1List.length === 0) return;
1395
1396                // 중복 체크
1397                if (gnbInner.find('.cate_list[data-name="' + depth1Name + '"]').length > 0) {
1398                    return true; // continue
1399                }
1400
1401                html.push('<div class="cate_list" data-name="'+depth1Name+'">');
1402                html.push('<ul class="depth02">');
1403            
1404                $.each(depth1List, function (_, depth1) {
1405                    const depth2Name = depth1.name.trim();
1406                    const depth1CateNo = depth1.cate_no;
1407                    const depth2List = methods.aSubCategory[depth1CateNo];
1408                    if (!depth2List || depth2List.length === 0) return;
1409
1410                    $.each(depth2List, function (_, depth2) {
1411                        const depth2CateNo = depth2.cate_no;
1412                        const depth3List = methods.aSubCategory[depth2CateNo];
1413            
1414                        html.push('<li>');
1415                        html.push(
1416                            '<a href="/product/list.html' + depth2.param + '">' +
1417                            depth2.name +
1418                            '</a>'
1419                        );
1420            
1421                        if (depth3List && depth3List.length > 0) {
1422                            html.push('<ul class="depth03">');
1423                            $.each(depth3List, function (_, depth3) {
1424                                html.push(
1425                                    '<li>' +
1426                                    '<a href="/product/list.html' + depth3.param + '">' +
1427                                    depth3.name +
1428                                    '</a>' +
1429                                    '</li>'
1430                                );
1431                            });
1432                            html.push('</ul>');
1433                        }
1434            
1435                        html.push('</li>');
1436                    });
1437                });
1438
1439                html.push('</ul>');
1440                html.push('</div>');
1441            
1442                if (html.length > 0) {
1443                    gnbInner.append(html.join(''));
1444                }
1445            }
1446                       
1447            if (window.i18nextCafe24) {
1448            	i18nextCafe24.translate('data-i18n-new');
1449            }
1450        },
1451
1452        close: function() {
1453            $('.sub-category').remove();
1454        }
1455    };
1456
1457    methods.get();
1458
1459    $('#header .xans-layout-category > ul > li').mouseenter(function(e) {
1460        let $this = $(this).addClass('on');
1461        index = $this.index() + 1;
1462        iCateNo = Number(methods.getParam($this.find('a').attr('href'), 'cate_no'));
1463
1464        if (!iCateNo) iCateNo = Number(methods.getParamSeo($this.find('a').attr('href')));
1465        if (!iCateNo) return;
1466        
1467        methods.show($this, iCateNo, index);
1468    }).mouseleave(function(e) {
1469        $(this).removeClass('on');
1470
1471        methods.close();
1472    });
1473
1474    if (
1475        $('.header_search_A').length > 0 ||
1476        $('.header_search_B').length > 0 ||
1477        $('.header_search_C').length > 0
1478    ) {
1479        setTimeout(() => {
1480            const list = $('#header .xans-layout-category > ul > li');
1481            list.each(function () {
1482                const $this = $(this);
1483                const index = $this.index();
1484                let iCateNo = Number(methods.getParam($this.find('a').attr('href'), 'cate_no'));
1485
1486                if (!iCateNo) {
1487                    iCateNo = Number(methods.getParamSeo($this.find('a').attr('href')));
1488                }
1489                if (!iCateNo && iCateNo !== 0) return;
1490
1491                methods.show($this, iCateNo, index);
1492            });
1493        }, 50);
1494    }
1495});
1496
1497function subMenuon(obj) {
1498	$(obj).parent().find('li').removeClass('on');
1499	$(obj).parent().addClass('on');
1500	$(obj).parent().siblings().removeClass("on");
1501}
1502function checkInArray(sBookmarkList, iCateNo) {
1503    if (sBookmarkList == null) return false;
1504    var aBookmarkList = sBookmarkList.split("|");
1505    for (var i = 0; i < aBookmarkList.length; i++) {
1506        if (aBookmarkList[i] == iCateNo) {
1507            return true;
1508        }
1509    }
1510    return false;
1511}
1512
1513//window popup script
1514function winPop(url) {
1515    window.open(url, "popup", "width=300,height=300,left=10,top=10,resizable=no,scrollbars=no");
1516}
1517/**
1518 * document.location.href split
1519 * return array Param
1520 */
1521function getQueryString(sKey)
1522{
1523    var sQueryString = document.location.search.substring(1);
1524    var aParam       = {};
1525
1526    if (sQueryString) {
1527        var aFields = sQueryString.split("&");
1528        var aField  = [];
1529        for (var i=0; i<aFields.length; i++) {
1530            aField = aFields[i].split('=');
1531            aParam[aField[0]] = aField[1];
1532        }
1533    }
1534
1535    aParam.page = aParam.page ? aParam.page : 1;
1536    return sKey ? aParam[sKey] : aParam;
1537};
1538
1539$(function(){
1540    // tab
1541    $.eTab = function(ul){
1542        $(ul).find('a').on('click', function(){
1543            var _li = $(this).parent('li').addClass('selected').siblings().removeClass('selected'),
1544                _target = $(this).attr('href'),
1545                _siblings = '.' + $(_target).attr('class');
1546            $(_target).show().siblings(_siblings).hide();
1547            return false
1548        });
1549    }
1550    if ( window.call_eTab ) {
1551        call_eTab();
1552    };
1553});
1554
1555/**
1556 * 구매 버튼 플로팅 영역 제어
1557 * 스크롤 시 원본 버튼이 화면에서 사라지면 플로팅 버튼을 표시
1558 */
1559var globalBuyBtnScrollFunc = function() {
1560    var sFixId = $('#orderFixItem').length > 0 ? 'orderFixItem' : 'fixedActionButton',
1561        $area = $('#orderFixArea'),
1562        $item = $('#' + sFixId).length > 0 ? $('#' + sFixId).not($area) : $('.fixedActionButton').not($area);
1563
1564    // 필수 요소가 없으면 실행하지 않음
1565    if ($area.length === 0 || $item.length === 0) {
1566        return;
1567    }
1568
1569    $(window).on('scroll', function(){
1570        try {
1571            var iCurrentHeightPos = $(this).scrollTop() + $(this).height(),
1572                iButtonHeightPos = $item.offset().top;
1573
1574            if (iCurrentHeightPos > iButtonHeightPos || iButtonHeightPos < $(this).scrollTop() + $item.height()) {
1575                if (iButtonHeightPos < $(this).scrollTop() - $item.height()) {
1576                    $area.fadeIn('fast');
1577                } else {
1578                    $area.hide();
1579                }
1580            } else {
1581                $area.fadeIn('fast');
1582            }
1583        } catch(e) { }
1584    });
1585};
1586
1587$(function(){
1588    globalBuyBtnScrollFunc();
1589});
1590
1591
1592/**
1593 * 메인 상품 목록 스와이퍼 레이어 제어
1594 * - 특정 버튼 클릭 시 자기 레이어 제외하고 다른 레이어 닫기
1595 * - 클릭된 li z-index 상승, 다른 li z-index 복원
1596 */
1597document.addEventListener('DOMContentLoaded', function(){
1598    var swiperWrapper = document.querySelector('.main_product_list .prdList.swiper-wrapper');
1599    if (!swiperWrapper) return;
1600
1601    // 트리거와 해당 레이어 매핑
1602    var triggerLayerMap = [
1603        { trigger: '.discountPeriod > a', layer: '.layerDiscountPeriod' },
1604        { trigger: '.deliveryBenefitDetailInfo', layer: '.shippingFee .ec-base-tooltip' },
1605        { trigger: '.description .option', layer: '.xans-product-optionpreview .prdOption' },
1606        { trigger: '.EC-stockdesign', layer: '.ec-shop-detail-stock-layer' }
1607    ];
1608
1609    var allLayerSelectors = [
1610        '.shippingFee .ec-base-tooltip',
1611        '.layerDiscountPeriod',
1612        '.xans-product-optionpreview .prdOption',
1613        '.ec-shop-detail-stock-layer'
1614    ];
1615
1616    document.addEventListener('click', function(e){
1617        var li = e.target.closest('.main_product_list .prdList.swiper-wrapper > li');
1618        if (!li) return;
1619
1620        var clickedTrigger = null;
1621        for (var i = 0; i < triggerLayerMap.length; i++) {
1622            if (e.target.closest(triggerLayerMap[i].trigger)) {
1623                clickedTrigger = triggerLayerMap[i];
1624                break;
1625            }
1626        }
1627
1628        if (clickedTrigger) {
1629            var allLis = document.querySelectorAll('.main_product_list .prdList.swiper-wrapper > li');
1630            allLis.forEach(function(item){
1631                // 다른 li의 레이어 닫기 + z-index 복원
1632                if (item !== li) {
1633                    item.style.zIndex = '';
1634                    allLayerSelectors.forEach(function(selector){
1635                        var layer = item.querySelector(selector);
1636                        if (layer) {
1637                            layer.style.display = 'none';
1638                        }
1639                    });
1640                } else {
1641                    // 자기 li의 다른 레이어만 닫기
1642                    allLayerSelectors.forEach(function(selector){
1643                        if (selector !== clickedTrigger.layer) {
1644                            var layer = item.querySelector(selector);
1645                            if (layer) {
1646                                layer.style.display = 'none';
1647                            }
1648                        }
1649                    });
1650                }
1651            });
1652
1653            // 클릭된 li z-index 상승
1654            li.style.zIndex = '2';
1655        }
1656    }, true);
1657});
1658
1659/**
1660 * 할인기간 레이어 - 모바일(1024px 이하) 터치 대응
1661 * - 외부 코드의 mouseover/mouseout 이벤트를 click 토글로 대체
1662 * - btnClose 클릭 시 레이어 닫기
1663 * - 외부 클릭 시 레이어 닫기
1664 * - 적용 범위: 전체 상품 목록
1665 */
1666$(function(){
1667    var noHover = window.matchMedia('(hover: none)').matches;
1668
1669    // hover 불가 환경에서만 click 토글로 변경
1670    if (noHover) {
1671        // hover 이벤트 제거 후 click 토글로 대체
1672        EC$('.discountPeriod > a').off('mouseover mouseout').on('click', function(e){
1673            e.preventDefault();
1674            e.stopPropagation();
1675
1676            var $layer = EC$(this).parent().find('.layerDiscountPeriod');
1677
1678            // 다른 레이어 닫기
1679            EC$('.layerDiscountPeriod').not($layer).hide();
1680
1681            // 토글
1682            $layer.toggle();
1683        });
1684    }
1685
1686    // 1024px 이하에서 닫기 처리 (btnClose, 외부 클릭)
1687    EC$(document).on('click', function(e){
1688        if (window.innerWidth > 1024) return;
1689
1690        // btnClose 클릭 시 닫기
1691        var $btnClose = EC$(e.target).closest('.layerDiscountPeriod .btnClose');
1692        if ($btnClose.length) {
1693            e.preventDefault();
1694            $btnClose.closest('.layerDiscountPeriod').hide();
1695            return;
1696        }
1697
1698        // 외부 클릭 시 닫기
1699        if (!EC$(e.target).closest('.discountPeriod').length) {
1700            EC$('.layerDiscountPeriod').hide();
1701        }
1702    });
1703});
1704
1705(function($){
1706$.fn.extend({
1707    center: function() {
1708        this.each(function() {
1709            var
1710                $this = $(this),
1711                $w = $(window);
1712            $this.css({
1713                position: "absolute",
1714                top: ~~(($w.height() - $this.outerHeight()) / 2) + $w.scrollTop() + "px",
1715                left: ~~(($w.width() - $this.outerWidth()) / 2) + $w.scrollLeft() + "px"
1716            });
1717        });
1718        return this;
1719    }
1720});
1721$(function() {
1722    var $container = function(){/*
1723<div id="modalContainer">
1724    <iframe id="modalContent" scroll="0" scrolling="no" frameBorder="0"></iframe>
1725</div>');
1726*/}.toString().slice(14,-3);
1727    $('body')
1728    .append($('<div id="modalBackpanel"></div>'))
1729    .append($($container));
1730    function closeModal () {
1731        $('#modalContainer').hide();
1732        $('#modalBackpanel').hide();
1733    }
1734    $('#modalBackpanel').on('click', closeModal);
1735    zoom = function ($piProductNo, $piCategoryNo, $piDisplayGroup) {
1736        var $url = '/product/image_zoom.html?product_no=' + $piProductNo + '&cate_no=' + $piCategoryNo + '&display_group=' + $piDisplayGroup;
1737        $('#modalContent').attr('src', $url);
1738        $('#modalContent').on("load",function(){
1739            $(".header .close",this.contentWindow.document.body).on("click", closeModal);
1740        });
1741        $('#modalBackpanel').css({width:$("body").width(),height:$("body").height(),opacity:.4}).show();
1742        $('#modalContainer').center().show();
1743    }
1744});
1745})(jQuery);
1746$(function(){
1747    var loginButtons = document.querySelectorAll('.header-login-btn');
1748    
1749    loginButtons.forEach(function(button) {
1750        button.addEventListener('click', function() {
1751            var contentValue = document.querySelector('meta[name="path_role"]').getAttribute('content');
1752
1753            if (contentValue == 'MEMBER_JOIN' || contentValue == 'MEMBER_AGREEMENT' || contentValue == 'MEMBER_LOGIN') {
1754                window.location.href = '/member/login.html';
1755                return true;
1756            }
1757
1758            var existingParams = new URLSearchParams(window.location.search);
1759            var returnUrl = existingParams.has('returnUrl') ? existingParams.get('returnUrl') : window.location.pathname + window.location.search;
1760            existingParams.set('returnUrl', returnUrl);
1761
1762            window.location.href = '/member/login.html?' + existingParams.toString();
1763        });
1764    });
1765});
1766// 멀티샵 버튼 클릭
1767const bodyEl = document.querySelector('body');
1768const dimmed = document.querySelector('.dimmed');
1769
1770// 검색창
1771const btnSearch = document.querySelector('#header .eSearch');
1772const searchForm = document.querySelector('#searchBarForm');
1773if(btnSearch){
1774    btnSearch.addEventListener('click', function() {
1775        if (bodyEl.classList.contains('searchExpand')) {
1776            setTimeout(() => {
1777                bodyEl.classList.remove('searchExpand');
1778            }, 200);
1779        }
1780    });
1781}
1782
1783// 딤드 클릭 시 닫기
1784dimmed.addEventListener('click', function() {
1785    if (bodyEl.classList.contains('expand')) {
1786        bodyEl.classList.remove('expand');
1787    }
1788    if (bodyEl.classList.contains('searchExpand')) {
1789        bodyEl.classList.remove('searchExpand');
1790    }
1791    if (multishopPopup.classList.contains('active')) {
1792        multishopPopup.classList.remove('active');
1793        dimmed.classList.remove('active');
1794    }
1795});
1796
1797// 레이아웃 변경 버튼 클릭
1798const changeBtn = document.querySelector('.change_layout button');
1799const changeDepth01 = document.querySelector('.change_layout .depth01');
1800const changeDepth01A = document.querySelectorAll('.change_layout .depth01 > li > a');
1801const changeDepth02 = document.querySelector('.change_layout .depth02');
1802const changeDepth02A = document.querySelectorAll('.change_layout .depth02 > li > a');
1803
1804if(changeBtn){
1805    changeBtn.addEventListener('click', function(e) {
1806        e.preventDefault();
1807    
1808        const isActive01 = changeDepth01.classList.contains('active');
1809        const isActive02 = changeDepth02.classList.contains('active');
1810    
1811        if (isActive01 || isActive02) {
1812            changeDepth01.classList.remove('active');
1813            changeDepth02.classList.remove('active');
1814    
1815            changeDepth01.querySelectorAll('li').forEach(function(li) {
1816                li.classList.remove('dpnone');
1817            });
1818            changeDepth02.querySelectorAll('li').forEach(function(li) {
1819                li.classList.remove('dpnone');
1820            });
1821    
1822            changeDepth01A.forEach(function(a) {
1823                a.classList.remove('dpnone');
1824            });
1825            changeDepth02A.forEach(function(a) {
1826                a.classList.remove('dpnone');
1827            });
1828        } else {
1829            changeDepth01.classList.add('active');
1830        }
1831    });
1832}
1833
1834// depth01 항목 클릭
1835changeDepth01A.forEach(function(anchor) {
1836    anchor.addEventListener('click', function(e) {
1837        e.preventDefault();
1838        if (this.tagName.toLowerCase() === 'a') {
1839            this.classList.add('dpnone');
1840        }
1841
1842        const depth02 = this.parentElement.querySelector('.depth02');
1843        if (depth02) {
1844            depth02.classList.add('active');
1845        }
1846
1847        const siblings = Array.from(this.closest('li').parentElement.children);
1848        siblings.forEach(function(sibling) {
1849            if (sibling !== anchor.closest('li')) {
1850                sibling.classList.add('dpnone');
1851            }
1852        });
1853    });
1854});
1855
1856// 장바구니 팝업 함수
1857var cartPopupFunc = function() {
1858    var basketSelectors = [
1859        '.xans-product-basketadd',
1860        '.xans-order-layerbasketpackage'
1861    ];
1862
1863    document.addEventListener('click', function(e) {
1864        try {
1865            var target = e.target;
1866
1867            // 두 종류의 장바구니 레이어 체크
1868            for (var i = 0; i < basketSelectors.length; i++) {
1869                var basketLayer = target.closest(basketSelectors[i]);
1870                if (basketLayer && target === basketLayer) {
1871                    basketLayer.remove();
1872                    break;
1873                }
1874            }
1875        } catch(e) { }
1876    });
1877};
1878cartPopupFunc();
1879
1880// 홍보문구 있을때 검색창 클릭 이벤트
1881document.addEventListener("DOMContentLoaded", function () {
1882    setTimeout(() => {
1883        const bannerAction = document.querySelector("#banner_action");
1884        const btnSearch = document.querySelector(".xans-layout-searchheader span");
1885        const searchValue = document.querySelector(".xans-layout-searchheader #keyword").value;
1886        let bannerValue = bannerAction ? bannerAction.value : "";
1887        
1888        if (window.innerWidth <= 1024 && bannerAction) {
1889            bannerAction.value = "";
1890            
1891            if (btnSearch && bannerValue) {
1892                btnSearch.addEventListener("click", function () {
1893                    const newValue = document.querySelector(".xans-layout-searchheader #keyword").value;
1894                    if(searchValue === newValue){
1895                        window.location.href = bannerValue;
1896                    }
1897                });
1898            }
1899        }    
1900    }, 300);
1901
1902    /* const input = document.querySelector("#contents .keyword");
1903    const btnDelete = document.querySelector("#contents .searchField .btnDelete");
1904
1905    if (!input || !btnDelete) return;
1906
1907    function toggleDeleteButton() {
1908        console.log('input.value = ',input.value);
1909        
1910        if (input.value.trim() !== "") {
1911            btnDelete.style.display = "block";
1912        } else {
1913            btnDelete.style.display = "none";
1914        }
1915    }
1916
1917    input.addEventListener("input", toggleDeleteButton);
1918
1919    toggleDeleteButton();
1920
1921    btnDelete.addEventListener("click", function () {
1922        input.value = "";
1923        toggleDeleteButton();
1924        input.focus();
1925    }); */
1926});
1927
1928// 상품 옵션 레이어
1929const modals = document.querySelectorAll(".ec-base-layer.typeModal");
1930const contents = document.querySelector("#contents");
1931const btnOpen = document.querySelectorAll(".EC-stockdesign");
1932
1933btnOpen.forEach(btn => {
1934    btn.addEventListener("click", function () {
1935        if (!modals.length || !contents) return;
1936        updateModalPositions();
1937    });
1938});
1939
1940function updateModalPositions() {
1941    if (window.innerWidth >= 1024) {
1942        const rect = contents.getBoundingClientRect();
1943
1944        modals.forEach(modal => {
1945            modal.style.left = rect.left + "px";
1946            modal.style.width = rect.width + "px";
1947        });
1948    } else {
1949        // 1024 미만일 때는 기본 스타일로 초기화
1950        modals.forEach(modal => {
1951            modal.style.left = "";
1952            modal.style.width = "";
1953        });
1954    }
1955}
1956
1957/* 레이아웃 클래스명 업데이트 */
1958(function () {
1959    const container = document.getElementById('container');
1960    if (!container) return;
1961
1962    // 분기점 설정
1963    const BREAKPOINTS = [850, 767, 599, 500, 440, 400];
1964    const ALL_CLASSES = BREAKPOINTS.map(bp => `layout_${bp}`);
1965
1966    function updateLayoutClasses() {
1967        const width = container.getBoundingClientRect().width;
1968
1969        bodyEl.classList.remove(...ALL_CLASSES);
1970        for (const bp of BREAKPOINTS) {
1971        if (width <= bp) bodyEl.classList.add(`layout_${bp}`);
1972        }
1973    }
1974
1975    // 초기 실행
1976    updateLayoutClasses();
1977
1978    // 리사이즈
1979    let ticking = false;
1980    window.addEventListener('resize', () => {
1981        if (ticking) return;
1982        ticking = true;
1983        requestAnimationFrame(() => {
1984        updateLayoutClasses();
1985        ticking = false;
1986        });
1987    });
1988})();
1989
1990// 상품 목록 아이템 클릭 처리 (1024px 초과 데스크톱에서만)
1991(function() {
1992    var clickHandlers = new Map();
1993
1994    function initClickHandlers() {
1995        document.querySelectorAll('.main_product_list.typeDimmed .prdList__item').forEach(function(item) {
1996            if (clickHandlers.has(item)) return;
1997
1998            item.style.cursor = 'pointer';
1999
2000            var handler = function(e) {
2001                // 버튼이나 기존 링크 클릭은 무시
2002                if (e.target.closest('button, .likeButton, .icon__box, a')) {
2003                    return;
2004                }
2005
2006                // 상품 링크로 이동
2007                var link = this.querySelector('.thumbnail a');
2008                if (link && link.href) {
2009                    window.location.href = link.href;
2010                }
2011            };
2012
2013            item.addEventListener('click', handler);
2014            clickHandlers.set(item, handler);
2015        });
2016    }
2017
2018    function removeClickHandlers() {
2019        clickHandlers.forEach(function(handler, item) {
2020            item.style.cursor = '';
2021            item.removeEventListener('click', handler);
2022        });
2023        clickHandlers.clear();
2024    }
2025
2026    function handleResize() {
2027        if (window.innerWidth > 1024) {
2028            initClickHandlers();
2029        } else {
2030            removeClickHandlers();
2031        }
2032    }
2033
2034    // 초기 실행
2035    handleResize();
2036
2037    // 리사이즈 이벤트
2038    window.addEventListener('resize', handleResize);
2039})();
2040
2041document.addEventListener('DOMContentLoaded', function () {    
2042    //fade-in 애니메이션
2043    const prdFade = document.querySelectorAll('.prd_fade');
2044
2045    const prdScroll = new IntersectionObserver((entries, observer) => {
2046        entries.forEach(entry => {
2047            if (entry.isIntersecting) {
2048                entry.target.classList.add('prd_fade_in');
2049                observer.unobserve(entry.target); // 한 번만 실행
2050            }
2051        });
2052    }, { threshold: 0.2 });
2053
2054    prdFade.forEach(el => prdScroll.observe(el));
2055});
2056document.addEventListener('DOMContentLoaded', function () {
2057    const topButton = document.querySelector('.moveToTop_module');
2058    const floatMenu = document.querySelector('.floatMenu_B');
2059    const foldBtn = document.querySelector('.fold_btn');
2060
2061    topButton.addEventListener('click', function () {
2062        window.scrollTo({
2063            top: 0,
2064            behavior: 'smooth'
2065        });
2066    });
2067
2068    window.addEventListener('scroll', () => {
2069        if (!topButton) return;
2070        if (window.scrollY > 1000) {
2071            topButton.classList.add('visible');
2072        } else { topButton.classList.remove('visible'); }
2073    });
2074
2075    setTimeout(() => {
2076        if (floatMenu && topButton) {
2077            if(floatMenu.classList.contains('is-folded')){
2078                topButton.classList.remove('active_b');
2079            } else {
2080                topButton.classList.add('active_b');
2081            }
2082        }
2083    }, 100)
2084
2085    if (foldBtn && floatMenu && topButton) {
2086        foldBtn.addEventListener('click', () => {
2087            if (floatMenu.classList.contains('is-folded')) {
2088                topButton.classList.add('active_b');
2089            } else {
2090                topButton.classList.remove('active_b');
2091            }
2092        });
2093    }
2094
2095});
2096const searchInput = document.querySelector('.xans-layout-searchheader #keyword');
2097if (searchInput) {
2098    searchInput.setAttribute('placeholder', '어떤 상품을 찾으시나요?');
2099}
2100const top_banner_A_a = document.querySelector('.top_banner_A_a')
2101const top_banner_A_a_CloseBtn = document.querySelector('.top_banner_A_a .btn_banner_close')
2102
2103top_banner_A_a_CloseBtn.addEventListener('click',()=>{
2104    top_banner_A_a.style.display = 'none'
2105});
2106// 모바일 스크롤 이벤트
2107window.addEventListener('scroll', function () {
2108    const header = document.querySelector('header');
2109
2110    if (window.innerWidth <= 1024) {
2111        if (window.scrollY > 70) {
2112            header.classList.add('fixed');
2113        } else {
2114            header.classList.remove('fixed');
2115        }
2116    } else {
2117        header.classList.remove('fixed');
2118    }
2119});
2120
2121document.addEventListener('DOMContentLoaded', function () {
2122    // top_banner에 따른 header fixed 추가
2123    const header = document.getElementById('header');
2124    const topBanners = document.querySelectorAll('.top_banner');
2125
2126    let totalBannerHeight = 0;
2127
2128    function updateBannerHeight() {
2129        totalBannerHeight = 0;
2130        topBanners.forEach(banner => {
2131            totalBannerHeight += banner.offsetHeight;
2132        });
2133    }
2134
2135    function handleScroll() {
2136        if (window.scrollY > totalBannerHeight) {
2137            header.classList.add('fixed');
2138        } else {
2139            header.classList.remove('fixed');
2140        }
2141    }
2142
2143    updateBannerHeight();
2144    handleScroll();
2145
2146    window.addEventListener('resize', () => {
2147        updateBannerHeight();
2148        handleScroll();
2149    });
2150    window.addEventListener('scroll', handleScroll);
2151
2152    // 카테고리 이벤트
2153    const category = document.querySelector('#header .inner .top_category');
2154
2155    let isDown = false;
2156    let startX;
2157    let scrollLeft;
2158
2159    category.addEventListener('mousedown', (e) => {
2160        isDown = true;
2161        category.classList.add('dragging');
2162        startX = e.pageX - category.offsetLeft;
2163        scrollLeft = category.scrollLeft;
2164
2165        // 링크 기본동작 막기
2166        if (e.target.tagName === 'A') {
2167            e.preventDefault(); // 링크로 이동 막기
2168        }
2169    });
2170
2171    category.addEventListener('mouseleave', () => {
2172        isDown = false;
2173        category.classList.remove('dragging');
2174    });
2175
2176    category.addEventListener('mouseup', (e) => {
2177        isDown = false;
2178        category.classList.remove('dragging');
2179
2180        // 클릭 방지 (드래그 중 클릭이 발생하는 것을 막음)
2181        if (e.target.tagName === 'A') {
2182            e.preventDefault();
2183        }
2184    });
2185
2186    category.addEventListener('mousemove', (e) => {
2187        if (!isDown) return;
2188        e.preventDefault();
2189        const x = e.pageX - category.offsetLeft;
2190        const walk = (x - startX) * 1.5; // 이동 속도
2191        category.scrollLeft = scrollLeft - walk;
2192    });
2193});
2194function checkAsideC() {
2195    const asideC = document.querySelector('#aside.aside_C');
2196    if (!asideC) return;
2197
2198    let isHidden = false;
2199    let parent = asideC.parentElement;
2200
2201    while (parent) {
2202        const style = window.getComputedStyle(parent);
2203        if (style.display === 'none') {
2204            isHidden = true;
2205            break;
2206        }
2207        parent = parent.parentElement;
2208    }
2209
2210    if (!isHidden) {
2211        applyAsideC(asideC);
2212    }
2213}
2214
2215function applyAsideC(asideC) {
2216    // 중복 적용 방지
2217    if (asideC.dataset.applied === 'true') return;
2218    asideC.dataset.applied = 'true';
2219
2220    // 스타일 적용
2221    const style = document.createElement('style');
2222    style.textContent = `
2223    body.layout_mobile.expand { overflow: hidden; }
2224    body.layout_mobile.expand #aside { left: 0; visibility: visible; }
2225    body.layout_mobile.expand #layoutDimmed { display: none; }
2226    `;
2227    asideC.appendChild(style);
2228
2229    document.addEventListener('DOMContentLoaded', function () {
2230        const bottomNav = document.querySelector('.bottom_nav');
2231        const aside = document.getElementById('aside');
2232
2233        if (bottomNav && aside) {
2234            function setAsideHeightMobileOnly() {
2235                const viewportHeight = window.visualViewport ? window.visualViewport.height : window.innerHeight;
2236                const bottomNavHeight = bottomNav.offsetHeight || 0;
2237
2238                // height 계산
2239                aside.style.height = `${Math.max(0, viewportHeight - bottomNavHeight + 1)}px`;
2240
2241                // 현재 스크롤된 높이 + bottomNav 높이만큼 top 적용
2242                aside.style.top = `${window.scrollY}px`;
2243            }
2244
2245            window.addEventListener('resize', setAsideHeightMobileOnly);
2246            window.addEventListener('scroll', setAsideHeightMobileOnly); // 스크롤 감지 추가
2247            setAsideHeightMobileOnly();
2248        }
2249    });
2250
2251    const btnNavs = document.querySelectorAll('#aside .btnClose');
2252    btnNavs.forEach(function (btnNav) {
2253        btnNav.addEventListener('click', function () {
2254            document.body.classList.toggle('expand');
2255        });
2256    });
2257}
2258
2259// 초기 실행
2260checkAsideC();
2261
2262// 리사이즈 시 재확인
2263window.addEventListener('resize', checkAsideC);
2264$(function(){
2265    if (typeof(EC_SHOP_MULTISHOP_SHIPPING) != "undefined") {
2266        var sShippingCountryCode4Cookie = 'shippingCountryCode';
2267        var bShippingCountryProc = false;
2268
2269        // 배송국가 선택 설정이 사용안함이면 숨김
2270        if (EC_SHOP_MULTISHOP_SHIPPING.bMultishopShippingCountrySelection === false) {
2271            $('.xans-layout-multishopshipping .xans-layout-multishopshippingcountrylist').hide();
2272            $('.xans-layout-multishoplist .xans-layout-multishoplistmultioption .xans-layout-multishoplistmultioptioncountry').hide();
2273        } else {
2274            $('.thumb .xans-layout-multishoplistitem').hide();
2275            var aShippingCountryCode = document.cookie.match('(^|;) ?'+sShippingCountryCode4Cookie+'=([^;]*)(;|$)');
2276            if (typeof(aShippingCountryCode) != 'undefined' && aS
2276hippingCountryCode != null && aShippingCountryCode.length > 2) {
2277                var sShippingCountryValue = aShippingCountryCode[2];
2278            }
2279
2280            // query string으로 넘어 온 배송국가 값이 있다면, 그 값을 적용함
2281            var aHrefCountryValue = decodeURIComponent(location.href).split("/?country=");
2282
2283            if (aHrefCountryValue.length == 2) {
2284                var sShippingCountryValue = aHrefCountryValue[1];
2285            }
2286
2287            // 메인 페이지에서 국가선택을 안한 경우, 그 외의 페이지에서 셋팅된 값이 안 나오는 현상 처리
2288            if (location.href.split("/").length != 4 && $(".xans-layout-multishopshipping .xans-layout-multishopshippingcountrylist").val()) {
2289                $(".xans-layout-multishoplist .xans-layout-multishoplistmultioption a .ship span").text(" : "+$(".xans-layout-multishopshipping .xans-layout-multishopshippingcountrylist option:selected").text().split("SHIPPING TO : ").join(""));
2290
2291                if ($("#f_country").length > 0 && location.href.indexOf("orderform.html") > -1) {
2292                    $("#f_country").val($(".xans-layout-multishopshipping .xans-layout-multishopshippingcountrylist").val());
2293                }
2294            }
2295            if (typeof(sShippingCountryValue) != "undefined" && sShippingCountryValue != "" && sShippingCountryValue != null) {
2296                sShippingCountryValue = sShippingCountryValue.split("#")[0];
2297                var bShippingCountryProc = true;
2298
2299                $(".xans-layout-multishopshipping .xans-layout-multishopshippingcountrylist").val(sShippingCountryValue);
2300                $(".xans-layout-multishoplist .xans-layout-multishoplistmultioption a .ship span").text(" : "+$(".xans-layout-multishopshipping .xans-layout-multishopshippingcountrylist option:selected").text().split("SHIPPING TO : ").join(""));
2301                var expires = new Date();
2302                expires.setTime(expires.getTime() + (30 * 24 * 60 * 60 * 1000)); // 30일간 쿠키 유지
2303                document.cookie = sShippingCountryCode4Cookie+'=' + $(".xans-layout-multishopshipping .xans-layout-multishopshippingcountrylist").val() +';path=/'+ ';expires=' + expires.toUTCString();
2304                if ($("#f_country").length > 0 && location.href.indexOf("orderform.html") > -1) {
2305                    $("#f_country").val(sShippingCountryValue).change();
2306                }
2307            }
2308        }
2309        // 언어선택 설정이 사용안함이면 숨김
2310        if (EC_SHOP_MULTISHOP_SHIPPING.bMultishopShippingLanguageSelection === false) {
2311            $('.xans-layout-multishopshipping .xans-layout-multishopshippinglanguagelist').hide();
2312            $('.xans-layout-multishoplist .xans-layout-multishoplistmultioption .xans-layout-multishoplistmultioptionlanguage').hide();
2313        } else {
2314            $('.thumb .xans-layout-multishoplistitem').hide();
2315        }
2316
2317        // 배송국가 및 언어 설정이 둘 다 사용안함이면 숨김
2318        if (EC_SHOP_MULTISHOP_SHIPPING.bMultishopShipping === false) {
2319            $(".xans-layout-multishopshipping").hide();
2320            $('.xans-layout-multishoplist .xans-layout-multishoplistmultioption').hide();
2321        } else if (bShippingCountryProc === false && location.href.split("/").length == 4) { // 배송국가 값을 처리한 적이 없고, 메인화면일 때만 선택 레이어를 띄움
2322            var sShippingCountryValue = $(".xans-layout-multishopshipping .xans-layout-multishopshippingcountrylist").val();
2323            $(".xans-layout-multishopshipping .xans-layout-multishopshippingcountrylist").val(sShippingCountryValue);
2324            $(".xans-layout-multishoplist .xans-layout-multishoplistmultioption a .ship span").text(" : "+$(".xans-layout-multishopshipping .xans-layout-multishopshippingcountrylist option:selected").text().split("SHIPPING TO : ").join(""));
2325            // 배송국가 선택을 사용해야 레이어를 보이게 함
2326            if (EC_SHOP_MULTISHOP_SHIPPING.bMultishopShippingCountrySelection === true) {
2327                $(".xans-layout-multishopshipping").show();
2328            }
2329        }
2330
2331        $(".xans-layout-multishopshipping .close").on("click", function() {
2332            $(".xans-layout-multishopshipping").hide();
2333        });
2334
2335        $(".xans-layout-multishopshipping .ec-base-button a").on("click", function() {
2336            var expires = new Date();
2337            expires.setTime(expires.getTime() + (30 * 24 * 60 * 60 * 1000)); // 30일간 쿠키 유지
2338            document.cookie = sShippingCountryCode4Cookie+'=' + $(".xans-layout-multishopshipping .xans-layout-multishopshippingcountrylist").val() +';path=/'+ ';expires=' + expires.toUTCString();
2339
2340            // 도메인 문제로 쿠키로 배송국가 설정이 안 되는 경우를 위해 query string으로 배송국가 값
2340을 넘김
2341            var sQuerySting = (EC_SHOP_MULTISHOP_SHIPPING.bMultishopShippingCountrySelection === false) ? "" : "/?country="+encodeURIComponent($(".xans-layout-multishopshipping .xans-layout-multishopshippingcountrylist").val());
2342
2343            location.href = '//'+$(".xans-layout-multishopshipping .xans-layout-multishopshippinglanguagelist").val()+sQuerySting;
2344        });
2345        $(".xans-layout-multishoplist .xans-layout-multishoplistmultioption a").on("click", function() {
2346            $(".xans-layout-multishopshipping").show();
2347        });
2348    }
2349});
2350/**
2351 * 상품 정보 표시 설정
2352 *
2353 * @property {string} label - 항목명 표시 텍스트 (운영자 수정 가능)
2354 *   - $ prefix: 부분 매칭 (예: '$할인가' → 'VIP할인가', '최고회원할인가' 매칭)
2355 * @property {string} class - 적용할 데코레이션 클래스 (고정)
2356 * @property {string} detailLabel - 상세 페이지 레이블 (할인판매가/최적할인가 둘 다 있을 때 표시)
2357 * @property {number} order - 상세 페이지 노출 순서 (낮을수록 위)
2358 */
2359window.styleMap = {
2360    product_name: {
2361        label: '상품명',
2362        class: 'deco_title',
2363        order: 1
2364    },
2365    price: {
2366        label: '판매가',
2367        class: 'deco_price',
2368        order: 2
2369    },
2370    sale_price: {
2371        label: '할인판매가',
2372        class: 'deco_sale_price',
2373        detailLabel: '할인판매가',
2374        order: 3
2375    },
2376    optimum_price: {
2377        label: '최적할인가',
2378        class: 'deco_optimum_price',
2379        detailLabel: '최적할인가',
2380        order: 5
2381    },
2382    member_sale_price: {
2383        label: '$할인가',
2384        class: 'deco_member_sale_price',
2385        detailLabel: '할인판매가',
2386        order: 4
2387    },
2388    member_optimum_price: {
2389        label: '$최적가',
2390        class: 'deco_member_optimum_price',
2391        detailLabel: '최적할인가',
2392        order: 6
2393    }
2394};
2395
2396/**
2397 * 스타일 클래스 정의
2398 */
2399window.styleClasses = {
2400    strikethrough: 'deco_strikethrough',
2401    memberSaleDisplayText: 'member_sale_display_text',
2402    memberOptimumDisplayText: 'member_optimum_display_text',
2403    memberOptimumPriceLabel: 'member_optimum_price_label'
2404};
2405
2406/**
2407 * 텍스트 정규화 (공백 제거)
2408 */
2409const normalizeKey = (text) => text?.replace(/\s+/g, '') || '';
2410
2411/**
2412 * styleMap에서 항목명 매칭
2413 * @param {string} key - 정규화된 항목명
2414 * @returns {Object|null} { id, class } 또는 null
2415 */
2416const findStyleMatch = (key) => {
2417    if (!window.styleMap || !key) return null;
2418
2419    for (const id in window.styleMap) {
2420        const config = window.styleMap[id];
2421        if (!config?.label) continue;
2422
2423        const label = config.label;
2424
2425        // 정확 매칭 우선 ($ 없는 label)
2426        if (!label.startsWith('$') && key === label) {
2427            return { id, class: config.class };
2428        }
2429
2430        // 부분 매칭 ($ 붙은 label)
2431        if (label.startsWith('$') && key.includes(label.substring(1))) {
2432            return { id, class: config.class };
2433        }
2434    }
2435
2436    return null;
2437};
2438
2439/**
2440 * inline style 제거 (img 태그 제외)
2441 */
2442const removeInlineStyles = (element) => {
2443    element.querySelectorAll('*[style]:not(img)').forEach(el => el.removeAttribute('style'));
2444};
2445
2446/**
2447 * 상품 목록 처리 (메인/목록/검색)
2448 */
2449function processListItems(listItems) {
2450    if (!listItems?.length) return;
2451
2452    let hasDiscountPrice = false;
2453    let hasSalePrice = false;
2454    let hasOptimumPrice = false;
2455    let priceElement = null;
2456    const highlightedItems = [];
2457
2458    // 상품명 처리 (첫 번째 li 기준)
2459    const firstItem = listItems[0];
2460    const prdListItem = firstItem?.closest('.prdList__item');
2461    const nameElement = prdListItem?.querySelector('.description .name');
2462
2463    if (nameElement && window.styleMap?.product_name) {
2464        nameElement.classList.add(window.styleMap.product_name.class);
2465        removeInlineStyles(nameElement);
2466        nameElement.querySelector('strong.title')?.classList.add('displaynone');
2467    }
2468
2469    // li 항목 처리
2470    listItems.forEach(item => {
2471        const titleSpans = item?.querySelectorAll('strong.title span');
2472        if (!titleSpans?.length) return;
2473
2474        titleSpans.forEach(titleSpan => {
2475            const key = normalizeKey(titleSpan.textContent);
2476            const liElement = titleSpan.closest('li');
2477            if (!liElement) return;
2478
2479            // 항목명 숨김
2480            titleSpan.closest('strong.title')?.classList.add('displaynone');
2481
2482            // styleMap 매칭
2483            const matched = findStyleMatch(key);
2484
2485            if (matched) {
2486                // 강조 대상 항목
2487                liElement.classList.add(matched.class);
2488                removeInlineStyles(liElement);
2489                highlightedItems.push({ liElement, matched });
2490
2491                // 부가세 표시문구 숨김
2492                liElement.querySelector('#span_product_tax_type_text')?.classList.add('displaynone');
2493
2494                // 할인가 유형 체크
2495                if (['sale_price', 'member_sale_price'].includes(matched.id)) {
2496                    hasSalePrice = true;
2497                    hasDiscountPrice = true;
2498                }
2499                if (['optimum_price', 'member_optimum_price'].includes(matched.id)) {
2500                    hasOptimumPrice = true;
2501                    hasDiscountPrice = true;
2502                }
2503
2504                // 판매가 저장
2505                if (matched.id === 'price') {
2506                    priceElement = liElement;
2507                }
2508            } else {
2509                // 비강조 항목 숨김
2510                liElement.classList.add('displaynone');
2511            }
2512        });
2513    });
2514
2515    // 판매가 취소선 적용
2516    if (hasDiscountPrice && priceElement && window.styleClasses?.strikethrough) {
2517        priceElement.classList.add(window.styleClasses.strikethrough);
2518    }
2519
2520    // 할인/최적 레이블 추가 (둘 다 있을 때만, 최적할인가만 표시)
2521    if (hasSalePrice && hasOptimumPrice && window.styleClasses?.memberOptimumPrice
2521Label) {
2522        highlightedItems.forEach(({ liElement, matched }) => {
2523            const config = window.styleMap?.[matched.id];
2524
2525            if (config?.detailLabel && ['optimum_price', 'member_optimum_price'].includes(matched.id)) {
2526                const valueSpan = liElement.querySelector(':scope > span');
2527                const innerSpan = valueSpan?.querySelector('span'); // 내부 span 찾기
2528                const existingLabel = innerSpan?.querySelector(`.${window.styleClasses.memberOptimumPriceLabel}`);
2529
2530                if (innerSpan && !existingLabel) {
2531                    const label = document.createElement('span');
2532                    label.className = window.styleClasses.memberOptimumPriceLabel;
2533                    label.textContent = ` ${config.detailLabel}`;
2534                    innerSpan.appendChild(label);
2535                }
2536            }
2537        });
2538    }
2539
2540    // 하나만 있을 때 single 클래스 추가
2541    if ((hasSalePrice && !hasOptimumPrice) || (!hasSalePrice && hasOptimumPrice)) {
2542        highlightedItems.forEach(({ liElement, matched }) => {
2543            if (['sale_price', 'member_sale_price', 'optimum_price', 'member_optimum_price'].includes(matched.id)) {
2544                liElement.classList.add('single');
2545            }
2546        });
2547    }
2548}
2549
2550/**
2551 * 상품 상세 처리
2552 */
2553function processDetailItems(rows) {
2554    if (!rows?.length) return;
2555
2556    let hasDiscountPrice = false;
2557    let hasSalePrice = false;
2558    let hasOptimumPrice = false;
2559    let priceRow = null;
2560    const highlightedRows = [];
2561    const rowDataMap = new Map();
2562
2563    // 1단계: 모든 tr 처리
2564    rows.forEach(tr => {
2565        const thSpan = tr.querySelector('th span');
2566        if (!thSpan) return;
2567
2568        const key = normalizeKey(thSpan.textContent);
2569        const matched = findStyleMatch(key);
2570
2571        if (matched) {
2572            // 강조 대상 항목
2573            highlightedRows.push(tr);
2574            rowDataMap.set(tr, matched);
2575
2576            // 항목명 숨김
2577            thSpan.closest('th')?.classList.add('displaynone');
2578
2579            // 클래스 추가
2580            tr.classList.add(matched.class);
2581
2582            // inline style 제거
2583            const td = tr.querySelector('td');
2584            if (td) {
2585                removeInlineStyles(td);
2586                // deco_와 price가 둘 다 포함된 클래스일 때만 colspan 추가
2587                if (matched.class.includes('deco_') && matched.class.includes('price')) {
2588                    td.setAttribute('colspan', '2');
2589                }
2590            }
2591
2592            // 할인가 유형 체크
2593            if (['sale_price', 'member_sale_price'].includes(matched.id)) {
2594                hasSalePrice = true;
2595                hasDiscountPrice = true;
2596            }
2597            if (['optimum_price', 'member_optimum_price'].includes(matched.id)) {
2598                hasOptimumPrice = true;
2599                hasDiscountPrice = true;
2600            }
2601
2602            // 판매가 저장
2603            if (matched.id === 'price') {
2604                priceRow = tr;
2605            }
2606        }
2607    });
2608
2609    // 2단계: 순서 재정렬 (order 기준 정렬)
2610    const tbody = rows[0]?.closest('tbody');
2611    if (tbody && highlightedRows.length) {
2612        // order 값으로 정렬 (낮을수록 위)
2613        const sortedRows = highlightedRows.sort((a, b) => {
2614            const orderA = window.styleMap?.[rowDataMap.get(a)?.id]?.order || 999;
2615            const orderB = window.styleMap?.[rowDataMap.get(b)?.id]?.order || 999;
2616            return orderA - orderB;
2617        });
2618
2619        // 정렬된 순서대로 맨 위에 배치
2620        sortedRows.reverse().forEach(tr => tbody.prepend(tr));
2621    }
2622
2623    // 3단계: 판매가 취소선 적용
2624    if (hasDiscountPrice && priceRow && window.styleClasses?.strikethrough) {
2625        priceRow.classList.add(window.styleClasses.strikethrough);
2626    }
2627
2628    // 4단계: member 등급명 이동 처리
2629    highlightedRows.forEach(tr => {
2630        const rowData = rowDataMap.get(tr);
2631
2632        // member_sale_price 등급명 이동
2633        if (rowData?.id === 'member_sale_price') {
2634            const td = tr.querySelector('td');
2635            if (td) {
2636                const spans = td.querySelectorAll(':scope > span');
2637                if (spans.length > 1) {
2638                    const gradeSpan = spans[0];
2639                    const gradeText = gradeSpan.textContent.trim();
2640                    const valueSpan = spans[1].querySelector('span[id*="sale"]');
2641
2642                    if (valueSpan && gradeText && window.styleClasses?.memberSaleDisplayText) {
2643                        const existingLabel = valueSpan.querySelector(`.${window.styleClasses.memberSaleDisplayText}`);
2644                        if (!existingLabel) {
2645                            const gradeLabel = document.createElement('span');
2646                            gradeLabel.className = window.styleClasses.memberSaleDisplayText;
2647                            gradeLabel.textContent = ` ${gradeText}`;
2648                            valueSpan.appendChild(gradeLabel);
2649                            gradeSpan.classList.add('displaynone');
2650                        }
2651                    }
2652                }
2653            }
2654        }
2655
2656        // member_optimum_price 등급명 이동
2657        if (rowData?.id === 'member_optimum_price') {
2658            const td = tr.querySelector('td');
2659            if (td) {
2660                const spans = td.querySelectorAll(':scope > span');
2661                if (spans.length > 1) {
2662                    const gradeSpan = spans[0];
2663                    const gradeText = gradeSpan.textContent.trim();
2664                    const valueSpan = spans[1].querySelector('span[id^="span_optimum"]');
2665
2666                    if (valueSpan && gradeText && window.styleClasses?.memberOptimumDisplayText) {
2667                        const existingLabel = valueSpan.querySelector(`.${window.styleClasses.memberOptimumDisplayText}`);
2668                        if (!existingLabel) {
2669                            const gradeLabel = document.createElement('span');
2670                            gradeLabel.className = window.styleClasses.memberOptimumDisplayText;
2671                            gradeLabel.textContent = ` ${gradeText}`;
2672                            valueSpan.appendChild(gradeLabel);
2673                            gradeSpan.classList.add('displaynone');
2674                        }
2675                    }
2676                }
2677            }
2678        }
2679    });
2680
2681    // 5단계: 할인/최적 레이블 추가 및 중복 등급명 숨김 (둘 다 있을 때만)
2682    if (hasSalePrice && hasOptimumPrice) {
2683        highlightedRows.forEach(tr => {
2684            const rowData = rowDataMap.get(tr);
2685            const config = window.styleMap?.[rowData?.id];
2686
2687            // member_sale_price 등급명 숨김
2688            if (rowData?.id === 'member_sale_price' && window.styleClasses?.memberSaleDisplayText) {
2689                const td = tr.querySelector('td');
2690                if (td) {
2691                    const gradeLabel = td.querySelector(`.${window.styleClasses.memberSaleDisplayText}`);
2692                    if (gradeLabel) {
2693                        gradeLabel.classList.add('displaynone');
2694                    }
2695                }
2696            }
2697
2698            // 최적할인가 레이블 추가
2699            if (config?.detailLabel && ['optimum_price', 'member_optimum_price'].includes(rowData?.id) && window.styleClasses?.memberOptimumPrice
2699Label) {
2700                const td = tr.querySelector('td');
2701                if (td) {
2702                    const valueSpan = td.querySelector('span[id^="span_optimum"]');
2703                    const existingLabel = valueSpan?.querySelector(`.${window.styleClasses.memberOptimumPriceLabel}`);
2704
2705                    if (valueSpan && !existingLabel) {
2706                        const label = document.createElement('span');
2707                        label.className = window.styleClasses.memberOptimumPriceLabel;
2708                        label.textContent = ` ${config.detailLabel}`;
2709                        valueSpan.appendChild(label);
2710                    }
2711                }
2712            }
2713        });
2714    }
2715
2716    // 하나만 있을 때 single 클래스 추가
2717    if ((hasSalePrice && !hasOptimumPrice) || (!hasSalePrice && hasOptimumPrice)) {
2718        highlightedRows.forEach(tr => {
2719            const rowData = rowDataMap.get(tr);
2720            if (rowData && ['sale_price', 'member_sale_price', 'optimum_price', 'member_optimum_price'].includes(rowData.id)) {
2721                tr.classList.add('single');
2722            }
2723        });
2724    }
2725}
2726
2727/**
2728 * 상품 목록 동적 변경 감지
2729 */
2730const observeProductList = () => {
2731    const containers = document.querySelectorAll('.xans-product-listnormal, .xans-product-listmain, .xans-product-listnew');
2732
2733    containers.forEach(container => {
2734        const observer = new MutationObserver(mutations => {
2735            mutations.forEach(mutation => {
2736                mutation.addedNodes.forEach(node => {
2737                    if (node.nodeType !== Node.ELEMENT_NODE) return;
2738
2739                    const items = node.matches?.('.prdList__item')
2740                        ? [node]
2741                        : [...(node.querySelectorAll?.('.prdList__item') || [])];
2742
2743                    items.forEach(item => {
2744                        const ul = item.querySelector('ul.spec');
2745                        if (ul) {
2746                            processListItems([...ul.querySelectorAll('li')]);
2747                        }
2748                    });
2749                });
2750            });
2751        });
2752
2753        observer.observe(container, { childList: true, subtree: true });
2754    });
2755};
2756
2757/**
2758 * 초기화
2759 */
2760(() => {
2761    // 상품 목록
2762    document.querySelectorAll('.prdList__item').forEach(item => {
2763        const ul = item.querySelector('ul.spec');
2764        if (ul) {
2765            processListItems([...ul.querySelectorAll('li')]);
2766        }
2767    });
2768
2769    // 동적 상품 감지
2770    observeProductList();
2771
2772    // 상품 상세
2773    document.querySelectorAll('.xans-product-detail table.info_table tbody').forEach(tbody => {
2774        processDetailItems([...tbody.querySelectorAll('tr')]);
2775    });
2776})();
2777
2778/**
2779 * 위시리스트 버튼 후처리
2780 */
2781document.addEventListener('DOMContentLoaded', () => {
2782    const updateWishStatus = (button) => {
2783        const img = button.querySelector('img');
2784        if (!img) return;
2785
2786        const status = img.getAttribute('icon_status');
2787        button.classList.toggle('active', status === 'on');
2788    };
2789
2790    const handleWishClick = (button) => {
2791        const img = button.querySelector('img');
2792        if (img) {
2793            img.click();
2794            setTimeout(() => updateWishStatus(button), 300);
2795        }
2796    };
2797
2798    document.querySelectorAll('.top_btn .wish').forEach(button => {
2799        const img = button.querySelector('img');
2800        if (img) {
2801            button.style.display = 'flex';
2802            setTimeout(() => updateWishStatus(button), 300);
2803            button.addEventListener('click', () => handleWishClick(button));
2804        }
2805    });
2806});
2807
2808/**
2809 * Custom Modal Functions
2810 * 브라우저 기본 alert/confirm을 디자인된 모달로 대체
2811 *
2812 * Usage:
2813 *   customAlert('메시지');
2814 *   customAlert('메시지', callback);
2815 *   customConfirm('메시지', onConfirm, onCancel);
2816 *
2817 * Behavior:
2818 *   - 버튼 클릭 또는 ESC 키로 닫기 (배경 클릭 비활성화)
2819 *   - Alert: ESC = 확인
2820 *   - Confirm: ESC = 취소
2821 *
2822 * Accessibility:
2823 *   - 포커스 트랩 (Tab/Shift+Tab)
2824 *   - 열릴 때 첫 버튼 포커스
2825 *   - 닫힐 때 이전 포커스 복원
2826 *   - body scroll lock (모달 열릴 때)
2827 *   - 다중 모달 방지
2828 */
2829
2830var CustomModal = (function() {
2831    var alertCallback = null;
2832    var confirmCallback = null;
2833    var cancelCallback = null;
2834    var previousFocus = null;
2835    var previousBodyOverflow = null;
2836    var openModalCount = 0;
2837    var mainContentSelector = 'main, #wrap, #container, .wrapper, body > *:not([id^="custom"])';
2838
2839    // 포커스 가능한 요소 선택자
2840    var FOCUSABLE_SELECTOR = 'button, [href], input, select, textarea, [tabindex]:not
2840([tabindex="-1"])';
2841
2842    // 포커스 가능 여부 필터링 (disabled, hidden, aria-hidden 제외)
2843    function isElementFocusable(el) {
2844        if (el.disabled) return false;
2845        if (el.hidden) return false;
2846        if (el.getAttribute('aria-hidden') === 'true') return false;
2847        if (el.tabIndex < 0) return false;
2848        if (el.offsetParent === null && getComputedStyle(el).position !== 'fixed') return false;
2849        return true;
2850    }
2851
2852    // 모달 내 포커스 가능 요소 목록 (필터링 적용)
2853    function getFocusableElements(modal) {
2854        var elements = modal.querySelectorAll(FOCUSABLE_SELECTOR);
2855        var result = [];
2856        for (var i = 0; i < elements.length; i++) {
2857            if (isElementFocusable(elements[i])) {
2858                result.push(elements[i]);
2859            }
2860        }
2861        return result;
2862    }
2863
2864    // 배경 콘텐츠 inert 처리
2865    function setBackgroundInert(inert) {
2866        var mainElements = document.querySelectorAll(mainContentSelector);
2867        for (var i = 0; i < mainElements.length; i++) {
2868            var el = mainElements[i];
2869            // 모달 자체는 제외
2870            if (el.id === 'customAlertModal' || el.id === 'customConfirmModal') continue;
2871            if (inert) {
2872                el.setAttribute('inert', '');
2873                el.setAttribute('aria-hidden', 'true');
2874            } else {
2875                el.removeAttribute('inert');
2876                el.removeAttribute('aria-hidden');
2877            }
2878        }
2879    }
2880
2881    // body scroll lock
2882    function lockBodyScroll() {
2883        if (openModalCount === 0) {
2884            previousBodyOverflow = document.body.style.overflow;
2885            document.body.style.overflow = 'hidden';
2886        }
2887        openModalCount++;
2888    }
2889
2890    function unlockBodyScroll() {
2891        openModalCount--;
2892        if (openModalCount <= 0) {
2893            openModalCount = 0;
2894            document.body.style.overflow = previousBodyOverflow || '';
2895            previousBodyOverflow = null;
2896        }
2897    }
2898
2899    // 모달 열림 상태 확인
2900    function isAnyModalOpen() {
2901        var alertModal = document.getElementById('customAlertModal');
2902        var confirmModal = document.getElementById('customConfirmModal');
2903        var isAlertOpen = alertModal && !alertModal.hidden;
2904        var isConfirmOpen = confirmModal && !confirmModal.hidden;
2905        return isAlertOpen || isConfirmOpen;
2906    }
2907
2908    function trapFocus(modal, e) {
2909        var focusableElements = getFocusableElements(modal);
2910        if (focusableElements.length === 0) return;
2911
2912        var firstElement = focusableElements[0];
2913        var lastElement = focusableElements[focusableElements.length - 1];
2914
2915        // activeElement가 모달 밖이면 강제로 첫 요소로 되돌림
2916        if (!modal.contains(document.activeElement)) {
2917            e.preventDefault();
2918            firstElement.focus();
2919            return;
2920        }
2921
2922        if (e.shiftKey && document.activeElement === firstElement) {
2923            e.preventDefault();
2924            lastElement.focus();
2925        } else if (!e.shiftKey && document.activeElement === lastElement) {
2926            e.preventDefault();
2927            firstElement.focus();
2928        }
2929    }
2930
2931    // 포커스 이탈 감지 및 복귀 (focusin 이벤트용)
2932    function handleFocusIn(e) {
2933        var alertModal = document.getElementById('customAlertModal');
2934        var confirmModal = document.getElementById('customConfirmModal');
2935
2936        var isAlertOpen = alertModal && !alertModal.hidden;
2937        var isConfirmOpen = confirmModal && !confirmModal.hidden;
2938
2939        if (!isAlertOpen && !isConfirmOpen) return;
2940
2941        var activeModal = isAlertOpen ? alertModal : confirmModal;
2942
2943        // 포커스가 모달 밖으로 나갔으면 첫 요소로 되돌림
2944        if (!activeModal.contains(e.target)) {
2945            var focusableElements = getFocusableElements(activeModal);
2946            if (focusableElements.length > 0) {
2947                focusableElements[0].focus();
2948            }
2949        }
2950    }
2951
2952    function handleKeydown(e) {
2953        var alertModal = document.getElementById('customAlertModal');
2954        var confirmModal = document.getElementById('customConfirmModal');
2955
2956        var isAlertOpen = alertModal && !alertModal.hidden;
2957        var isConfirmOpen = confirmModal && !confirmModal.hidden;
2958
2959        if (!isAlertOpen && !isConfirmOpen) return;
2960
2961        // ESC 키로 닫기
2962        if (e.key === 'Escape' || e.keyCode === 27) {
2963            e.preventDefault();
2964            if (isAlertOpen) {
2965                closeAlert(); // Alert: 확인과 동일
2966            } else if (isConfirmOpen) {
2967                closeConfirm(false); // Confirm: 취소와 동일
2968            }
2969            return;
2970        }
2971
2972        // Tab 키 포커스 트랩
2973        if (e.key === 'Tab' || e.keyCode === 9) {
2974            var activeModal = isAlertOpen ? alertModal : confirmModal;
2975            trapFocus(activeModal, e);
2976        }
2977    }
2978
2979    function saveFocus() {
2980        previousFocus = document.activeElement;
2981    }
2982
2983    function restoreFocus() {
2984        if (previousFocus && typeof previousFocus.focus === 'function') {
2985            try {
2986                previousFocus.focus();
2987            } catch (e) {
2988                // 포커스 복원 실패 시 무시
2989            }
2990        }
2991        previousFocus = null;
2992    }
2993
2994    function focusFirstButton(modal) {
2995        var firstButton = modal.querySelector('button');
2996        if (firstButton) {
2997            firstButton.focus();
2998        }
2999    }
3000
3001    function closeAlert() {
3002        var modal = document.getElementById('customAlertModal');
3003        if (modal && !modal.hidden) {
3004            modal.hidden = true;
3005            setBackgroundInert(false);
3006            unlockBodyScroll();
3007        }
3008        restoreFocus();
3009        if (typeof alertCallback === 'function') {
3010            var cb = alertCallback;
3011            alertCallback = null;
3012            try {
3013                cb();
3014            } catch (e) {
3015                console.error('CustomAlert callback error:', e);
3016            }
3017        }
3018    }
3019
3020    function closeConfirm(confirmed) {
3021        var modal = document.getElementById('customConfirmModal');
3022        if (modal && !modal.hidden) {
3023            modal.hidden = true;
3024            setBackgroundInert(false);
3025            unlockBodyScroll();
3026        }
3027        restoreFocus();
3028        if (confirmed && typeof confirmCallback === 'function') {
3029            var cb = confirmCallback;
3030            confirmCallback = null;
3031            cancelCallback = null;
3032            try {
3033                cb();
3034            } catch (e) {
3035                console.error('CustomConfirm callback error:', e);
3036            }
3037        } else if (!confirmed && typeof cancelCallback === 'function') {
3038            var cb = cancelCallback;
3039            confirmCallback = null;
3040            cancelCallback = null;
3041            try {
3042                cb();
3043            } catch (e) {
3044                console.error('CustomConfirm cancel callback error:', e);
3045            }
3046        } else {
3047            confirmCallback = null;
3048            cancelCallback = null;
3049        }
3050    }
3051
3052    function showAlert(message, callback) {
3053        // 다중 모달 방지: 이미 모달이 열려있으면 기본 alert 사용
3054        if (isAnyModalOpen()) {
3055            alert(message);
3056            if (typeof callback === 'function') {
3057                try {
3058                    callback();
3059                } catch (e) {
3060                    console.error('CustomAlert fallback callback error:', e);
3061                }
3062            }
3063            return;
3064        }
3065
3066        alertCallback = callback || null;
3067        var modal = document.getElementById('customAlertModal');
3068        var title = document.getElementById('customAlertTitle');
3069        if (!modal || !title) {
3070            alert(message);
3071            if (typeof callback === 'function') {
3072                try {
3073                    callback();
3074                } catch (e) {
3075                    console.error('CustomAlert fallback callback error:', e);
3076                }
3077            }
3078            return;
3079        }
3080        saveFocus();
3081        lockBodyScroll();
3082        setBackgroundInert(true);
3083        title.textContent = message;
3084        modal.hidden = false;
3085        // 모달 컨테이너에 포커스 후 첫 버튼으로 이동
3086        var dialogContainer = modal.querySelector('[role="alertdialog"]');
3087        if (dialogContainer) dialogContainer.focus();
3088        focusFirstButton(modal);
3089    }
3090
3091    function showConfirm(message, onConfirm, onCancel) {
3092        // 다중 모달 방지: 이미 모달이 열려있으면 기본 confirm 사용
3093        if (isAnyModalOpen()) {
3094            if (confirm(message)) {
3095                if (typeof onConfirm === 'function') {
3096                    try {
3097                        onConfirm();
3098                    } catch (e) {
3099                        console.error('CustomConfirm fallback callback error:', e);
3100                    }
3101                }
3102            } else {
3103                if (typeof onCancel === 'function') {
3104                    try {
3105                        onCancel();
3106                    } catch (e) {
3107                        console.error('CustomConfirm fallback cancel callback error:', e);
3108                    }
3109                }
3110            }
3111            return;
3112        }
3113
3114        confirmCallback = onConfirm || null;
3115        cancelCallback = onCancel || null;
3116        var modal = document.getElementById('customConfirmModal');
3117        var title = document.getElementById('customConfirmTitle');
3118        if (!modal || !title) {
3119            if (confirm(message)) {
3120                if (typeof onConfirm === 'function') {
3121                    try {
3122                        onConfirm();
3123                    } catch (e) {
3124                        console.error('CustomConfirm fallback callback error:', e);
3125                    }
3126                }
3127            } else {
3128                if (typeof onCancel === 'function') {
3129                    try {
3130                        onCancel();
3131                    } catch (e) {
3132                        console.error('CustomConfirm fallback cancel callback error:', e);
3133                    }
3134                }
3135            }
3136            return;
3137        }
3138        saveFocus();
3139        lockBodyScroll();
3140        setBackgroundInert(true);
3141        title.textContent = message;
3142        modal.hidden = false;
3143        // 모달 컨테이너에 포커스 후 취소 버튼으로 이동 (안전한 기본값)
3144        var dialogContainer = modal.querySelector('[role="dialog"]');
3145        if (dialogContainer) dialogContainer.focus();
3146        var cancelButton = modal.querySelector('[data-action="cancel"]');
3147        if (cancelButton) {
3148            cancelButton.focus();
3149        }
3150    }
3151
3152    // 키보드 이벤트 리스너 등록
3153    document.addEventListener('keydown', handleKeydown);
3154    // 포커스 이탈 감지 리스너 등록
3155    document.addEventListener('focusin', handleFocusIn);
3156
3157    return {
3158        alert: showAlert,
3159        confirm: showConfirm,
3160        closeAlert: closeAlert,
3161        closeConfirm: closeConfirm,
3162        isOpen: isAnyModalOpen
3163    };
3164})();
3165
3166function customAlert(message, callback) {
3167    CustomModal.alert(message, callback);
3168}
3169
3170function customConfirm(message, onConfirm, onCancel) {
3171    CustomModal.confirm(message, onConfirm, onCancel);
3172}
3173
3174var aCategory = [];
3175$(function(){
3176    var methods = {
3177        aCategory    : [],
3178        aSubCategory : {},
3179        get: function() {
3180             $.ajax({
3181                url : '/exec/front/Product/SubCategory',
3182                dataType: 'json',
3183                success: function(aData) {
3184                    if (aData == null || aData == 'undefined') {
3185                        methods.checkSub();
3186                        return;
3187                    }
3188                    for (var i=0; i<aData.length; i++)
3189                    {
3190                        var sParentCateNo = aData[i].parent_cate_no;
3191                        var sCateNo = aData[i].cate_no;
3192                        if (!methods.aSubCategory[sParentCateNo]) {
3193                            methods.aSubCategory[sParentCateNo] = [];
3194                        }
3195                        if (!aCategory[sCateNo]) {
3196                            aCategory[sCateNo] = [];
3197                        }
3198                        methods.aSubCategory[sParentCateNo].push( aData[i] );
3199                        aCategory[sCateNo] = aData[i];
3200                    }
3201                    methods.checkSub();
3202                }
3203            });
3204        },
3205        getParam: function(sUrl, sKey) {
3206            if (typeof sUrl !== 'string') return;
3207            var aUrl         = sUrl.split('?');
3208            var sQueryString = aUrl[1];
3209            var aParam       = {};
3210            if (sQueryString) {
3211                var aFields = sQueryString.split("&");
3212                var aField  = [];
3213                for (var i=0; i<aFields.length; i++) {
3214                    aField = aFields[i].split('=');
3215                    aParam[aField[0]] = aField[1];
3216                }
3217            }
3218            return sKey ? aParam[sKey] : aParam;
3219        },
3220        getParamSeo: function(sUrl) {
3221            var aUrl = EC_ROUTE.getCleanUrl(sUrl).split('/');
3222            return aUrl[3] ? aUrl[3] : null;
3223        },
3224
3225        show: function(overNode, iCateNo) {
3226             var oParentNode = overNode;
3227            var aHtml = [];
3228            var sMyCateList = localStorage.getItem("myCateList");
3229            if (methods.aSubCategory[iCateNo] != undefined) {
3230                aHtml.push('<ul class="slideSubMenu sub_cate01">');
3231                $(methods.aSubCategory[iCateNo]).each(function() {
3232                    var sNextParentNo = this.cate_no;
3233                    var sCateSelected = (checkInArray(sMyCateList, this.cate_no) == true) ? ' selected' : '';
3234                    if (methods.aSubCategory[sNextParentNo] == undefined) {
3235                        aHtml.push('<li class="noChild" id="cate'+this.cate_no+'">');
3236                        var sHref = '/product/list.html'+this.param;
3237                    } else {
3238                        aHtml.push('<li id="cate'+this.cate_no+'">');
3239                        var sHref = '#none';
3240                    }
3241                    aHtml.push('<a href="/product/list.html'+this.param+'" class="view" cate="'+this.param+'" data-i18n="LIST.PRD_CATE_NO_'+this.cate_no+'" data-i18n-new>'+this.name+'</a>');
3242                    if (methods.aSubCategory[sNextParentNo] != undefined)  aHtml.push('<a href="'+sHref+'"'+this.param+'" onclick="subMenuEvent(this);" class="cate">more</a>');
3243
3244                    if (methods.aSubCategory[sNextParentNo] != undefined) {
3245                        aHtml.push('<ul class="sub_cate02">');
3246                        $(methods.aSubCategory[sNextParentNo]).each(function() {
3247                            var sNextParentNo2 = this.cate_no;
3248                            var sCateSelected = (checkInArray(sMyCateList, this.cate_no) == true) ? ' selected' : '';
3249                            if (methods.aSubCategory[sNextParentNo2] == undefined) {
3250                                aHtml.push('<li class="noChild" id="cate'+this.cate_no+'">');
3251                                var sHref = '/product/list.html'+this.param;
3252                            } else {
3253                                aHtml.push('<li id="cate'+this.cate_no+'">');
3254                                var sHref = '#none';
3255                            }
3256                            aHtml.push('<a href="/product/list.html'+this.param+'" class="view" cate="'+this.param+'" data-i18n="LIST.PRD_CATE_NO_'+this.cate_no+'" data-i18n-new>'+this.name+'</a>');
3257                            if (methods.aSubCategory[sNextParentNo] != undefined)  aHtml.push('<a href="'+sHref+'"'+this.param+'" onclick="subMenuEvent(this);" class="cate">more</a>');
3258
3259                            if (methods.aSubCategory[sNextParentNo2] != undefined) {
3260                                aHtml.push('<ul class="sub_cate03">');
3261
3262                                $(methods.aSubCategory[sNextParentNo2]).each(function() {
3263                                    aHtml.push('<li class="noChild" id="cate'+this.cate_no+'">');
3264                                    var sCateSelected = (checkInArray(sMyCateList, this.cate_no) == true) ? ' selected' : '';
3265                                    aHtml.push('<a href="/product/list.html'+this.param+'" class="view" cate="'+this.param+'" onclick="subMenuEvent(this);" data-i18n="LIST.PRD_CATE_NO_'+this.cate_no+'" data-i18n-new>'+this.name+'</a>');
3266                                    aHtml.push('</li>');
3267                                });
3268                                aHtml.push('</ul>');
3269                            }
3270                            aHtml.push('</li>');
3271                        });
3272                        aHtml.push('</ul>');
3273                    }
3274                    aHtml.push('</li>');
3275                });
3276                aHtml.push('</ul>');
3277            }
3278            $(oParentNode).append(aHtml.join(''));
3279            if (window.i18nextCafe24) {
3280            	i18nextCafe24.translate('data-i18n-new');
3281            }
3282        },
3283        close: function() {
3284            $('.slideSubMenu').remove();
3285        },
3286        checkSub: function() {
3287            $('.cate').each(function(){
3288                var sParam = $(this).attr('cate');
3289                if (!sParam) return;
3290                var iCateNo = Number(methods.getParam(sParam, 'cate_no'));
3291                var result = methods.aSubCategory[iCateNo];
3292                if (result == undefined) {
3293                    if ($(this).closest('#slideProjectList').length) {
3294                        var sHref = '/product/project.html'+sParam;
3295                    } else {
3296                        var sHref = '/product/list.html'+sParam;
3297                    }
3298
3299                    $(this).attr('href', sHref);
3300                    $(this).parent().attr('class', 'noChild');
3301                }
3302            });
3303        }
3304    };
3305
3306    methods.get();
3307
3308    // 하위 카테고리가 없을때 more 버튼 숨김 처리
3309    function fnCateNone01(list){
3310        list.each(function () {
3311            const $li = $(this);
3312            const $link = $li.children('.view').children('a');
3313            
3314            if ($link.length === 0) return;
3315    
3316            const href = $link.attr('href');
3317            let iCateNo = Number(methods.getParam(href, 'cate_no'));
3318    
3319            if (!iCateNo) {
3320                iCateNo = Number(methods.getParamSeo(href));
3321            }
3322    
3323            if (methods.aSubCategory[iCateNo] == undefined && $link.siblings('.sub_cate01').length === 0) {
3324                const $moreBtn = $li.find('.more');
3325                if ($moreBtn.length) {
3326                    $moreBtn.hide();
3327                }
3328            }
3329        });
3330    }
3331    function fnCateNone02(list){
3332        list.each(function () {
3333            const $li = $(this);
3334            const $link = $li.children('.view');
3335    
3336            if ($link.length === 0) return;
3337    
3338            const href = $link.attr('href');
3339            let iCateNo = Number(methods.getParam(href, 'cate_no'));
3340            
3341            
3342            if (!iCateNo) {
3343                iCateNo = Number(methods.getParamSeo(href));
3344            }
3345    
3346            if (methods.aSubCategory[iCateNo] == undefined) {
3347                const $moreBtn = $li.find('.cate');
3348                if ($moreBtn.length) {
3349                    $moreBtn.hide();
3350                }
3351            }
3352        });
3353    }
3354    setTimeout(() => {
3355        fnCateNone01($('#slideCateList #slide_add_category > li'));
3356    }, 500);
3357
3358    $('#slideCateList').on('click', '.sub_cate01 > li > .cate', function(e) {
3359        fnCateNone02($('#slideCateList #slide_add_category .sub_cate02 > li'));
3360    });
3361    $('#slideCateList').on('click', '.sub_cate02 > li > .cate', function(e) {
3362        fnCateNone02($('#slideCateList #slide_add_category .sub_cate03 > li'));
3363    });
3364
3365    $('#slideCateList li .more').on('click', function (e) {
3366        if($('.aside_A')){
3367            const link = $(this).siblings('a')
3368            let iCateNo = Number(methods.getParam(link.attr('href'), 'cate_no'));
3369            
3370            if (!iCateNo) {
3371                iCateNo = Number(methods.getParamSeo(link.attr('href')));
3372            }
3373    
3374            if($(this).closest('li').hasClass('noChild') && !$(this).closest('li').hasClass('xans-record-')){
3375    
3376                if(link.parent().hasClass('selected')) {
3377                    link.parent().removeClass('selected');
3378                } else {
3379                    $('#aside #slideCateList li.selected').removeClass('selected');
3380                    $('#aside #slideCateList .view.selected').removeClass('selected');
3381                    link.parent().addClass('selected');
3382                }
3383            }
3384    
3385            if (!iCateNo) {
3386               return;
3387            }
3388            let hasClass =  link.parent().hasClass('selected');
3389            
3390            if(hasClass) {
3391                methods.close();
3392                link.parent().removeClass('selected');
3393            } else {
3394                $('#aside #slideCateList li.selected').removeClass('selected');
3395                $('#aside #slideCateList .view.selected').removeClass('selected');
3396                link.parent().addClass('selected');
3397                methods.close();
3398                methods.show(this.parentNode, iCateNo);
3399            }
3400            e.preventDefault();
3401        } else if($('.aside_B')){
3402            e.preventDefault();
3403    
3404            const $moreBtn = $(this);
3405            const $link = $moreBtn.siblings('a');
3406            const $li = $link.parent();
3407            const $subCate = $moreBtn.siblings('.sub_cate01');
3408        
3409            let iCateNo = Number(methods.getParam($link.attr('href'), 'cate_no'));
3410            if (!iCateNo) {
3411                iCateNo = Number(methods.getParamSeo($link.attr('href')));
3412            }
3413        
3414            const isSelected = $li.hasClass('selected');
3415        
3416            if (iCateNo) {
3417                if (isSelected) {
3418                    methods.close();
3419                    $li.removeClass('selected');
3420                } else {
3421                    $('#aside #slideCateList li').removeClass('selected');
3422                    $li.addClass('selected');
3423                    methods.close();
3424                    methods.show($li[0], iCateNo);
3425                }
3426            } else if ($subCate.length) {
3427                if (isSelected) {
3428                    $li.removeClass('selected');
3429                } else {
3430                    $('#aside #slideCateList li').removeClass('selected');
3431                    $li.addClass('selected');
3432                }
3433            }
3434        }
3435    });
3436
3437	/* 모바일 슬라이드바 카테고리 중분류체크 */
3438	jQuery('#slide_add_category li').each(function(){
3439		if( jQuery(this).children('ul').length == 0 ){
3440			jQuery(this).addClass('noChild');
3441		} else {
3442			jQuery(this).append('<a href="#none" class="cate">상품보기</a>');
3443		}
3444    });
3445
3446    /* 모바일 슬라이드바 카테고리 */
3447    $('#aside ul a.cate').on('click', function(e){
3448        var sParam = $(this).attr('cate');
3449        if(sParam) return;
3450
3451        $(this).parent().find('li').removeClass('selected');
3452        $('#slideCateList .categoryList li').removeClass('selected');
3453        $(this).parent().toggleClass('selected');
3454
3455        if (!$(this).parent('li').hasClass('noChild')){
3456            e.preventDefault();
3457        }
3458    });
3459
3460	/* 슬라이드 고객센터 토글 */
3461    jQuery('#aside .navigation-menu__board .icoCategory').click(function() {
3462        var target = jQuery(this).parents('#aside .navigation-menu__board');
3463        if(target.find('.categoryList').css("display") == "none"){
3464            target.find('.categoryList').show();
3465        }else{
3466            target.find('.categoryList').hide();
3467        }
3468
3469        jQuery(this).parents('.title').toggleClass('selected');
3470    });
3471
3472    $('#slideCateList h2').on('click', function() {
3473        var oParentId = $(this).parent().attr('id');
3474        if (oParentId == 'slideCateList' || oParentId == 'slideMultishopList' || oParentId == 'slideProjectList') {
3475            ($(this).attr('class') == 'selected') ? $(this).next().hide() : $(this).next().show();
3476        }
3477        $(this).toggleClass('selected');
3478    });
3479
3480    $('#slideProjectList .icoCategory').on('click', function() {
3481        var target = $(this).parents('#slideProjectList');
3482        if(target.find('.categoryList').css("display") == "none"){
3483            target.find('.categoryList').show();
3484        }else{
3485            target.find('.categoryList').hide();
3486        }
3487
3488        $(this).parents('.title').toggleClass('selected');
3489    });
3490
3491});
3492function subMenuEvent(obj) {
3493    $(obj).parent().find('li').removeClass('selected');
3494    $(obj).parent().toggleClass('selected');
3495}
3496
3497function checkInArray(sBookmarkList, iCateNo) {
3498    if (sBookmarkList == null) return false;
3499    var aBookmarkList = sBookmarkList.split("|");
3500    for (var i = 0; i < aBookmarkList.length; i++) {
3501        if (aBookmarkList[i] == iCateNo) {
3502            return true;
3503        }
3504    }
3505    return false;
3506}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.