PageSourceSearch

https://www.petitvictorhugo.fr/js/globals/script.js?v=26

js petitvictorhugo.fr collected 2026-10-04 09:41:16 UTC 28,805 bytes, 910 lines download raw bytes

1//-------------------------------------
2//	FUNCTIONS
3//-------------------------------------
4//-- Calculate Navigation Width
5const calculate_nav_width = () => {
6	// Ensure DOM elements exist before calculating
7	if (!d.q('.homelink') || !d.q('nav')) {
8		// Elements not ready yet
9		return
10	}
11	
12	// Update homelink width
13	const homelinkEl = d.q('.homelink')
14	
15	// Check if homelink is properly styled (should not be block-level spanning full width)
16	const homelinkDisplay = window.getComputedStyle(homelinkEl).display
17	const homelinkFloat = window.getComputedStyle(homelinkEl).float
18	const homelinkPosition = window.getComputedStyle(homelinkEl).position
19	
20	// If homelink is display:block and not floated/positioned, it's not ready yet
21	if (homelinkDisplay === 'block' && homelinkFloat === 'none' && homelinkPosition === 'static') {
22		nav_width = 0
23		return
24	}
25	
26	homelink_width = homelinkEl.scrollWidth
27	
28	// Additional safety check - if homelink is taking full window width, something's wrong
29	if (homelink_width >= window.innerWidth - 10) {
30		nav_width = 0
31		return
32	}
33	
34	if (nav_horizontal_right_left) {
35		let nav_padding_side =
36			parseInt(getComputedStyle(d.q('nav')).paddingLeft) + parseInt(getComputedStyle(d.q('nav')).paddingRight)
37
38		let btn_margin = 0
39		let btn_border = 0
40		let number_of_btns = 0
41		nav_btns_width = 0
42		
43		if (d.q('nav .buttons-wrap-header .btn')) {
44			number_of_btns = d.qAll('nav .buttons-wrap-header .btn').length
45			btn_margin = parseInt(getComputedStyle(d.q('nav .buttons-wrap-header .btn')).marginRight) || 0
46			btn_border = parseInt(window.getComputedStyle(d.q('nav .buttons-wrap-header .btn'), null).borderLeftWidth) * 2 || 0
47			for (let n = 0; n < number_of_btns; n++) {
48				nav_btns_width = nav_btns_width + d.qAll('nav .buttons-wrap-header .btn')[n].scrollWidth
49			}
50		}
51
52		nav_btns_width = nav_btns_width + btn_border * 2 * number_of_btns + btn_margin * number_of_btns
53		nav_dropdown_lang_width = 0
54		
55		if (template != 15 && d.q('.drodown-wrap--lang')) {
56			nav_dropdown_lang_width = d.q('.drodown-wrap--lang').scrollWidth || 0
57		}
58
59		let nav_items_width = 0
60		if (document.getElementsByClassName('nav__items')[0]) {
61			let navElement = document.getElementsByClassName('nav__items')[0]
62			nav_items_width = navElement.scrollWidth || 0
63		}
64
65		nav_width =
66			homelink_width +
67			nav_items_width +
68			nav_btns_width +
69			nav_dropdown_lang_width +
70			nav_padding_side +
71			20
72	}
73}
74
75//-- Adjust navigation widths when content overflows
76const adjust_nav_widths = () => {
77	let window_width = window.innerWidth
78	
79	if (nav_horizontal_left) {
80		if (nav_width >= window_width) {
81			d.q('.nav .nav-items-wrap').style.width = 'calc(100% - ' + d.q('.nav .nav__buttons').scrollWidth + 'px)'
82			d.q('.nav .homelink').style.width = '100%'
83		} else {
84			d.q('.nav .nav-items-wrap').style.width = 'auto'
85			d.q('.nav .homelink').style.width = 'auto'
86		}
87	}
88
89	if (nav_horizontal_right) {
90		if (nav_width >= window_width) {
91			d.q('.nav .homelink').style.width = 'calc(100% - ' + d.q('.nav .nav__buttons').scrollWidth + 'px)'
92		} else {
93			d.q('.nav .homelink').style.width = 'auto'
94		}
95	}
96
97	if (nav_horizontal_center) {
98		let nav_height = d.q('nav').offsetHeight
99		if (nav_height >= nav_height_max) {
100			d.q('.nav--buttons-only .homelink').style.width =
101				'calc(100% - ' +
102				d.q('.nav--buttons-only .nav__buttons').scrollWidth +
103				'px - ' +
104				d.q('.nav--buttons-only .buttons-wrap-header').scrollWidth +
105				'px - 24px)'
106		} else {
107			d.q('.nav--buttons-only .homelink').style.width = 'auto'
108		}
109	}
110}
111
112//-- Display Burger icon
113const display_burger_icon = () => {
114	let window_width = window.innerWidth
115	
116	if (nav_horizontal_right_left) {
117		// Determine if burger menu should show based on window width first
118		let should_show_burger = false
119		
120		// Fixed mobile breakpoint
121		if (window_width <= 768) {
122			// Mobile - always show burger
123			should_show_burger = true
124		} else if (window_width <= 1024) {
125			// Tablet range - calculate to see if nav fits
126			// Temporarily show nav items to get accurate measurement
127			let navItems = d.q('.nav__items')
128			let langDropdown = d.q('.drodown-wrap--lang')
129			let wasHidden = false
130			
131			if (navItems && navItems.style.display === 'none') {
132				navItems.style.display = 'flex'
133				wasHidden = true
134			}
135			if (langDropdown && langDropdown.style.display === 'none') {
136				langDropdown.style.display = 'flex'
137			}
138			
139			// Calculate with items visible
140			calculate_nav_width()
141			
142			// Hide again if calculation shows we need burger
143			if (nav_width === 0) {
144				// Measurement failed, if nav was hidden before, keep it hidden
145				should_show_burger = wasHidden
146			} else if (wasHidden || nav_width + 50 > window_width) {
147				should_show_burger = true
148			}
149		} else {
150			// Desktop (> 1024px) - only show burger if content really doesn't fit
151			// Temporarily show nav items to measure
152			let navItems = d.q('.nav__items')
153			let langDropdown = d.q('.drodown-wrap--lang')
154			
155			if (navItems && navItems.style.display === 'none') {
156				navItems.style.display = 'flex'
157			}
158			if (langDropdown && langDropdown.style.display === 'none') {
159				langDropdown.style.display = 'flex'
160			}
161			
162			// Calculate with items visible
163			calculate_nav_width()
164			
165			// For desktop, be more conservative - only show burger if really needed
166			if (nav_width === 0) {
167				// Measurement failed, default to showing full nav on desktop
168				should_show_burger = false
169			} else if (nav_width > window_width - 20) {
170				should_show_burger = true
171			} else {
172				should_show_burger = false
173			}
174		}
175		
176		if (should_show_burger) {
177			// Show burger menu
178			if (d.q('.nav__items')) d.q('.nav__items').style.display = 'none'
179			if (d.q('.drodown-wrap--lang')) d.q('.drodown-wrap--lang').style.display = 'none'
180			if (window_width <= 768 && d.q('nav .buttons-wrap-header')) d.q('nav .buttons-wrap-header').style.display = 'none'
181			if (d.q('.burger-button')) d.q('.burger-button').classList.add('show')
182		} else {
183			// Hide burger menu
184			if (d.q('.nav__items')) d.q('.nav__items').style.display = 'flex'
185			if (d.q('.drodown-wrap--lang')) d.q('.drodown-wrap--lang').style.display = 'flex'
186			if (d.q('nav .buttons-wrap-header')) d.q('nav .buttons-wrap-header').style.display = 'flex'
187			if (d.q('.burger-button')) d.q('.burger-button').classList.remove('show')
188			remove_burger_menu()
189		}
190	}
191
192	if (nav_horizontal_center) {
193		let nav_height = d.q('nav').offsetHeight
194
195		if (nav_height >= nav_height_max) {
196			d.q('.nav--buttons-only').style.top = '0'
197			d.q('nav').style.top = '-100%'
198			d.q('.burger-button').classList.add('show')
199		} else {
200			d.q('nav').style.top = '0'
201			d.q('.nav--buttons-only').style.top = '-100%'
202			d.q('.burger-button').classList.remove('show')
203			remove_burger_menu()
204		}
205	}
206
207	//-- If no logo and title too long
208	setTimeout(function () {
209		adjust_nav_widths()
210	}, 100)
211}
212
213//-- Display Burger menu
214const display_burger_menu = () => {
215	if (nav_vertical) {
216		d.q('.nav-vertical').classList.toggle('show')
217		d.q('body').classList.toggle('overlay')
218	} else {
219		d.q('.burger-menu').classList.toggle('show')
220	}
221	d.q('.burger-button').classList.toggle('active')
222	d.q('body').classList.toggle('burger-menu-enable')
223
224	// Update aria-expanded for accessibility
225	const burgerBtn = d.q('.burger-button')
226	if (burgerBtn) {
227		const isExpanded = burgerBtn.classList.contains('active')
228		burgerBtn.setAttribute('aria-expanded', isExpanded ? 'true' : 'false')
229	}
230}
231
232//-- Remove Burger menu
233const remove_burger_menu = () => {
234	if (nav_vertical) {
235		d.q('.nav-vertical').classList.remove('show')
236		d.q('body').classList.remove('overlay')
237	} else {
238		d.q('.burger-menu').classList.remove('show')
239	}
240	d.q('.burger-button').classList.remove('active')
241	d.q('body').classList.remove('burger-menu-enable')
242
243	// Update aria-expanded for accessibility
244	const burgerBtn = d.q('.burger-button')
245	if (burgerBtn) {
246		burgerBtn.setAttribute('aria-expanded', 'false')
247	}
248}
249
250//-- Remove buttons on nav for tiny screen
251const remove_buttons_menu = () => {
252	let window_width = window.innerWidth
253	// Check if buttons should be removed for mobile view
254
255	// Use a fixed breakpoint for consistency
256	if (window_width <= 480) {
257		// Hiding buttons (mobile width exceeded)
258		if (nav_horizontal_right_left) d.q('.buttons-wrap-header').style.display = 'none'
259		if (nav_vertical) d.q('header .buttons-wrap-header').style.display = 'none'
260		if (nav_horizontal_center)
261			for (let n = 0; n < d.qAll('.nav--buttons-only .btn').length; n++)
262				d.qAll('.nav--buttons-only .btn')[n].style.display = 'none'
263	} else {
264		if (nav_horizontal_right_left) {
265			if (window_width <= 768 && d.q('.burger-button') && d.q('.burger-button').classList.contains('show')) {
266				d.q('nav .buttons-wrap-header').style.display = 'none'
267			} else {
268				d.q('nav .buttons-wrap-header').style.display = 'flex'
269			}
270		}
271		if (nav_vertical) d.q('header .buttons-wrap-header').style.display = 'flex'
272		if (nav_horizontal_center)
273			for (let n = 0; n < d.qAll('.nav--buttons-only .btn').length; n++)
274				d.qAll('.nav--buttons-only .btn')[n].style.display = 'flex'
275	}
276}
277
278//-- Dropdown Burger Menu
279const display_burger_dropdown = (param) => {
280	param.offsetParent.classList.toggle('visible')
281
282	// Update aria-expanded for accessibility
283	const isExpanded = param.offsetParent.classList.contains('visible')
284	param.setAttribute('aria-expanded', isExpanded ? 'true' : 'false')
285}
286
287//-- Sticky nav menu
288const sticky_menu_nav = () => {
289	let nav_height = d.q('nav').offsetHeight
290	if (nav_height >= nav_height_max) {
291		let nav_height = d.q('.nav--buttons-only').offsetHeight
292		d.q('.menu-nav').style.top = nav_height + 'px'
293	} else {
294		let nav_height = d.q('.hello').offsetHeight
295		d.q('.menu-nav').style.top = nav_height + 'px'
296	}
297}
298
299//-- Menu active item
300const menu_active_item = () => {
301	for (let n = 0; n < d.qAll('.menu-nav__item').length; n++) {
302		d.qAll('.menu-nav__item')[0].classList.add('active')
303		d.qAll('.menu-nav__item')[n].onclick = function (e) {
304			for (let j = 0; j < d.qAll('.menu-nav__item').length; j++) {
305				d.qAll('.menu-nav__item')[j].classList.remove('active')
306			}
307			this.classList.add('active')
308		}
309	}
310}
311
312//-- Menu active item • Summary
313const menu_active_item_summary = () => {
314	for (let n = 0; n < d.qAll('.menu-nav__item--home').length; n++) {
315		d.qAll('.menu-wrap')[0].classList.add('active')
316		// Calculate height after a small delay to ensure content is rendered
317		setTimeout(() => {
318			if (d.q('.menus-wrapper') && d.qAll('.menu-wrap')[0]) {
319				d.q('.menus-wrapper').style.height = d.qAll('.menu-wrap')[0].offsetHeight + 'px'
320			}
321		}, 100)
322		d.qAll('.menu-nav__item--home')[0].classList.add('active')
323
324		d.qAll('.menu-nav__item--home')[n].onclick = function (e) {
325			for (let j = 0; j < d.qAll('.menu-wrap').length; j++) {
326				d.qAll('.menu-wrap')[j].classList.remove('active')
327
328				if (this.dataset.anchor == d.qAll('.menu-wrap')[j].getAttribute('id')) {
329					d.qAll('.menu-wrap')[j].classList.add('active')
330					d.q('.menus-wrapper').style.height = d.qAll('.menu-wrap')[j].offsetHeight + 'px'
331				}
332			}
333
334			for (let j = 0; j < d.qAll('.menu-nav__item--home').length; j++) {
335				d.qAll('.menu-nav__item--home')[j].classList.remove('active')
336			}
337
338			this.classList.add('active')
339		}
340	}
341}
342
343//-- Contact form with accessible error handling (WCAG 3.3.1, 3.3.3)
344if ($('#contact-form').length > 0) {
345	$('#contact-form').validate({
346		// Use custom error placement for accessibility
347		errorPlacement: function (error, element) {
348			var errorId = element.attr('id') + '-error'
349			var errorContainer = $('#' + errorId)
350			if (errorContainer.length > 0) {
351				errorContainer.text(error.text())
352			}
353		},
354		// Add aria-invalid when field is invalid
355		highlight: function (element) {
356			$(element).attr('aria-invalid', 'true')
357		},
358		// Remove aria-invalid when field is valid
359		unhighlight: function (element) {
360			$(element).attr('aria-invalid', 'false')
361			var errorId = $(element).attr('id') + '-error'
362			$('#' + errorId).text('')
363		},
364		// Announce errors to screen readers on form submit
365		invalidHandler: function (event, validator) {
366			var errorCount = validator.numberOfInvalids()
367			if (errorCount > 0) {
368				var errorSummary = $('#contact-form-errors')
369				var message = errorCount === 1
370					? '1 error found. Please correct the highlighted field.'
371					: errorCount + ' errors found. Please correct the highlighted fields.'
372				errorSummary.text(message)
373				// Focus first invalid field
374				$(validator.errorList[0].element).focus()
375			}
376		},
377		submitHandler: function (form) {
378			// Clear error summary on successful submit
379			$('#contact-form-errors').text('')
380			var options = {
381				target: '#contact-form', // target element(s) to be updated with server response
382				beforeSubmit: function (formData, jqForm, options) {
383					var queryString = $.param(formData)
384					return true
385				},
386				success: function (data) {
387					$('.step2').toggleClass('hidden')
388					// Send a google analytics event
389					$(window).trigger('contact-form-sent')
390				},
391				url: '/contact-form.php',
392			}
393			$(form).ajaxSubmit(options)
394			return false
395		},
396	})
397}
398
399//-- Fancybox
400$('[data-fancybox].iframe--widget').fancybox({
401	buttons: [],
402	touch: false,
403	beforeLoad: function () {
404		if (!$('.fancybox-iframe').parent().hasClass('iframe-wrapper')) {
405			$('.fancybox-iframe').wrap('<div class="iframe-wrapper"/>')
406		}
407	},
408})
409
410$('[data-fancybox].iframe--contact').fancybox({
411	buttons: [],
412	touch: false,
413	beforeLoad: function () {
414		if (!$('.fancybox-iframe').parent().hasClass('iframe-wrapper')) {
415			$('.fancybox-iframe').wrap('<div class="iframe-wrapper"/>')
416		}
417	},
418})
419
420$('[data-fancybox]:not(.iframe--widget):not(.iframe--menus)').fancybox({
421	iframe: {
422		css: {
423			height: '450px',
424		},
425	},
426	buttons: ['close'],
427	beforeLoad: function () {
428		if (!$('.fancybox-iframe').parent().hasClass('iframe-wrapper')) {
429			$('.fancybox-iframe').wrap('<div class="iframe-wrapper"/>')
430		}
431	},
432})
433
434function bindEvent(element, eventName, eventHandler) {
435	if (element.addEventListener) {
436		element.addEventListener(eventName, eventHandler, false)
437	} else if (element.attachEvent) {
438		element.attachEvent('on' + eventName, eventHandler)
439	}
440}
441
442//-- Listen to message from child window
443bindEvent(window, 'message', function (e) {
444	if (e.data === 'close-widget') {
445		$.fancybox.getInstance().close()
446	}
447})
448
449//-- Slider
450const slider = () => {
451	if ($('.slide').length > 0) {
452		$('.slide.active').cycle({
453			log: false,
454			prev: '.nav__btn--prev',
455			next: '.nav__btn--next',
456			slides: '>div',
457		})
458
459		$('.albums li').click(function (e) {
460			if (!$(this).hasClass('active')) {
461				var slider = $(this).children('a').attr('data-slider')
462				$('.albums li.active').removeClass('active')
463				$(this).addClass('active')
464				$('.slide.active').fadeOut(200, function () {
465					$('.slide.active').removeClass('active').cycle('pause')
466					$('#' + slider).fadeIn(200, function () {
467						if ($('#' + slider).is('.cycle-paused')) {
468							$(this).cycle('resume').addClass('active')
469						} else {
470							$('#' + slider)
471								.cycle({
472									log: false,
473									prev: '.nav__btn--prev',
474									next: '.nav__btn--next',
475									slides: '>div',
476								})
477								.addClass('active')
478						}
479					})
480				})
481			}
482			return false
483		})
484	}
485}
486
487//-------------------------------------
488//	MAIN
489//-------------------------------------
490const main = () => {
491	// Initialize navigation measurements first
492	initialize_nav_measurements()
493	
494	// Then check if burger icon should be displayed
495	if (nav_horizontal_right_left || nav_horizontal_center) display_burger_icon()
496	if (nav_horizontal_center && page_name == 'menus') sticky_menu_nav()
497	if (nav_horizontal_right_left || nav_horizontal_center || nav_vertical) remove_buttons_menu()
498	if (nav_vertical) d.q('.nav-items-wrap').style.height = 'calc(100% - ' + d.q('.nav__bottom').scrollHeight + 'px)'
499	menu_active_item()
500	menu_active_item_summary()
501	// if ((template_w_slider && (page_name == 'gallery' || page_name == 'custom')) || template == 0)
502	slider()
503
504	if (nav_vertical) {
505		if (768 >= window.innerWidth) {
506			d.q('.header-vertical .homelink').style.width =
507				'calc(100% - ' + d.q('.header-vertical .nav__buttons').scrollWidth + 'px)'
508		} else {
509			d.q('.header-vertical .homelink').style.width = 'auto'
510		}
511	} else if (nav_inside) {
512		if (768 >= window.innerWidth) {
513			d.q('.nav-inside .homelink').style.width =
514				'calc(100% - ' + d.q('.nav-inside .burger-button').scrollWidth + 'px)'
515		} else {
516			d.q('.nav-inside .homelink').style.width = 'auto'
517		}
518	}
519
520	//-- Delete loader (Must be before any external dependency as a fallback safety)
521	setTimeout(function () {
522		d.q('body').style.overflow = 'initial'
523		d.q('.loader-wrap').classList.add('hide')
524	}, 400)
525
526	//-- Opening hours active day
527	var day = new Date().getDay() || 7
528	$('.day' + day).addClass('day-wrap--active')
529
530	//-- Active page
531	let nav_item_class = d.q('.nav__item--' + page_name)
532	if (page_name != 'home' && nav_item_class) nav_item_class.classList.add('active')
533
534	//-- Smooth scrolling to page anchor on click
535	$("a[href*='#']:not([href='#'])").click(function () {
536		if (
537			location.hostname == this.hostname &&
538			this.pathname.replace(/^\//, '') == location.pathname.replace(/^\//, '')
539		) {
540			let target = $(this.hash)
541			let window_width = $(window).width()
542			let menu_nav_height = $('.menu-nav').outerHeight()
543			let nav_height = !nav_vertical ? $('nav').outerHeight() : $('header').outerHeight()
544
545			//-- Conditions
546			if (page_name == 'menus') {
547				if (
548					(window_width <= 970 && (template == 1 || template == 4)) ||
549					(window_width <= 750 && (template == 2 || template == 5))
550				) {
551					nav_height = nav_height + menu_nav_height
552				} else if (
553					(window_width <= 1220 && (template == 2 || template == 5)) ||
554					(window_width <= 750 && (template == 3 || template == 6)) ||
555					(window_width >= 750 && template == 9)
556				) {
557					nav_height = menu_nav_height
558				} else if (
559					(window_width >= 1220 && (template == 2 || template == 5)) ||
560					(window_width >= 750 && (template == 3 || template == 6))
561				) {
562					nav_height = 20
563				} else if (window_width >= 970 && (template == 1 || template == 4)) {
564					nav_height = nav_height
565				} else {
566					nav_height = nav_height + menu_nav_height
567				}
568			} else if (template == 0) {
569				nav_height = menu_nav_height
570			} else if (template == 10) {
571				nav_height = menu_nav_height
572			} else if (page_name == 'gallery') {
573				if (template == 3 || template == 6) {
574					nav_height = 20
575				} else {
576					nav_height = nav_height + 20
577				}
578			}
579
580			target = target.length ? target : $('[name=' + this.hash.slice(1) + ']')
581			if (target.length) {
582				$('html, body').animate(
583					{
584						scrollTop: target.offset().top - nav_height,
585					},
586					1000
587				)
588			}
589		}
590	})
591
592	//-- Smooth scrolling to the top of page
593	$('#scroll-top').click(function () {
594		$('html, body').animate(
595			{
596				scrollTop: 0,
597			},
598			500
599		)
600	})
601
602	//-- Tootips plugin init
603	tippy('.tippy', {
604		arrow: false,
605		animation: 'shift-away-subtle',
606	})
607
608	//-- Add class on nav when you scroll over XXXpx
609	$(window).scroll(function () {
610		if ($(this).scrollTop() > 100) {
611			$('nav').addClass('scroll')
612		} else {
613			$('nav').removeClass('scroll')
614		}
615	})
616
617	scrollTo(document.body, 0, 100)
618	document.querySelector('body').style.overflow = 'hidden'
619
620	//-- Browser update
621	var $buoop = { required: { e: -4, f: -3, o: -3, s: -1, c: -3 }, insecure: true, unsupported: true, api: 2021.05 }
622
623	function $buo_f() {
624		var e = document.createElement('script')
625		e.src = '//browser-update.org/update.min.js'
626		document.body.appendChild(e)
627	}
628	try {
629		document.addEventListener('DOMContentLoaded', $buo_f, false)
630	} catch (e) {
631		window.attachEvent('onload', $buo_f)
632	}
633}
634
635//-------------------------------------
636//	RESPONSIVE
637//-------------------------------------
638const responsive = () => {
639	// Add debouncing to prevent rapid recalculations
640	clearTimeout(window.resizeTimeout)
641	window.resizeTimeout = setTimeout(() => {
642		// Reset any width constraints before recalculating
643		if (nav_horizontal_left) {
644			if (d.q('.nav .nav-items-wrap')) d.q('.nav .nav-items-wrap').style.width = 'auto'
645			if (d.q('.nav .homelink')) d.q('.nav .homelink').style.width = 'auto'
646		}
647		if (nav_horizontal_right) {
648			if (d.q('.nav .homelink')) d.q('.nav .homelink').style.width = 'auto'
649		}
650		
651		// Recalculate navigation display
652		if (nav_horizontal_right_left || nav_horizontal_center) display_burger_icon()
653		if (nav_horizontal_center && page_name == 'menus') sticky_menu_nav()
654		if (nav_horizontal_right_left || nav_horizontal_center || nav_vertical) remove_buttons_menu()
655		if (nav_inside || (nav_vertical && 750 >= window.innerWidth)) remove_burger_menu()
656		if (nav_vertical) d.q('.nav-items-wrap').style.height = 'calc(100% - ' + d.q('.nav__bottom').scrollHeight + 'px)'
657		
658		// Apply width adjustments after navigation state is determined
659		adjust_nav_widths()
660
661		if (nav_vertical) {
662			if (768 >= window.innerWidth) {
663				d.q('.header-vertical .homelink').style.width =
664					'calc(100% - ' + d.q('.header-vertical .nav__buttons').scrollWidth + 'px)'
665			} else {
666				d.q('.header-vertical .homelink').style.width = 'auto'
667			}
668		} else if (nav_inside) {
669			if (768 >= window.innerWidth) {
670				d.q('.nav-inside .homelink').style.width =
671					'calc(100% - ' + d.q('.nav-inside .burger-button').scrollWidth + 'px)'
672			} else {
673				d.q('.nav-inside .homelink').style.width = 'auto'
674			}
675		}
676
677		//-- Resize menus summary on screen resize
678		for (let j = 0; j < d.qAll('.menu-wrap').length; j++) {
679			if (d.qAll('.menu-wrap')[j].classList.contains('active')) {
680				d.q('.menus-wrapper').style.height = d.qAll('.menu-wrap')[j].offsetHeight + 'px'
681			}
682		}
683	}, 150)
684}
685
686//-------------------------------------
687//	VARIABLES
688//-------------------------------------
689var d = document
690d.q = document.querySelector
691d.qAll = document.querySelectorAll
692
693var page_name = d.q('body').className.split('current-page-')[1].split(' ')[0]
694
695var template_w_slider = template == 0 || template == 7 || template == 8 || template == 9
696
697var nav_horizontal_right =
698	template == 1 ||
699	template == 4 ||
700	template == 11 ||
701	template == 15 ||
702	template == 16 ||
703	template == 17 ||
704	template == 18 ||
705	template == 19
706var nav_horizontal_left = template == 7
707
708var nav_horizontal_right_left = nav_horizontal_right + nav_horizontal_left
709
710var nav_horizontal_center = template == 8
711var nav_vertical = template == 2 || template == 5 || template == 9
712var nav_inside = template == 3 || template == 6
713
714//-- Init variables for nav
715var nav_btns_width = 0
716var nav_dropdown_lang_width = 0
717var homelink_width = 0
718var nav_width = 0
719var nav_mobile_width = 0
720var initial_nav_mobile_width = 0 // Store the initial calculation
721var nav_height_max = 0 // For nav_horizontal_center
722
723// Initialize navigation measurements after DOM is ready
724const initialize_nav_measurements = () => {
725	if (nav_vertical) {
726		let header_padding_side =
727			parseInt(getComputedStyle(d.q('header')).paddingLeft) + parseInt(getComputedStyle(d.q('header')).paddingRight)
728
729		let number_of_btns = 0
730		let btn_margin = 0
731		nav_btns_width = 0
732		
733		if (d.q('header .buttons-wrap-header .btn')) {
734			number_of_btns = d.qAll('header .buttons-wrap-header .btn').length
735			btn_margin = parseInt(getComputedStyle(d.q('header .buttons-wrap-header .btn')).marginRight) || 0
736			for (let n = 0; n < number_of_btns; n++)
737				nav_btns_width = nav_btns_width + d.qAll('header .buttons-wrap-header .btn')[n].scrollWidth
738			nav_btns_width = nav_btns_width + btn_margin * number_of_btns
739		}
740
741		nav_mobile_width = d.q('header .homelink').scrollWidth + nav_btns_width + 54 + header_padding_side
742		initial_nav_mobile_width = nav_mobile_width
743	}
744
745	if (nav_horizontal_center) {
746		var nav_padding =
747			parseInt(getComputedStyle(d.q('nav')).paddingTop) + parseInt(getComputedStyle(d.q('nav')).paddingBottom)
748		var item_margin =
749			parseInt(getComputedStyle(d.q('nav .nav__item')).marginTop) +
750			parseInt(getComputedStyle(d.q('nav .nav__item')).marginBottom)
751
752		let nav_btns_width = 0
753		let nav_btn_height = 0
754		if (d.q('.nav__items .btn')) {
755			nav_btn_height = d.q('.nav__items .btn').offsetHeight
756			for (let n = 0; n < d.qAll('.nav__items .btn').length; n++)
757				nav_btns_width = nav_btns_width + d.qAll('.nav__items .btn')[n].scrollWidth
758		}
759
760		nav_height_max =
761			(d.q('nav .nav__item').clientHeight + item_margin) * 2 + (nav_btn_height + item_margin) + nav_padding
762
763		// Get homelink width if not already set
764		if (homelink_width === 0 && d.q('.homelink')) {
765			homelink_width = d.q('.homelink').scrollWidth
766		}
767		
768		nav_mobile_width = homelink_width + nav_btns_width + 80 + 54 + 40
769		initial_nav_mobile_width = nav_mobile_width
770	}
771	
772	// For horizontal nav, calculate initial values
773	if (nav_horizontal_right_left) {
774		calculate_nav_width()
775	}
776}
777
778// Ensure DOM is ready before running main
779if (document.readyState === 'loading') {
780	document.addEventListener('DOMContentLoaded', main)
781} else {
782	// DOM is already ready, call main immediately
783	main()
784}
785
786window.addEventListener('resize', responsive)
787
788// Recalculate nav width when fonts are loaded
789if (document.fonts && document.fonts.ready) {
790	document.fonts.ready.then(() => {
791		// Reinitialize only if initial_nav_mobile_width wasn't set properly
792		if (initial_nav_mobile_width === 0) {
793			initialize_nav_measurements()
794		}
795		if (nav_horizontal_right_left || nav_horizontal_center) {
796			setTimeout(() => {
797				display_burger_icon()
798			}, 100)
799		}
800	})
801}
802
803// Also recalculate on window load (for images and other resources)
804window.addEventListener('load', () => {
805	// Reinitialize only if initial_nav_mobile_width wasn't set properly
806	if (initial_nav_mobile_width === 0) {
807		initialize_nav_measurements()
808	}
809	if (nav_horizontal_right_left || nav_horizontal_center) {
810		setTimeout(() => {
811			display_burger_icon()
812		}, 100)
813	}
814})
815
816// Additional safeguard - recalculate after a short delay
817setTimeout(() => {
818	// Final attempt to initialize if still not set
819	if (initial_nav_mobile_width === 0) {
820		initialize_nav_measurements()
821	}
822	if (nav_horizontal_right_left || nav_horizontal_center) {
823		display_burger_icon()
824	}
825}, 500)
826
827//-------------------------------------
828//	ACCESSIBILITY - Keyboard Navigation
829//-------------------------------------
830
831// Focus trap for modal dialogs (burger menu)
832const getFocusableElements = (container) => {
833	if (!container) return []
834	return Array.from(container.querySelectorAll(
835		'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not
835([tabindex="-1"])'
836	)).filter(el => el.offsetParent !== null) // Only visible elements
837}
838
839const trapFocus = (e, container) => {
840	const focusableElements = getFocusableElements(container)
841	if (focusableElements.length === 0) return
842
843	const firstElement = focusableElements[0]
844	const lastElement = focusableElements[focusableElements.length - 1]
845
846	if (e.shiftKey && document.activeElement === firstElement) {
847		// Shift+Tab on first element -> go to last
848		e.preventDefault()
849		lastElement.focus()
850	} else if (!e.shiftKey && document.activeElement === lastElement) {
851		// Tab on last element -> go to first
852		e.preventDefault()
853		firstElement.focus()
854	}
855}
856
857// Add keyboard support for burger button
858document.addEventListener('keydown', function (e) {
859	// Handle Enter or Space on burger button
860	if (e.target.classList.contains('burger-button')) {
861		if (e.key === 'Enter' || e.key === ' ') {
862			e.preventDefault()
863			display_burger_menu()
864			// Focus first focusable element in menu after opening
865			setTimeout(() => {
866				const burgerMenu = d.q('.burger-menu.show') || d.q('.nav-vertical.show')
867				if (burgerMenu) {
868					const focusable = getFocusableElements(burgerMenu)
869					if (focusable.length > 0) {
870						focusable[0].focus()
871					}
872				}
873			}, 100)
874		}
875	}
876
877	// Handle Enter or Space on dropdown icons in burger menu
878	if (e.target.classList.contains('fa-angle-down') && e.target.hasAttribute('role')) {
879		if (e.key === 'Enter' || e.key === ' ') {
880			e.preventDefault()
881			display_burger_dropdown(e.target)
882		}
883	}
884
885	// Handle Tab key for focus trap in burger menu
886	if (e.key === 'Tab') {
887		const burgerMenu = d.q('.burger-menu')
888		const navVertical = d.q('.nav-vertical')
889		if (burgerMenu && burgerMenu.classList.contains('show')) {
890			trapFocus(e, burgerMenu)
891		} else if (navVertical && navVertical.classList.contains('show')) {
892			trapFocus(e, navVertical)
893		}
894	}
895
896	// Handle Escape key to close burger menu
897	if (e.key === 'Escape') {
898		const burgerMenu = d.q('.burger-menu')
899		const navVertical = d.q('.nav-vertical')
900		if ((burgerMenu && burgerMenu.classList.contains('show')) ||
901			(navVertical && navVertical.classList.contains('show'))) {
902			remove_burger_menu()
903			// Return focus to burger button
904			const burgerBtn = d.q('.burger-button')
905			if (burgerBtn) {
906				burgerBtn.focus()
907			}
908		}
909	}
910})

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.