//<script type="text/javascript">
if (top != self) {
	top.location.href = location.href;
}

var SITEROOT = '/';

// 2019-08 Compat fix: c.curCSS is not a function
jQuery.curCSS = function(element, prop, val) {
    return jQuery(element).css(prop, val);
};

function MM_preloadImages() { //v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
	var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
	if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}

function MM_swapImgRestore() { //v3.0
  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}

function MM_findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
	d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}

function MM_swapImage() { //v3.0
  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}

$.urlParam = function(name, queryString){
	var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(queryString || window.location.href);
	if (!results) { return 0; }
	return results[1] || 0;
}

function initZoomDatasheet(closeMessage) {
    // return;
	$(".zoom").fancybox({
        arrows: true,
        // Close window if user clicks outside the image
        hideOnOverlayClick: false,
        wheel: true,
        axis: 'x',
        buttons: ['close'],
        btnTpl: {
            close: '<button style="width: 64px; height: 64px" data-fancybox-close class="fancybox-button fancybox-button--close" title="{{CLOSE}}">' +
                '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 10.6L6.6 5.2 5.2 6.6l5.4 5.4-5.4 5.4 1.4 1.4 5.4-5.4 5.4 5.4 1.4-1.4-5.4-5.4 5.4-5.4-1.4-1.4-5.4 5.4z"/></svg>' +
                "</button>"
        }
    });
    /*
    $(".zoom").fancybox({
		'showCloseButton'	: false,
		'changeSpeed'		: 50,
		'padding'			: 0,
		'titlePosition' 	: 'inside',
		'titleFormat'		: function (title, currentArray, currentIndex, currentOpts) {
			return '<div id="zoom-title"><span>' +
				'<a href="javascript:$.fancybox.close();"><img src="/images/icons_2011/popup_close.png" /></a></span>' +
				(
					currentArray.length > 1
					? (
						(currentIndex > 0 ? '<a class="noho arrow-left" href="javascript:$.fancybox.prev();"><img src="/images/icons_2011/popup_left.png" border="0" /></a> ' : '') +
						(title && title.length ? '<b>' + title + '</b>' : '' ) + (currentIndex + 1) + ' / ' + currentArray.length) +
						(currentIndex < (currentArray.length - 1) ? ' <a class="noho arrow-right" href="javascript:$.fancybox.next();"><img src="/images/icons_2011/popup_right.png" border="0" /></a>' : '')
					: (
						'<div><a class="small" href="javascript:$.fancybox.close();">'+closeMessage+'</a></div>'
					)
				) +
				'</div>';
	    },
	});
    */
}

function initZoomModal() {
	$(".zoom").fancybox({
		arrows              : true,
		wheel               : true,
        axis                : 'x',
        buttons             : ['close']
	});
}







// ChatGPT-4 upgraded touch handler, 2023-10

// Track current dropdown and state
// Track current dropdown and state
var currentDropDown = null;
var dropdownJustOpened = false;
var animationDuration = 200;

// Helper function to calculate submenu position
function calculateSubmenuPosition(submenu, parentItem) {
    var viewportWidth = window.innerWidth;

    submenu.css({
        'left': '',
        'right': ''
    });

    var parentRect = parentItem[0].getBoundingClientRect();
    var submenuRect = submenu[0].getBoundingClientRect();

    if (submenuRect.right > viewportWidth) {
        submenu.css({
            'left': 'auto',
            'right': '0'
        });
    }
}

function setDropDown(submenu, control, visible) {
    var parentItem = control.closest('.menu-item');

    if (visible) {
        if (currentDropDown) {
            currentDropDown.submenu.hide();
            currentDropDown.parent.removeClass('vhover');
            currentDropDown.control.removeClass('open');
        }

        parentItem.addClass('vhover');
        control.addClass('open');
        submenu.show();

        calculateSubmenuPosition(submenu, parentItem);

        currentDropDown = {
            submenu: submenu,
            parent: parentItem,
            control: control
        };

        dropdownJustOpened = true;
        setTimeout(() => dropdownJustOpened = false, 100);
    } else if (currentDropDown && currentDropDown.submenu.is(submenu)) {
        submenu.hide();
        parentItem.removeClass('vhover');
        control.removeClass('open');
        currentDropDown = null;
    }
}

function initDropDown(submenuSelector, controlSelector) {
    const submenu = $(submenuSelector);
    const control = $(controlSelector);
    const menuItem = control.closest('.menu-item');

    if (!submenu.length) return;

    const handleOpen = function(event) {
        if (event.type === 'touchstart' && $(event.target).closest(controlSelector).length) {
            event.preventDefault();
            event.stopPropagation();

            if (currentDropDown && currentDropDown.submenu.is(submenu)) {
                setDropDown(submenu, control, false);
                return;
            }
        }

        setDropDown(submenu, control, true);
    };

    const handleClose = function(event) {
        // Get the related target (element being moved to)
        const relatedTarget = $(event.relatedTarget);

        // Check if we're moving between the menu item and its submenu
        const isMovingWithinMenu =
            menuItem.has(relatedTarget).length ||
            submenu.has(relatedTarget).length ||
            menuItem.is(relatedTarget) ||
            submenu.is(relatedTarget);

        if (!isMovingWithinMenu) {
            setDropDown(submenu, control, false);
        }
    };

    // Clean up existing events
    menuItem.off('mouseenter mouseleave');
    submenu.off('mouseenter mouseleave');
    control.off('touchstart');

    // Bind mouse events to both menu item and submenu
    menuItem.on('mouseenter', handleOpen);
    menuItem.on('mouseleave', handleClose);
    submenu.on('mouseenter', handleOpen);
    submenu.on('mouseleave', handleClose);

    // Bind touch events to control only
    control.on('touchstart', handleOpen);

    // Handle clicks outside
    $(document).off('touchstart.dropdown click.dropdown')
        .on('touchstart.dropdown click.dropdown', function(event) {
            if ($(event.target).closest('.submenu-item a').length) {
                return;
            }

            if (!dropdownJustOpened &&
                currentDropDown &&
                !menuItem.is(event.target) &&
                !submenu.is(event.target) &&
                menuItem.has(event.target).length === 0 &&
                submenu.has(event.target).length === 0) {
                setDropDown(currentDropDown.submenu, currentDropDown.control, false);
            }
        });

    // Handle window resize
    $(window).off('resize.dropdown')
        .on('resize.dropdown', function() {
            if (currentDropDown) {
                calculateSubmenuPosition(currentDropDown.submenu, currentDropDown.parent);
            }
        });
}




function forceFancyLoader() {
	setTimeout(
		function() {
			try {
				$.fancybox.init();
				$.fancybox.showActivity();
			}
			catch (e) {
			}
		},
		200
	);
}

function setThumbPager(mode) {
    if (mode === null)
        buttons = [' ', ' '];
    else if (mode === -1)
        buttons = [' ', '&#xBB;'];
    else if (mode === 1)
        buttons = ['&#xAB;', ' '];
    else
        buttons = ['&#xAB;', '&#xBB;'];
    $("#go_prev").html(buttons[0]);
    $("#go_next").html(buttons[1]);
}


function forceFancyOverlay() {
	try {
		var overlay	= $('#fancybox-overlay');

		var isIE6 = !$.support.opacity && !window.XMLHttpRequest;
		if (isIE6) {
			$('select:not(#fancybox-tmp select)').filter(function() {
				return this.style.visibility !== 'hidden';
			}).css({'visibility':'hidden'}).one('fancybox-cleanup', function() {
				this.style.visibility = 'inherit';
			});
		}
		overlay.css({
			'background-color'	: '#000',
			'opacity'			: '0.6',
	        'height'			: '100%'
	    }).unbind().show();

		forceFancyLoader();
	}
	catch (e) {
	}
}

/* Fancybox swipe retrofit */
let touchStartX = null;

// Define your swipe handler function
function handleSwipe(touchEndX) {
    if (touchStartX && touchEndX) {
        if (touchEndX < touchStartX) {
            $.fancybox.next();
        } else {
            $.fancybox.prev();
        }
    }
    touchStartX = null;
}

// Function to add event listeners to an element
function addEventListeners(element) {
    element.addEventListener('touchstart', function(event) {
        touchStartX = event.changedTouches[0].clientX;
    }, false);

    element.addEventListener('touchend', function(event) {
        handleSwipe(event.changedTouches[0].clientX);
    }, false);
}

// Set up a MutationObserver to watch for changes to the body of the document
let observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        // If the addedNodes property has one or more nodes
        if (mutation.addedNodes.length) {
            let fancyBoxElements = document.querySelectorAll('#fancybox-content, #fancybox-right, #fancybox-left');
            fancyBoxElements.forEach(function(element) {
                addEventListeners(element);
            });

            // Once the event listeners are added, we can stop observing
            if (fancyBoxElements.length > 0) {
                observer.disconnect();
            }
        }
    });
});


// onload
// Start observing the document with the configured parameters
$(function() {
    // Start observing the document with the configured parameters
    observer.observe(document.body, { childList: true, subtree: true });
});



/*
$(function() {
	$('#image_rotate').innerfade(
		{ speed: 'slow', timeout: 5000, type: 'sequence', containerheight: '237px' }
	);
});
*/

$(window).load(function(){
	if (typeof jQuery.fn.bxSlider != 'undefined') {
		$('#image_rotate').bxSlider({
			speed: 1500,
			pause: 4500,
			mode: 'fade',
			auto: true,
			nextText : '',
			prevText : ''
		});
	}
});


/*****************************************************************************
jQuery Placeholder 1.1.1

Copyright (c) 2010 Michael J. Ryan (http://tracker1.info/)

Dual licensed under the MIT and GPL licenses:
	http://www.opensource.org/licenses/mit-license.php
	http://www.gnu.org/licenses/gpl.html

------------------------------------------------------------------------------

Sets up a watermark for inputted fields... this will create a LABEL.watermark 
tag immediately following the input tag, the positioning will be set absolute, 
and it will be positioned to match the input tag.

To activate on all tags with a 'data-watermark' attribute:

	$('input[placeholder],textarea[placeholder]').placeholder();


To style the tags as appropriate (you'll want to make sure the font matches):

	label.placeholder {
		cursor: text;				<--- display a cursor to match the text input

		padding: 4px 4px 4px 4px;   <--- this should match the border+padding 
											for the input field(s)
		color: #999999;				<--- this will display as faded
	}

You'll also want to have the color set for browsers with native support
	input:placeholder, textarea:placeholder {
		color: #999999;
	}
	input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
		color: #999999;
	}

------------------------------------------------------------------------------

Thanks to...
	http://www.alistapart.com/articles/makingcompactformsmoreaccessible
	http://plugins.jquery.com/project/overlabel

	This works similar to the overlabel, but creates the actual label tag
	based on a data-watermark attribute on the input tag, instead of 
	relying on the markup to provide it.

*****************************************************************************/
(function($){
	
	var ph = "PLACEHOLDER-INPUT";
	var phl = "PLACEHOLDER-LABEL";
	var boundEvents = false;
	var default_options = {
		labelClass: 'placeholder'
	};
	
	//check for native support for placeholder attribute, if so stub methods and return
	var input = document.createElement("input");
	if ('placeholder' in input) {
		$.fn.placeholder = $.fn.unplaceholder = function(){}; //empty function
		delete input; //cleanup IE memory
		return;
	};
	delete input;

	$.fn.placeholder = function(options) {
		bindEvents();

		var opts = $.extend(default_options, options)

		this.each(function(){
			var rnd=Math.random().toString(32).replace(/\./,'')
				,input=$(this)
				,label=$('<label style="position:absolute;display:none;top:0;left:0;"></label>');

			if (!input.attr('placeholder') || input.data(ph) === ph) return; //already watermarked

			//make sure the input tag has an ID assigned, if not, assign one.
			if (!input.attr('id')) { input.attr('id', 'input_' + rnd); }

			label	.attr('id',input.attr('id') + "_placeholder")
					.data(ph, '#' + input.attr('id'))	//reference to the input tag
					.attr('for',input.attr('id'))
					.addClass(opts.labelClass)
					.addClass(opts.labelClass + '-for-' + this.tagName.toLowerCase()) //ex: watermark-for-textarea
					.addClass(phl)
					.text(input.attr('placeholder'));

			input
				.data(phl, '#' + label.attr('id'))	//set a reference to the label
				.data(ph,ph)		//set that the field is watermarked
				.addClass(ph)		//add the watermark class
				.after(label);		//add the label field to the page

			//setup overlay
			itemIn.call(this);
			itemOut.call(this);
		});
	};

	$.fn.unplaceholder = function(){
		this.each(function(){
			var	input=$(this),
				label=$(input.data(phl));

			if (input.data(ph) !== ph) return;
				
			label.remove();
			input.removeData(ph).removeData(phl).removeClass(ph);
		});
	};


	function bindEvents() {
		if (boundEvents) return;

		//prepare live bindings if not already done.
		$('.' + ph)
			.live('click',itemIn)
			.live('focusin',itemIn)
			.live('focusout',itemOut);
		bound = true;

		boundEvents = true;
	};

	function itemIn() {
		var input = $(this)
			,label = $(input.data(phl));

		label.css('display', 'none');
	};

	function itemOut() {
		var that = this;

		//use timeout to let other validators/formatters directly bound to blur/focusout work first
		setTimeout(function(){
			var input = $(that);
			$(input.data(phl))
				.css('top', (input.position().top + parseInt(input.css('padding-top'))) + 'px')
				.css('left', (input.position().left + parseInt(input.css('padding-left'))) + 'px')
				.css('display', !!input.val() ? 'none' : 'block');
		}, 200);
	};

}(jQuery));
/* =========================================================

// jquery.innerfade.js

// Datum: 2008-02-14
// Firma: Medienfreunde Hofmann & Baldes GbR
// Author: Torsten Baldes
// Mail: t.baldes@medienfreunde.com
// Web: http://medienfreunde.com

// based on the work of Matt Oakes http://portfolio.gizone.co.uk/applications/slideshow/
// and Ralf S. Engelschall http://trainofthoughts.org/

 *
 *  <ul id="news"> 
 *      <li>content 1</li>
 *      <li>content 2</li>
 *      <li>content 3</li>
 *  </ul>
 *  
 *  $('#news').innerfade({ 
 *	  animationtype: Type of animation 'fade' or 'slide' (Default: 'fade'), 
 *	  speed: Fading-/Sliding-Speed in milliseconds or keywords (slow, normal or fast) (Default: 'normal'), 
 *	  timeout: Time between the fades in milliseconds (Default: '2000'), 
 *	  type: Type of slideshow: 'sequence', 'random' or 'random_start' (Default: 'sequence'), 
 * 		containerheight: Height of the containing element in any css-height-value (Default: 'auto'),
 *	  runningclass: CSS-Class which the container get’s applied (Default: 'innerfade'),
 *	  children: optional children selector (Default: null)
 *  }); 
 *

// ========================================================= */


(function($) {

    $.fn.innerfade = function(options) {
        return this.each(function() {   
            $.innerfade(this, options);
        });
    };

    $.innerfade = function(container, options) {
        var settings = {
        		'animationtype':    'fade',
            'speed':            'normal',
            'type':             'sequence',
            'timeout':          2000,
            'containerheight':  'auto',
            'runningclass':     'innerfade',
            'children':         null
        };
        if (options)
            $.extend(settings, options);
        if (settings.children === null)
            var elements = $(container).children();
        else
            var elements = $(container).children(settings.children);
        if (elements.length > 1) {
            $(container).css('position', 'relative').css('height', settings.containerheight).addClass(settings.runningclass);
            for (var i = 0; i < elements.length; i++) {
                $(elements[i]).css('z-index', String(elements.length-i)).css('position', 'absolute').hide();
            };
            if (settings.type == "sequence") {
                setTimeout(function() {
                    $.innerfade.next(elements, settings, 1, 0);
                }, settings.timeout);
                $(elements[0]).show();
            } else if (settings.type == "random") {
            		var last = Math.floor ( Math.random () * ( elements.length ) );
                setTimeout(function() {
                    do { 
												current = Math.floor ( Math.random ( ) * ( elements.length ) );
										} while (last == current );             
										$.innerfade.next(elements, settings, current, last);
                }, settings.timeout);
                $(elements[last]).show();
						} else if ( settings.type == 'random_start' ) {
								settings.type = 'sequence';
								var current = Math.floor ( Math.random () * ( elements.length ) );
								setTimeout(function(){
									$.innerfade.next(elements, settings, (current + 1) %  elements.length, current);
								}, settings.timeout);
								$(elements[current]).show();
						}	else {
							alert('Innerfade-Type must either be \'sequence\', \'random\' or \'random_start\'');
						}
				}
    };

    $.innerfade.next = function(elements, settings, current, last) {
        if (settings.animationtype == 'slide') {
            $(elements[last]).slideUp(settings.speed);
            $(elements[current]).slideDown(settings.speed);
        } else if (settings.animationtype == 'fade') {
            $(elements[last]).fadeOut(settings.speed);
            $(elements[current]).fadeIn(settings.speed, function() {
							removeFilter($(this)[0]);
						});
        } else
            alert('Innerfade-animationtype must either be \'slide\' or \'fade\'');
        if (settings.type == "sequence") {
            if ((current + 1) < elements.length) {
                current = current + 1;
                last = current - 1;
            } else {
                current = 0;
                last = elements.length - 1;
            }
        } else if (settings.type == "random") {
            last = current;
            while (current == last)
                current = Math.floor(Math.random() * elements.length);
        } else
            alert('Innerfade-Type must either be \'sequence\', \'random\' or \'random_start\'');
        setTimeout((function() {
            $.innerfade.next(elements, settings, current, last);
        }), settings.timeout);
    };

})(jQuery);

// **** remove Opacity-Filter in ie ****
function removeFilter(element) {
	if(element.style.removeAttribute){
		element.style.removeAttribute('filter');
	}
}

var player = new Audio();

function thisMovie(movieName){
	return document.getElementById(movieName);
}

var radioText;
var playing = '';
var currentItem;
var audioInit = function() {};

function audioPlayerInit(controlid, fileuri) {return true;}

function getUpdate(typ,pr1,pr2,pid) {
	if(typ == "item") { currentItem = pr1; setTimeout("getItemData(currentItem)",100); }
};

function getItemData(idx) {

	var obj = thisMovie("mediaplayer_flash").itemData(idx);
	if (obj.description && playing)
		newCaptionHtml = '<marquee id="rmq" scrollamount="2" behavior="scroll" loop="infinite">' + obj.description + '</marquee>';
	else
		newCaptionHtml = radioText;
	$("#player_caption").html(newCaptionHtml);
};


function playAudio(fileuri) {
	if (playing == fileuri) {
		player.pause();
		playing = '';
	} else {
		player.src = fileuri;
		player.play();
		playing = fileuri;
	}
}

function audioPlayStop(fileuri, anchor) {
	$('.audioplayer img').attr('src', SITEROOT + 'images/icons_2011/ico_sound.png');
	if (playing == fileuri) {
		player.pause();
		$('#player_caption').html(radioText);
		playing = '';
	}
	else {
		player.src = fileuri;
		if (anchor) {
			$(anchor).parents('.audioplayer').find('img:first').attr('src',
              SITEROOT + 'images/icons_2011/ico_sound_playing.png');
		}
		playing = fileuri;
        // player.load();
		player.play();
	}
	return false;
};


function openEmbRadio() {
	window.open( '/radio', 'EMBRadio', 'width=360,height=115,resizable=no,scrollbars=no,status=no');
	return false;
}
// IE11 polyfill for forEach
if (window.NodeList && !NodeList.prototype.forEach) {
    NodeList.prototype.forEach = Array.prototype.forEach;
}





function validateCartInput(inputElement) {
    // Get the data-min-order attribute value
    const minOrderAttribute = inputElement.getAttribute('data-min-order');
    console.log('mino', minOrderAttribute);

    // Check if the data-min-order attribute is present
    if (minOrderAttribute !== null) {
        const minOrder = parseInt(minOrderAttribute, 10);

        // Get the current value of the input
        const currentValue = parseInt(inputElement.value, 10);

        // Check if the current value is less than the minimum allowed value
        if (currentValue < minOrder) {
            // Set the input value to the minimum allowed value
            inputElement.value = minOrder;
            // Log order count mismatch
            console.log('Cart item count has to be greater than ' + minOrder);
        }
    }
    // If the data-min-order attribute is missing, no action is taken.
}


/*
Size based classes, 2023-10, with ChatGPT 4

Using jQuery that applies the specified classes to an element based on the size of its target element:

<!-- Applies class based on its own size -->
<div class="enable-sbc" sbc-if-size-lte="500" sbc-class="small-size">This content will get the "small-size" class if its width is 500px or less</div>

<!-- Applies class based on another element's size -->
<div class="enable-sbc" sbc-target=".targetElements" sbc-if-size-gte="200" sbc-class="big-size">This content will get the "big-size" class if any of the .targetElements width is 200px or more</div>

<div class="targetElements">Target Element 1</div>
<div class="targetElements">Target Element 2</div>
*/

function getMaxWidthOfElements($elements) {
    let maxWidth = 0;
    $elements.each(function () {
        maxWidth = Math.max(maxWidth, $(this).outerWidth());
    });
    return maxWidth;
}

function applySizeBasedClasses() {
    $('.enable-sbc').each(function () {
        const $element = $(this);
        let $targetElements = $element;

        // If sbc-target attribute is set, use those elements for size checks
        const targetSelector = $element.attr('sbc-target');
        if (targetSelector) {
            $targetElements = $(targetSelector);
        }

        const width = getMaxWidthOfElements($targetElements);
        const sbcClass = $element.attr('sbc-class');

        const sizeLte = parseInt($element.attr('sbc-if-size-lte'), 10);
        const sizeGte = parseInt($element.attr('sbc-if-size-gte'), 10);

        if (sizeLte && width <= sizeLte) {
            $element.addClass(sbcClass);
        } else if (sizeGte && width >= sizeGte) {
            $element.addClass(sbcClass);
        } else {
            $element.removeClass(sbcClass);
        }
    });
}

$(function () {
    // Initial application
    applySizeBasedClasses();

    // Listen for window resize to re-check and apply
    $(window).on('resize', applySizeBasedClasses);
});



// Logout form link handler, created in BoxSiteMenu
document.addEventListener("DOMContentLoaded", function(event) {
    items = document.querySelector("a[href='#logout-link']");
    if (items) {
        items.addEventListener("click", function (event) {
            event.preventDefault(); // Prevent the default behavior of the anchor link
            document.forms.logout.submit(); // Submit the form
        });
    }
});
// Fix large square images if URL fails
function zeroImages($parent) {
    // jQuery: all img tags under parent
    $images = $parent.find('img');

    // console.log('Zeroing ' + $images.length + ' images');
    $images.on('error', function () {
        $(this).css({
            'width': '0px',
            'height': '0px'
        });
    });
    $images.each(function () {
        if (this.complete && this.naturalWidth === 0 && this.naturalHeight === 0) {
            $(this).css({
                'width': '0px',
                'height': '0px'
            });
        }
    });
}

// bxSlider to responsive slider compatibility layer
function convertLegacySlider($oldSlider) {
    // Create new parent element
    var $sliderContainer = $('<div>').addClass('slider-container');

    // Create new ul with required attributes and classes
    var $newUl = $('<ul>').addClass('image-rotate').attr({
        'data-speed': '1000',
        'data-pause': '4500',
        'data-auto': 'true'
    });

    // For each li in the old ul
    $oldSlider.find('li').each(function () {
        // Create new li
        var $newLi = $('<li>');

        // Get old <a> and <img>
        var $oldA = $(this).find('a');
        var $oldImg = $oldA.find('img');
        // If <a> tag is missing, try to find <img> tag
        if ($oldImg.length === 0) {
            $oldImg = $(this).find('img');
        }

        // If <a> tag is missing, create a new one with a default href
        if ($oldA.length === 0) {
            $oldA = $('<a>').attr('href', '#');
        }

        // If <img> tag is missing, create a new one with a default src
        if ($oldImg.length === 0) {
            const emptySvg = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='900' height='200'%3E%3Ctext x='50%25' y='50%25' font-size='35' text-anchor='middle' fill='black'%3Eempty%3C/text%3E%3C/svg%3E";
            $oldImg = $('<img>').attr('src', emptySvg);
        }

        // Create new a with href of old a and new img with src of old img
        var $newA = $('<a>').attr('href', $oldA.attr('href'));
        var $newImg = $('<img>').attr('src', $oldImg.attr('src'));

        // console.log('carousel image: ' + $newImg.attr('src') + ' link: ' + $newA.attr('href'));

        // Append new img to new a and new a to new li
        $newA.append($newImg);
        $newLi.append($newA);

        // Append new li to new ul
        $newUl.append($newLi);
    });

    // Create and append fixed .slider-buttons block
    var $sliderButtons = $('<div>').addClass('slider-buttons');
    $sliderButtons.append($('<button>').addClass('prev').html('❮'));
    $sliderButtons.append($('<button>').addClass('next').html('❯'));

    // Append new ul and slider buttons to slider container
    $sliderContainer.append($newUl);
    $sliderContainer.append($sliderButtons);

    // console.log('slider container HTML: ' + $sliderContainer.html());

    // Replace old slider with new slider container
    $oldSlider.replaceWith($sliderContainer);
}

function removeWhitespaceNodes(element) {
    for (var i = 0; i < element.childNodes.length; i++) {
        var node = element.childNodes[i];

        if (node.nodeType === 3 && !/\S/.test(node.nodeValue)) {
            element.removeChild(node);
            i--;
        } else if (node.nodeType === 1) {
            removeWhitespaceNodes(node);
        }
    }
}


$(document).ready(function () {
    function initializeSlider($slider) {
        // Remove whitespace nodes
        for (var i = 0; i < $slider.length; i++) {
            removeWhitespaceNodes($slider[i].parentNode);
        }

        let mode = $slider.attr('data-mode');
        let speed = parseInt($slider.attr('data-speed')) || 1500;
        let pause = parseInt($slider.attr('data-pause')) || 4500;
        let auto = $slider.attr('data-auto') === 'true';

        let index = 0;
        let images = $slider.find('li');

        // If image count <= 1, don't initialize slider
        if (images.length <= 1) {
            // Remove buttons
            $slider.next('.slider-buttons').remove();
            return;
        }

        // Clone the first image and append to container,
        // so lists with only 2 images can still be animated
        let $cloneImage = $slider.find('li:first-child').clone();
        $cloneImage.addClass('clone').appendTo($slider);

        // Set first image active now
        // images.eq(index).addClass('active').css('opacity', 1);

        function showSlide() {
            // Fade out the currently active image
            images.filter('.active').stop().animate({opacity: 0}, speed, function () {
                $(this).removeClass('active');
            });

            // Fade in the next image
            images.eq(index).addClass('active').stop().animate({opacity: 1}, speed);
        }


        function nextSlide() {
            index = (index + 1) % images.length;
            showSlide();
        }

        function prevSlide() {
            index = (index - 1 + images.length) % images.length;
            showSlide();
        }

        let interval = setInterval(nextSlide, pause + speed);

        if (auto) {
            $slider.on('mouseover', function () {
                clearInterval(interval);
            });

            $slider.on('mouseout', function () {
                interval = setInterval(nextSlide, pause + speed);
            });
        }

        $slider.next('.slider-buttons').find('.next').on('click', function () {
            clearInterval(interval);
            nextSlide();
        });

        $slider.next('.slider-buttons').find('.prev').on('click', function () {
            clearInterval(interval);
            prevSlide();
        });

        showSlide();
    }

    $('.image-rotate').each(function () {
        zeroImages($('.image-rotate'));
        initializeSlider($(this));

        // Repeat after 100 msec
        setTimeout(function () {
            zeroImages($('.image-rotate'));
        }, 100);
    });
    $('#image_rotate').each(function () {
        $parent = $(this).parent();
        zeroImages($parent.find('#image_rotate'));
        convertLegacySlider($(this));

        initializeSlider($parent.find('.image-rotate'));
        // Repeat after 100 msec
        setTimeout(function () {
           zeroImages($parent.find('.image-rotate'));
        }, 100);
    });
});
document.addEventListener('DOMContentLoaded', function() {
    const scrollableContainers = document.querySelectorAll('.scroll-container');

    scrollableContainers.forEach(scrollableContainer => {
        const itemsContainer = scrollableContainer.querySelector('.scroll-content');
        const leftButton = scrollableContainer.querySelector('.scroll-button.scroll-left');
        const rightButton = scrollableContainer.querySelector('.scroll-button.scroll-right');
        const scrollIndicator = scrollableContainer.querySelector('.scroll-indicator');
        const scrollIndicatorThumb = scrollableContainer.querySelector('.scroll-indicator-thumb');
        let scrollIndicatorTimeout;

        if (!itemsContainer || !leftButton || !rightButton || !scrollIndicator || !scrollIndicatorThumb) {
            console.warn('Missing required elements in scrollable container');
            return;
        }

        // Mouse drag scrolling
        let isMouseDown = false;
        let startX;
        let scrollLeft;

        itemsContainer.addEventListener('mousedown', (e) => {
            isMouseDown = true;
            itemsContainer.style.cursor = 'grabbing';
            startX = e.pageX - itemsContainer.offsetLeft;
            scrollLeft = itemsContainer.scrollLeft;
        });

        itemsContainer.addEventListener('mouseleave', () => {
            isMouseDown = false;
            itemsContainer.style.cursor = 'grab';
        });

        itemsContainer.addEventListener('mouseup', () => {
            isMouseDown = false;
            itemsContainer.style.cursor = 'grab';
        });

        itemsContainer.addEventListener('mousemove', (e) => {
            if (!isMouseDown) return;
            e.preventDefault();
            const x = e.pageX - itemsContainer.offsetLeft;
            const walk = (x - startX);
            itemsContainer.scrollLeft = scrollLeft - walk;
        });

        // Button scroll
        const scrollStep = () => itemsContainer.offsetWidth * 0.9;

        function smoothScroll(element, target, duration = 500) {
            const start = element.scrollLeft;
            const distance = target - start;
            const startTime = performance.now();

            function animation(currentTime) {
                const timeElapsed = currentTime - startTime;
                const progress = Math.min(timeElapsed / duration, 1);
                const easeInOutQuad = t => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
                element.scrollLeft = start + (distance * easeInOutQuad(progress));

                if (progress < 1) {
                    requestAnimationFrame(animation);
                }
            }

            requestAnimationFrame(animation);
        }

        leftButton.addEventListener('click', () => {
            const targetScroll = itemsContainer.scrollLeft - scrollStep();
            smoothScroll(itemsContainer, targetScroll);
        });

        rightButton.addEventListener('click', () => {
            const targetScroll = itemsContainer.scrollLeft + scrollStep();
            smoothScroll(itemsContainer, targetScroll);
        });

        // Update button visibility
        const updateButtonVisibility = () => {
            const isAtStart = itemsContainer.scrollLeft <= 0;
            const isAtEnd = itemsContainer.scrollLeft >=
                (itemsContainer.scrollWidth - itemsContainer.clientWidth - 1);

            leftButton.style.opacity = isAtStart ? '0' : '1';
            rightButton.style.opacity = isAtEnd ? '0' : '1';

            leftButton.style.pointerEvents = isAtStart ? 'none' : 'auto';
            rightButton.style.pointerEvents = isAtEnd ? 'none' : 'auto';
        };


        // SCROLL INDICATION, CLICK SCROLLING AND DRAGGING

        // Update scroll indicator
        const updateScrollIndicator = () => {
            // Calculate the number of items and visible items
            const items = itemsContainer.children;
            const containerWidth = itemsContainer.clientWidth;
            const totalWidth = itemsContainer.scrollWidth;
            const visibleItems = containerWidth / (totalWidth / items.length);
            const totalItems = items.length;

            // Check if scrolling is needed
            const hasScrollableContent = totalWidth > containerWidth;
            scrollIndicator.style.display = hasScrollableContent ? 'block' : 'none';

            // If no scroll needed, exit early
            if (hasScrollableContent) {
                scrollIndicator.classList.add('active');
            } else {
                scrollIndicator.classList.remove('active');
            }

            // Calculate thumb width based on visible/total items ratio
            const minThumbWidth = 20; // Minimum thumb width in pixels
            const thumbWidthPercent = (visibleItems / totalItems) * 100;
            const thumbWidth = Math.max(
                minThumbWidth,
                (scrollIndicator.offsetWidth * thumbWidthPercent) / 100
            );

            // Calculate thumb position
            const scrollPercent = itemsContainer.scrollLeft / (totalWidth - containerWidth);
            const maxThumbOffset = scrollIndicator.offsetWidth - thumbWidth;
            const thumbPosition = maxThumbOffset * scrollPercent;

            // Update thumb style
            scrollIndicatorThumb.style.width = `${thumbWidth}px`;
            scrollIndicatorThumb.style.left = `${thumbPosition}px`;

            // Handle indicator opacity
            scrollIndicator.style.opacity = '0.8';
            clearTimeout(scrollIndicatorTimeout);
            scrollIndicatorTimeout = setTimeout(() => {
                scrollIndicator.style.opacity = '0.3';
            }, 600);
        };

        // Event listeners for scroll position
        itemsContainer.addEventListener('scroll', (e) => {
            updateButtonVisibility();
            updateScrollIndicator();
        });

        window.addEventListener('resize', () => {
            updateButtonVisibility();
            updateScrollIndicator();
        });

        // Mutation Observer to watch for content changes
        const observer = new MutationObserver(() => {
            updateScrollIndicator();
            updateButtonVisibility();
        });

        // --- Unified click and drag handling for scroll indicator
        let isDragging = false;

        function setScrollFromIndicator(e) {
            const indicatorRect = scrollIndicator.getBoundingClientRect();
            const clickPosition = (e.clientX - indicatorRect.left) / indicatorRect.width;
            const maxScroll = itemsContainer.scrollWidth - itemsContainer.clientWidth;
            const targetScroll = maxScroll * Math.max(0, Math.min(1, clickPosition));

            itemsContainer.scrollLeft = targetScroll;
        }

        scrollIndicator.addEventListener('mousedown', (e) => {
            isDragging = true;
            setScrollFromIndicator(e);
            scrollIndicator.style.cursor = 'grabbing';
            setTimeout(() => {
               setScrollIndicatorViewFromProximity(e);
            }, 20);
        });

        document.addEventListener('mousemove', (e) => {
            if (isDragging) {
                setScrollFromIndicator(e);
            }

        });

        document.addEventListener('mouseup', (e) => {
            isDragging = false;
            scrollIndicator.style.cursor = 'pointer';
        });

        // Thumbnail expand on hover
        let thumbExpandTimeout;
        document.addEventListener('mousemove', (e) => {
            if (isDragging) {
                setScrollFromIndicator(e);
                return;
            }

            setScrollIndicatorViewFromProximity(e);
        });

        // Proximity-based thumb expansion
        const setScrollIndicatorViewFromProximity = (e) => {
            const thumbRect = scrollIndicatorThumb.getBoundingClientRect();
            const proximityThreshold = 20; // pixels

            // Check if mouse is near the thumb area (including vertical proximity)
            const isNearThumb =
                Math.abs(e.clientX - (thumbRect.left + thumbRect.width/2)) < (thumbRect.width/2 + proximityThreshold) &&
                Math.abs(e.clientY - (thumbRect.top + thumbRect.height/2)) < (proximityThreshold * 2);

            // Clear any existing timeout
            clearTimeout(thumbExpandTimeout);

            if (isNearThumb) {
                scrollIndicatorThumb.classList.add('expanded');
            } else {
                // Small delay before collapsing
                thumbExpandTimeout = setTimeout(() => {
                    scrollIndicatorThumb.classList.remove('expanded');
                }, 150);
            }
        }
        // --- End of unified click and drag handling


        observer.observe(itemsContainer, {
            childList: true,
            subtree: true,
            attributes: true
        });

        // Initial visibility and indicator setup
        updateButtonVisibility();
        updateScrollIndicator();
    });
});




