{"component":{"id":34,"name":"ct_code_block","options":{"ct_id":34,"ct_parent":100002,"selector":"code_block-34-242","original":{"code-js":"function stopAutoplay(container) {\n if (container.__autoInterval) {\n clearInterval(container.__autoInterval);\n container.__autoInterval = null;\n container.__autoplayStopped = true;\n }\n}\n\nfunction addActiveClassesButtons(el) {\n Array.from(el.classList).forEach(cls => {\n if (!cls.startsWith('ct-') && !cls.endsWith('-active')) {\n el.classList.add(cls + '-active');\n }\n });\n}\n\nfunction removeActiveClassesButtons(el) {\n Array.from(el.classList).forEach(cls => {\n if (cls.endsWith('-active')) el.classList.remove(cls);\n });\n}\n\nfunction removeActiveClassesXTabsSi(container) {\n const xtabsSiBlocks = container.querySelectorAll('.x-tabs-si > .ct-div-block');\n xtabsSiBlocks.forEach(el => {\n Array.from(el.classList).forEach(cls => {\n if (cls.endsWith('-active')) {\n el.classList.remove(cls);\n }\n });\n });\n}\n\nfunction initializeTabs(container) {\n const activeAttr = parseInt(container.getAttribute('data-tabs-active'), 10);\n const transitionDuration = container.getAttribute('data-tabs-transition-duration') || '0s';\n const multiple = container.getAttribute('data-tabs-multiple') === 'true';\n const arrowPrevSelector = container.getAttribute('data-tabs-arrow-prev');\n const arrowNextSelector = container.getAttribute('data-tabs-arrow-next');\n const dataTabsArrowsType = container.getAttribute('data-tabs-arrows-type') || 'static';\n const dataTabsArrowsDuration = parseInt(container.getAttribute('data-tabs-arrows-duration'), 10) || 2000;\n\n if (!container.__autoplayStopped && container.__autoInterval) {\n clearInterval(container.__autoInterval);\n container.__autoInterval = null;\n }\n\n let activeIndex = isNaN(activeAttr) ? 0 : activeAttr - 1;\n const contents = Array.from(container.querySelectorAll(':scope > .ct-div-block'));\n if (activeIndex < 0) activeIndex = 0;\n if (activeIndex > contents.length - 1) activeIndex = contents.length - 1;\n\n container.style.position = 'relative';\n\n contents.forEach((el, i) => {\n el.style.position = 'absolute';\n el.style.top = '0';\n el.style.left = '0';\n if (i === activeIndex) {\n Array.from(el.classList).forEach(cls => {\n if (!cls.endsWith('-active')) {\n el.classList.add(`${cls}-active`);\n }\n });\n el.style.transition = `all ${transitionDuration} ease ${transitionDuration}`;\n el.style.visibility = 'visible';\n el.style.opacity = '1';\n el.style.position = 'relative';\n } else {\n Array.from(el.classList).forEach(cls => {\n if (cls.endsWith('-active')) {\n el.classList.remove(cls);\n }\n });\n el.style.transition = `all ${transitionDuration} ease 0s`;\n el.style.visibility = 'hidden';\n el.style.opacity = '0';\n el.style.position = 'absolute';\n }\n });\n\n const selectorAttr = container.getAttribute('data-tabs-selector');\n const selectors = selectorAttr ? selectorAttr.split(',').map(x => x.trim()) : ['next', 'prev'];\n\n const getTabsButtons = s => {\n if (s.toLowerCase() === ' ') {\n return [];\n } else if (s.toLowerCase() === 'both') {\n const p = container.previousElementSibling?.classList.contains('x-tabs-buttons') ? container.previousElementSibling : null;\n const n = container.nextElementSibling?.classList.contains('x-tabs-buttons') ? container.nextElementSibling : null;\n return [p, n].filter(el => el);\n } else if (s.toLowerCase() === 'next') {\n return container.nextElementSibling?.classList.contains('x-tabs-buttons') ? [container.nextElementSibling] : [];\n } else if (s.toLowerCase() === 'prev') {\n return container.previousElementSibling?.classList.contains('x-tabs-buttons') ? [container.previousElementSibling] : [];\n } else {\n return Array.from(document.querySelectorAll(s)).filter(el => el.classList.contains('x-tabs-buttons'));\n }\n };\n\n const allTabsButtons = selectors.flatMap(getTabsButtons);\n\n allTabsButtons.forEach(tb => {\n Array.from(tb.querySelectorAll('.ct-div-block')).forEach(btn => {\n btn.style.cursor = 'pointer';\n });\n });\n\n const allButtons = multiple\n ? allTabsButtons.flatMap(tb => Array.from(tb.querySelectorAll('.ct-div-block')))\n : allTabsButtons[0]\n ? Array.from(allTabsButtons[0].querySelectorAll('.ct-div-block'))\n : [];\n\n if (allButtons.length) {\n allTabsButtons.forEach(tb => {\n const btns = Array.from(tb.querySelectorAll('.ct-div-block'));\n btns.forEach((btn, i) => {\n const globalIndex = multiple ? allButtons.indexOf(btn) : i;\n if (globalIndex === activeIndex) {\n addActiveClassesButtons(btn);\n btn.style.transition = `all ${transitionDuration}`;\n btn.querySelectorAll('*').forEach(child => {\n addActiveClassesButtons(child);\n });\n } else {\n removeActiveClassesButtons(btn);\n btn.style.transition = '0s';\n btn.querySelectorAll('*').forEach(child => {\n removeActiveClassesButtons(child);\n });\n }\n });\n });\n }\n\n removeActiveClassesXTabsSi(container);\n\n const moveTo = i => {\n container.setAttribute('data-tabs-active', i + 1);\n initializeTabs(container);\n };\n\n const moveNext = () => {\n const current = parseInt(container.getAttribute('data-tabs-active'), 10) - 1;\n let newIndex = isNaN(current) ? 0 : current;\n newIndex++;\n if (dataTabsArrowsType === 'infinite' || dataTabsArrowsType === 'autoplay') {\n if (newIndex > contents.length - 1) newIndex = 0;\n } else {\n if (newIndex > contents.length - 1) newIndex = contents.length - 1;\n }\n moveTo(newIndex);\n };\n\n const movePrev = () => {\n const current = parseInt(container.getAttribute('data-tabs-active'), 10) - 1;\n let newIndex = isNaN(current) ? 0 : current;\n newIndex--;\n if (dataTabsArrowsType === 'infinite' || dataTabsArrowsType === 'autoplay') {\n if (newIndex < 0) newIndex = contents.length - 1;\n } else {\n if (newIndex < 0) newIndex = 0;\n }\n moveTo(newIndex);\n };\n\n const updateArrows = i => {\n if (dataTabsArrowsType === 'static') {\n if (arrowPrevSelector) {\n const prevArrow = document.querySelector(arrowPrevSelector);\n if (prevArrow) {\n prevArrow.style.opacity = i === 0 ? '0.5' : '1';\n }\n }\n if (arrowNextSelector) {\n const nextArrow = document.querySelector(arrowNextSelector);\n if (nextArrow) {\n nextArrow.style.opacity = i === contents.length - 1 ? '0.5' : '1';\n }\n }\n }\n };\n\n updateArrows(activeIndex);\n\n if (arrowPrevSelector) {\n const prevArrow = document.querySelector(arrowPrevSelector);\n if (prevArrow) {\n prevArrow.style.cursor = 'pointer';\n prevArrow.onclick = () => {\n stopAutoplay(container);\n movePrev();\n };\n }\n }\n\n if (arrowNextSelector) {\n const nextArrow = document.querySelector(arrowNextSelector);\n if (nextArrow) {\n nextArrow.style.cursor = 'pointer';\n nextArrow.onclick = () => {\n stopAutoplay(container);\n moveNext();\n };\n }\n }\n\n if (dataTabsArrowsType === 'autoplay' && !container.__autoplayStopped) {\n container.__autoInterval = setInterval(() => {\n moveNext();\n }, dataTabsArrowsDuration);\n }\n\n if (container.getAttribute('data-tabs-sticky-mobile') === 'true' && window.innerWidth <= 768) {\n if (container.__isInitialized) {\n const topAttr = container.getAttribute('data-tabs-sticky-mobile-top');\n let offset = 0;\n if (topAttr.endsWith('px')) {\n offset = parseFloat(topAttr);\n } else if (topAttr.endsWith('%')) {\n offset = window.innerHeight * (parseFloat(topAttr) / 100);\n } else if (topAttr.endsWith('vh')) {\n offset = window.innerHeight * (parseFloat(topAttr) / 100);\n }\n const rect = container.getBoundingClientRect();\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n window.scrollTo({ top: rect.top + scrollTop - offset, behavior: 'smooth' });\n } else {\n container.__isInitialized = true;\n }\n }\n}\n\ndocument.addEventListener('click', e => {\n const ctBlock = e.target.closest('.ct-div-block');\n if (!ctBlock) return;\n const tabsButtons = ctBlock.closest('.x-tabs-buttons');\n if (!tabsButtons) return;\n\n const allContents = Array.from(tabsButtons.parentElement.querySelectorAll('.x-tabs-contents'));\n const associated = allContents.filter(c => {\n const sel = c.getAttribute('data-tabs-selector');\n if (!sel) return false;\n const arr = sel.split(',').map(x => x.trim());\n return arr.some(x => {\n if (x.toLowerCase() === ' ') return false;\n if (x.toLowerCase() === 'both') {\n return c.previousElementSibling === tabsButtons || c.nextElementSibling === tabsButtons;\n } else if (x.toLowerCase() === 'next') {\n return c.nextElementSibling === tabsButtons;\n } else if (x.toLowerCase() === 'prev') {\n return c.previousElementSibling === tabsButtons;\n } else {\n return Array.from(document.querySelectorAll(x)).includes(tabsButtons);\n }\n });\n });\n if (!associated.length) return;\n\n associated.forEach(cont => {\n stopAutoplay(cont);\n const multiple = cont.getAttribute('data-tabs-multiple') === 'true';\n const sel = cont.getAttribute('data-tabs-selector');\n const arr = sel ? sel.split(',').map(x => x.trim()) : ['next', 'prev'];\n\n const getTabsButtons = x => {\n if (x.toLowerCase() === ' ') return [];\n if (x.toLowerCase() === 'both') {\n const p = cont.previousElementSibling?.classList.contains('x-tabs-buttons') ? cont.previousElementSibling : null;\n const n = cont.nextElementSibling?.classList.contains('x-tabs-buttons') ? cont.nextElementSibling : null;\n return [p, n].filter(el => el);\n } else if (x.toLowerCase() === 'next') {\n return cont.nextElementSibling?.classList.contains('x-tabs-buttons') ? [cont.nextElementSibling] : [];\n } else if (x.toLowerCase() === 'prev') {\n return cont.previousElementSibling?.classList.contains('x-tabs-buttons') ? [cont.previousElementSibling] : [];\n } else {\n return Array.from(document.querySelectorAll(x)).filter(el => el.classList.contains('x-tabs-buttons'));\n }\n };\n\n const tabsBtns = arr.flatMap(getTabsButtons);\n const relBtns = tabsBtns.filter(tb => tb.contains(tabsButtons));\n if (!relBtns.length) return;\n\n const allButtons = multiple\n ? tabsBtns.flatMap(tb => Array.from(tb.querySelectorAll('.ct-div-block')))\n : tabsBtns[0]\n ? Array.from(tabsBtns[0].querySelectorAll('.ct-div-block'))\n : [];\n\n allButtons.forEach(btn => {\n btn.style.cursor = 'pointer';\n });\n\n const clickedIndex = multiple\n ? allButtons.indexOf(ctBlock)\n : Array.from(tabsButtons.querySelectorAll('.ct-div-block')).indexOf(ctBlock);\n\n if (clickedIndex === -1) return;\n\n cont.setAttribute('data-tabs-active', clickedIndex + 1);\n initializeTabs(cont);\n });\n});\n\ndocument.querySelectorAll('.x-tabs-contents').forEach(c => {\n initializeTabs(c);\n});\n","code-css":"","code-php":""},"nicename":"JS Tabs Global","activeselector":false},"depth":2},"classes":{}}