PageSourceSearch

https://publiatis.com/assets/js/main.js

js publiatis.com collected 2026-10-08 12:07:38 UTC 44,247 bytes, 1,650 lines download raw bytes

1
2
3var debugMode = true;
4var langDDLWrapper = null;
5var clientsList = null;
6var contactFormData = null;
7var contactModal = null;
8var contactButtonExpanded = false;
9var hasMouseWheelListener = false;
10var navClick = false;
11
12var nodeField = null;
13
14var hoveredBtnSolution = null;
15
16var sliderItemIcons = 
17[
18	"assets/medias/img/logos/aef.jpg",
19	"assets/medias/img/logos/citizen.jpg",
20	"assets/medias/img/logos/dep-vet.jpg",
21	"assets/medias/img/logos/editialis.jpg",
22	"assets/medias/img/logos/indigo.jpg",
23	"assets/medias/img/logos/map.jpg",
24	"assets/medias/img/logos/mefi.jpg",
25	"assets/medias/img/logos/onisep.jpg",
26	"assets/medias/img/logos/ritzau.jpg",
27	"assets/medias/img/logos/sipa.jpg",
28	"assets/medias/img/logos/sncf.jpg",
29	"assets/medias/img/logos/haratch.jpg",
30	"assets/medias/img/logos/contents.jpg"
31];
32var sliderInterval = 0;
33var isSliderPlaying = false;
34var slideStep = 1;
35
36
37var userInfo = 
38{
39	name: 		["Nom : ", ""],
40	company: 	["Société : ", ""],
41	email: 		["Email : ", ""],
42	phone: 		["Téléphone : ", ""],
43	needs: 		["Je souhaite obtenir des informations sur : ", ""],
44	status: 	["Je suis : ", "", null],
45	wishes: 	["Je souhaite : ", []]
46};
47
48var currentScrollPos = 0;
49var autoScrollDuration = 800;
50var autoScrollDest = 0;
51
52var _vw = 0;
53var _vh = 0;
54
55
56var initialPos = {};
57var firstTouches = [false, false, false];
58
59
60var initialPosTemp = {};
61var cardsPositionOffsets = [];
62var cardsSlideIndex = 0;
63
64var URLRewriter = null;
65
66
67const CLIENTS_XML_URL = "assets/xml/clients.xml";
68const CONTACT_FORM_URL = "assets/templates/contact-form-template.html";
69const WISH_FORM_URL = "assets/templates/wish-form-template.html";
70
71const SCROLLPOS_THRESHOLD = 150;
72
73
74var wishModalData = 
75{
76	id: null,
77	solution: null,
78	diagramValues: [],
79	color: null,
80	htmlList: null
81};
82//diagrams
83var availabilityDiagram = null;
84var savingDiagram = null;
85var simplicityDiagram = null;
86
87
88
89
90// case-insensitive jQuery:contains
91$.expr[":"].contains = $.expr.createPseudo(function(arg) 
92{
93	return function( elem ) 
94	{
95			return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
96	};
97});
98
99
100
101
102
103function init( jQuery )
104{
105	Logger.init(debugMode);
106	Logger.log( "init" );
107	
108	updateViewportDimensions();
109	initNav();
110	initLangDDL();
111	
112	Logger.log("init ::"+Cookies.get( "page-url"));
113	//screensize
114	// showScreenSize();
115	
116	// NodeField
117	initNodeField();
118	
119	initButtons();
120	
121	initCardButtons();
122	
123	initParallax();
124	
125	initSlider();
126	
127	initIntersectionObserver();
128	
129	initForms();
130	
131	initTooltip();
132	
133	initProductCards();
134	
135	initScrollOffsets();
136	
137	initRotationCards();
138	
139	initFooter();
140	
141	
142	
143	initURLRewriter();
144	
145	//TODO make it clean!
146	initAutoScrollCards();
147	
148	initMap();
149	
150	initWishModal();
151	
152	
153	$( window ).resize( windowResizeHandler );
154	$( document ).on( "webkitvisibilitychange", visibilityChangeHandler )
155	
156	setTimeout( preloadScreenFadeOut, 1500 );
157}
158
159
160function initWishModal()
161{
162	
163	let modalOpts = 
164	{
165		backdrop: true,
166		keyboard: false,
167		focus		: true,
168		show		: false
169	};
170	$( "#wish-modal" ).modal( modalOpts );
171	
172	$( "#wish-modal" ).on( "show.bs.modal", showWishModalHandler );
173	$( "#wish-modal" ).on( "shown.bs.modal", shownWishModalHandler );
174	$( "#wish-modal" ).on( "hide.bs.modal", hideWishModalHandler );
175	$( "#wish-modal" ).on( "hidden.bs.modal", hiddenWishModalHandler );
176	
177	$( "a#modal-contact-btn" ).click( modalContactButtonClickHandler );
178;
179}
180
181
182function showWishModal()
183{
184	Logger.log( "showWishModal - wishModalData.solution : "+wishModalData.solution );
185	$( "#wish-modal" ).find( "h2.modal-sub-title" ).html( wishModalData.solution );
186	$( "#wish-modal" ).find( "div.modal-content" ).attr( "id", wishModalData.id );
187	$( "#wish-modal" ).find( "div.modal-body div.main-content" ).html( wishModalData.htmlList );
188	$( "#wish-modal" ).modal( "show" );
189}
190function hideWishModal()
191{
192	$( "#wish-modal" ).modal( "hide" );
193}
194function showWishModalHandler( evt )
195{
196	//afficher les diagrammes
197	let availabilityContainer = $( "#wish-modal" ).find( "div.modal-body div#availability div.diagram" );
198	let savingContainer = $( "#wish-modal" ).find( "div.modal-body div#saving div.diagram" );
199	let simplicityContainer = $( "#wish-modal" ).find( "div.modal-body div#simplicity div.diagram" );
200	
201	let diam = $( window ).width() > 500 ? 100 : 85;
202	let thickness = $( window ).width() > 500 ? 10 : 5;
203	let fontSize = $( window ).width() > 500 ? 20 : 15;
204
205	availabilityDiagram = new CircularDiagram( diam, wishModalData.color, 0xedebe6, thickness, fontSize, availabilityContainer, "availabilityDiagram" );
206	savingDiagram = new CircularDiagram( diam, wishModalData.color, 0xedebe6, thickness, fontSize, savingContainer, "savingDiagram" );
207	simplicityDiagram = new CircularDiagram( diam, wishModalData.color, 0xedebe6, thickness, fontSize, simplicityContainer, "simplicityDiagram" );
208}
209function shownWishModalHandler( evt )
210{
211	Logger.log( "shownWishModalHandler" );
212	//animer les diagrammes
213	availabilityDiagram.animate( 0.99, 1000, "easeOutQuad" );
214	savingDiagram.animate( 0.75, 1000, "easeOutQuad", 500 );
215	simplicityDiagram.animate( 1, 1000, "easeOutQuad", 1000 );
216}
217
218function hideWishModalHandler( evt )
219{
220	
221}
222function hiddenWishModalHandler( evt )
223{
224	//remove diagrams
225	availabilityDiagram.destroy();
226	savingDiagram.destroy();
227	simplicityDiagram.destroy();
228	
229	availabilityDiagram = null;
230	savingDiagram = null;
231	simplicityDiagram = null;
232}
233
234
235function modalContactButtonClickHandler( evt )
236{
237	evt.preventDefault();
238	evt.stopPropagation();
239	
240	let allChecks = $( ".form-check-input" );
241	allChecks.prop( "checked", false );
242	allChecks.change();
243	
244	autoCheck( String( $( "#wish-modal" ).find( "div.modal-content" ).attr( "id" ) ) + "-contact" );
245	hideWishModal();
246	computeAutoScrollDestinationOffset( "section-contact" );
247	smoothScroll();
248}
249
250
251
252
253function initMap()
254{
255	Logger.log("initMap");
256	let map = L.map('map-wrapper').setView( [ 48.86424, 2.36541 ], 19 );
257	L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', 
258	{
259		attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
260		maxZoom: 20,
261		id: 'mapbox/streets-v11',
262		accessToken: 'pk.eyJ1IjoidGlkdXMxMDEiLCJhIjoiY2s1aTQ2YXc3MDlyZjNvbnZheHducXM1aSJ9.misVZNuT0g4Wc8dKop_FoQ'
263	}).addTo( map );
264	let marker = L.marker( [ 48.86424, 2.36541 ] ).addTo( map );
265	let popupOptions = 
266	{
267		minWidth: 220,
268		maxWidth: 500,
269		closeButton: false,
270		autoClose: false,
271		closeOnClick: false,
272		closeOnEscapeKey: false
273	}
274	let popupContent = "<p>PUBLIATIS</p>";
275	popupContent += "<p>5 BD des Nations Unies 92190 Meudon</p>";
276	popupContent += "<p><a href='tel:+33-1-46-26-20-57'>+33 (1) 46 26 20 57</a></p>";	
277	popupContent += "<p><a href='mailto:[email protected]?subject=Demande%20d%27information'>[email protected]</a></p>";
278	let popup = L.popup( popupOptions )
279		.setContent( popupContent )
280		marker.bindPopup( popup ).openPopup();
281		
282}
283
284
285
286function initAutoScrollCards()
287{
288	Logger.log( "initAutoScrollCards" );
289	cardsPositionOffsets = [ $( "#publi-s-overview-card" ).position().left, $( "#publi-l-overview-card" ).position().left, $( "#publi-a-overview-card" ).position().left ];
290	
291	$( ".cards-holder" ).on( "touchstart", cardsHolderTouchStartEventHandler );
292	$( ".cards-holder" ).on( "touchmove", cardsHolderTouchMoveEventHandler );
293}
294
295
296function cardsHolderTouchStartEventHandler( evt )
297{
298	Logger.log( "cardsHolderTouchStartEventHandler - cardsSlideIndex : "+cardsSlideIndex );
299	initialPosTemp = 
300	{
301		x: evt.touches[0].clientX,
302		y: evt.touches[0].clientY
303	}
304}
305
306function cardsHolderTouchMoveEventHandler( evt )
307{
308	Logger.log( "cardsHolderTouchMoveEventHandler" );
309	if( initialPosTemp.x === null ) return;
310	if( initialPosTemp.y === null ) return;
311	
312	let diff = {};
313	let currentPos =
314	{
315		x: evt.touches[0].clientX,
316		y: evt.touches[0].clientY
317	}
318	
319	diff =
320	{
321		x: initialPosTemp.x - currentPos.x,
322		y: initialPosTemp.y - currentPos.y
323	}
324	
325	let swipeOffset = $( this ).parents( ".row.d-sm-none" ).width();
326	Logger.log( "swipeOffset : "+swipeOffset );
327	let cardsHolderPosition = $( this ).position().left;
328	let newCardsHolderPosition = 0;
329	//mouvement horizontal
330	if( Math.abs( diff.x ) > Math.abs( diff.y ) )
331	{
332		//left
333		if( diff.x > 0 )
334		{
335			if( cardsSlideIndex < 2 )
336			{
337				cardsSlideIndex++;
338				// Logger.log( "list item : "+$( "li.pagination-dot" )[cardsSlideIndex] );
339			}
340		}
341		else //right
342		{
343			if( cardsSlideIndex > 0 )
344			{
345				cardsSlideIndex--;
346			}
347		}
348		newCardsHolderPosition = -cardsPositionOffsets[ cardsSlideIndex ];
349		$( this ).animate( { left: String( newCardsHolderPosition )+"px" }, 500, "easeOutCubic", finish );
350		//pagination dots
351		if( $( "li.pagination-dot" ).hasClass( "active" ) )
352		{
353			$( "li.pagination-dot" ).removeClass( "active" );
354		}
355		$( $( "li.pagination-dot" ).toArray()[cardsSlideIndex] ).addClass( "active" );
356	}
357	initialPosTemp.x = initialPosTemp.y = null;
358}
359
360function finish( evt )
361{
362	Logger.log( "finish" );
363	Logger.log( "cards-holder left : "+$( ".cards-holder" ).position().left );
364}
365
366
367
368
369
370
371
372
373
374
375
376
377function preloadScreenFadeOut()
378{
379	$( ".preload-screen" ).animate( { opacity: 0 }, 500, "easeOutCubic", preloadScreenFadeOutComplete );
380}
381
382function preloadScreenFadeOutComplete( evt )
383{
384	$( ".preload-screen" ).remove();
385}
386
387function initURLRewriter()
388{
389	Logger.log( "initURLRewriter" );
390	URLRewriter = new URLRewrite( window.location.href );
391	Logger.log( "initURLRewriter - URLRewriter : "+URLRewriter );
392}
393
394
395
396function showScreenSize()
397{
398	let w = $( window ).width();
399	let h = $( window ).height();
400	let dpr = window.devicePixelRatio;
401	let str = "width : "+w+" | height : "+h+" | dpr : "+dpr;
402	$(".screensize-display").html( str );
403}
404
405function initScrollOffsets()
406{
407	Logger.log( "initScrollOffsets" );
408	$(".sps").each( defineScrollOffset );
409}
410
411function defineScrollOffset( index, item )
412{
413	let className = $( this ).attr( "class" );
414	let threshold = 0;
415	var isMobilePortrait = Boolean( $( window ).width() < $( window ).height() && $( window ).width() < 576 )
416	if( className.includes( "card" ) )
417	{
418		threshold = SCROLLPOS_THRESHOLD;
419	}
420	else if( className.includes( "list-item" ) )
421	{
422		threshold = isMobilePortrait ? SCROLLPOS_THRESHOLD : SCROLLPOS_THRESHOLD * 2;
423	}
424	else if( className.includes( "banner" ) )
425	{
426		threshold = isMobilePortrait ? SCROLLPOS_THRESHOLD : SCROLLPOS_THRESHOLD * 2;
427	}
428	$( this ).attr( "data-sps-offset", $( this ).offset().top - ( $(window).height() - threshold ) );
429}
430
431
432function initButtons()
433{
434	$( "#find-solution" ).click( cardButtonClickHandler );
435}
436
437
438function initCardButtons()
439{
440	$( ".card-button-wrapper" ).click( cardButtonClickHandler );
441}
442
443
444//TODO coupler initProductCards et initRotationCards ( same same but different )
445
446function initProductCards()
447{
448	let cards = $( ".h-card-grid" );
449	cards.each( initRibbon );
450}
451
452function initRibbon( index )
453{
454	Logger.log( "initRibbon" );
455	let that = $( this );
456	let SVGRibbon = that.find( "svg#ribbon" );
457	SVGRibbon.children("text").attr( 
458	{
459		"font-size": "30",
460		"text-anchor": "middle"
461	});
462	SVGRibbon.children("text").css( "fill", "#FFF" );
463	
464	let eltID = that.attr( "id" );
465	
466	let offerType = eltID === "publi-s-card" || eltID == "publi-s-card-back" ? {n: "S
466aaS", c: "#006699"} : 
467									eltID === "publi-l-card" || eltID == "publi-l-card-back" ? {n: "Licence", c: "#f06730"} : {n: "Agence", c: "#ba232a"};
468	SVGRibbon.children("text").html( offerType.n );
469	SVGRibbon.find("polygon").css( "fill", offerType.c );
470}
471
472function initRotationCards()
473{
474	updateRotationCardsDimensions();
475	
476	let btn = $( ".d3-arrow-btn" );
477	let contactBtn = $( ".d3-contact-btn" );
478	btn.click( rotateCard );
479	contactBtn.click( threeDeeContactButtonClickHandler );
480	
481	//swipe handling
482	$( ".rotating-box" ).on( "touchstart", touchStartEventHandler );
483	$( ".rotating-box" ).on( "touchmove", touchMoveEventHandler );
484	
485	//swipe info
486	$( ".swipe-info" ).on( "touchstart", swipeInfoLayerTouchStartEventHandler );
487	
488}
489
490//TODO SUPPRIMER ET AJOUTER NAV DOTS
491function swipeInfoLayerTouchStartEventHandler( evt )
492{
493	Logger.log( "swipeInfoLayerTouchStartEventHandler" );
494	$( evt.currentTarget ).animate( { opacity: 1 }, 500, "easeOutCubic" );
495	setTimeout( removeSwipeScreen, 1750, $( evt.currentTarget ) );
496}
497
498function removeSwipeScreen( target )
499{
500	Logger.log( "removeSwipeScreen - target : "+target[0] );
501	target.animate( { opacity: 0 }, 500, "easeOutCubic", removeSwipeScreenCompleteHandler );
502}
503
504function removeSwipeScreenCompleteHandler( evt )
505{
506	Logger.log( "removeSwipeScreenCompleteHandler - this : "+$( this )[0] );
507	$( this ).remove();
508}
509
510function touchStartEventHandler( evt )
511{
512	initialPos = 
513	{
514		x: evt.touches[0].clientX,
515		y: evt.touches[0].clientY
516	}
517	
518	
519}
520
521function touchMoveEventHandler( evt )
522{
523	if( initialPos.x === null ) return;
524	if( initialPos.y === null ) return;
525	
526	let diff = {};
527	let currentPos =
528	{
529		x: evt.touches[0].clientX,
530		y: evt.touches[0].clientY
531	}
532	
533	diff =
534	{
535		x: initialPos.x - currentPos.x,
536		y: initialPos.y - currentPos.y
537	}
538	//mouvement horizontal
539	if( Math.abs( diff.x ) > Math.abs( diff.y ) )
540	{
541		//left
542		if( diff.x > 0 )
543		{
544			rotateCardRight( $( evt.currentTarget ) );
545		}
546		else //right
547		{
548			rotateCardLeft( $( evt.currentTarget ) );
549		}
550	}
551	initialPos.x = initialPos.y = null;
552}
553
554function swipeLeftHandler( evt )
555{
556	Logger.log( "swipeLeftHandler" );
557	// alert( "swipeLeftHandler - this.id : "+$( evt.currentTarget ).attr( "class" ) );
558	
559}
560
561function swipeRightHandler( evt )
562{
563	Logger.log( "swipeRightHandler" );
564	// alert( "swipeRightHandler - this.id : "+$( evt.currentTarget ).attr( "class" ) );
565	rotateCardLeft( $( evt.currentTarget ) );
566	// for( let s in evt )
567	// {
568		// Logger.log( "swipeLeftHandler - "+s+" => "+evt[s] );
569	// }
570}
571
572function rotateCardLeft( target )
573{
574	Logger.log( "rotateCardLeft" );
575	// evt.preventDefault();
576	// evt.stopPropagation();
577	let currentAngle = Number( target.attr( "data-rotation-angle" ) );
578	let destAngle = 0;
579	
580	
581	destAngle = currentAngle + 90;
582	//update data attribute
583	target.attr( "data-rotation-angle", destAngle );
584	
585	target.animateRotate(currentAngle, destAngle, 500, "easeOutQuad");
586}
587
588function rotateCardRight( target )
589{
590	Logger.log( "rotateCardLeft" );
591	// evt.preventDefault();
592	// evt.stopPropagation();
593	let currentAngle = Number( target.attr( "data-rotation-angle" ) );
594	let destAngle = 0;
595	
596	
597	destAngle = currentAngle - 90;
598	//update data attribute
599	target.attr( "data-rotation-angle", destAngle );
600	
601	target.animateRotate(currentAngle, destAngle, 500, "easeOutQuad");
602}
603
604
605function rotateCard( evt )
606{
607	Logger.log( "rotateCard" );
608	evt.preventDefault();
609	evt.stopPropagation();
610	let btnClassName = $( this ).attr( "class" );
611	
612	let rBox = btnClassName.includes( "publi-s" ) ? $( ".rotating-box.publi-s" ) : btnClassName.includes( "publi-l" ) ? $( ".rotating-box.publi-l" ) : $( ".rotating-box.publi-a" );
613	let currentAngle = Number( rBox.attr( "data-rotation-angle" ) );
614	let destAngle = 0;
615	
616	if( btnClassName.includes( "left" ) )
617	{
618		destAngle = currentAngle + 90;
619	}
620	else if( btnClassName.includes( "right" ) )
621	{
622		destAngle = currentAngle - 90;
623	}
624	//update data attribute
625	rBox.attr( "data-rotation-angle", destAngle );
626	
627	rBox.animateRotate(currentAngle, destAngle, 500, "easeOutQuad");
628}
629
630
631
632function updateRotationCardsDimensions()
633{
634	let _w = [];
635	let _h = [];
636	let _i = 0;
637	$( ".rb-front" ).each( 
638	function (index)
639	{ 
640			// Logger.log( $( this )[0] );
641		_w[ index ] = $( this ).width(); 
642		_h[ index ] = $( this ).height(); 
643	} );
644	
645	Logger.log( "updateRotationCardsDimensions w : "+_w+" | h : "+_h );
646	
647	
648	
649	$( ".rotating-box-wrapper2" ).each( function (index) {
650	$(this).css( { "transform": "translateZ(-"+( _w[index] >> 1 )+"px)" } ) } );
651	
652	
653	$( ".rotating-box-wrapper" ).each( function (index) {
654		if( _i > 2 ) _i -= 3;
655		$(this).css( { /*"width": _w[_i]+"px", */"height": _h[_i]+"px"  } ) } );
656	
657	_i = 0;
658	
659	$( ".rb-face" ).each( function (index) {
660		if( _i > 2 ) _i -= 3;
661		$(this).css( { "width": _w[_i]+"px", "height": _h[_i]+"px"  } ) } );
662		_i++;
663		
664	$( ".rb-front" ).each( function (index) {
665		$(this).css( { "transform": "translateZ("+( _w[index] >> 1 )+"px)" } ) } );
666		
667	$( ".rb-back" ).each( function (index) {
668		$(this).css( { "transform": "rotateY(180deg) translateZ("+( _w[index] >> 1 )+"px)" } ) } );
669		
670	$( ".rb-left" ).each( function (index) {
671		$(this).css( { "transform": "rotateY(-90deg) translateX(-"+( _w[index] >> 1 )+"px)" } ) } );
672		
673	$( ".rb-right" ).each( function (index) {
674		$(this).css( { "transform": "rotateY(90deg) translateX("+( _w[index] >> 1 )+"px)" } ) } );
675		
676		
677	$( ".rb-front" ).each( 
678	function (index)
679	{ 
680		_w[ index ] = $( this ).width(); 
681		_h[ index ] = $( this ).height(); 
682	} );
683	
684	$( ".d3-arrow-btn" ).each( function (index)
685	{
686		if( index > 2 ) index -= 3;
687		$(this).css
688		(
689			{
690				"top": String(_h[index] >> 1)+"px",
691				"transform": "translateY(-50%)"
692			}
693		) 
694	} );
695	
696	$( ".d3-container-row" ).each( function (index)
697	{
698		$(this).css
699		(
700			{
701				"height": String(_h[index] )+"px"
702			}
703		)
704	}	);
705	
706	
707	
708	
709	// Logger.log( "updateRotationCardsDimensions - section-solutions.height : "+$( ".section-solutions" ).height() );
710	//TODO recalculer la hauteur de la section-solutions ici!
711	// updateSectionSolutionsHeight();
712	
713}
714
715// function updateSectionSolutionsHeight()
716// {
717	
718// }
719
720
721function initFooter()
722{
723	$( ".sitemap-link-item" ).click( siteMapLinkItemClickHandler );
724}
725
726/**
727*	NAV
728**/
729function initNav()
730{
731	Logger.log( "initNav" );
732	$("li.nav-item").each( initNavItems );
733	let cookieVal = Cookies.get( "page-url" )
734	if( cookieVal === undefined )
735	{
736		$("li.nav-item").children( "a.nav-link:first" ).click();
737	}
738	else
739	{
740		$("li.nav-item").children( "a.nav-link[href='"+cookieVal+"']" ).click();
741	}
742}
743
744function initNavItems( index )
745{
746	$(this).children( "a.nav-link" ).click( navItemClickHandler );
747}
748
749function storeNavData( pageURL )
750{
751	let options = 
752	{
753		secure:		!debugMode
754	}
755	Cookies.set( "page-url", pageURL, options );
756	Logger.log( "storeNavData::cookie { page-url: "+Cookies.get( "page-url" )+" }" );
757}
758
759function updateNav( sectionID )
760{
761	// Logger.log( "updateNav" );
762	let navLink = $( "a.nav-link[href='"+sectionID+"']" );
763	let navItem = navLink.parent( ".nav-item" );
764	if( !navItem.hasClass( "active" ) )
765	{
766		// Logger.log( "REAL updateNav!!" );
767		storeNavData( sectionID );
768		
769		navItem.toggleClass( "active", true );
770		if( navItem.siblings().hasClass( "active" ) )
771		{
772			navItem.siblings().toggleClass("active", false);
773			//on force le focus out pour eviter le bug du bouton precedemment activé qui le reste
774			//quand scroll
775			navItem.siblings().trigger( "focusout" );
776			navItem.siblings().find( "a.nav-link" ).trigger( "focusout" );
777			navItem.siblings().find( "div.nav-item-underline" ).trigger( "focusout" );
778		}
779	}
780}
781function initLangDDL()
782{
783	Logger.log( "initLangDDL" );
784	langDDLWrapper = $('#langDDLWrapper');
785	let langDropDown = $('#langDDLWrapper a.dropdown-item');
786	langDropDown.click( langDDLItemClickHandler );
787	$('#langDDLWrapper a.dropdown-item:first').click();
788	/*
789	langDDLWrapper.on( "show.bs.dropdown", langDDLShowHandler );
790	langDDLWrapper.on( "hide.bs.dropdown", langDDLHideHandler );
791	*/
792}
793
794function updateLangDDLIcon( src )
795{
796	let langDDLBtn = $("#langDDLBtn");
797	langDDLBtn.html( "<img src='"+src+"' class='selected-ddl-icon'>" );
798}
799
800
801
802
803/**
804*	NODEFIELD
805**/
806function initNodeField()
807{
808	Logger.log( "initNodeField" );
809	// Definir le nb de nodes en fonction de la largeur d'ecran
810	let w = $( window ).width();
811	let nbNodes = w < 512 ? 20 : 50;
812	nodeField = new NodeField(nbNodes, $( ".nodefield-wrapper" ));
813}
814
815
816
817/**
818*	PARALLAX
819**/
820function initParallax()
821{
822	let parallaxParams = { speed: 8.0 };
823	new universalParallax().init( parallaxParams );
824
825}
826
827
828/**
829*	SLIDER
830**/
831function initSlider()
832{
833	Logger.log( "initSlider" );
834	let sliderContainer = $( ".slider-container" );
835	
836	let lng = sliderItemIcons.length;
837	for( let i = 0; i < lng; i++ )
838	{
839		sliderContainer.append( "<div class='slider-item' id='slider-item-"+i+"'></div>" );
840	}
841	
842	let sliderItems = $( ".slider-item" );
843	sliderItems.each( initSliderItem );
844}
845
846function initSliderItem( index, item )
847{
848	Logger.log( "initSlider - index : "+index );
849	$( this ).css( "background-image", "url("+ sliderItemIcons[ index ] +")" );
850}
851
852function autoSlide()
853{
854	// Logger.log( "autoSlide" );
855	let sliderContainer = $( ".slider-container" );
856	let sliderItems = $( ".slider-item" );
857	let sliderItem = $( ".slider-item" ).first();
858	let position = sliderContainer.css( "left" );
859	let positionNum = Number( position.substring(0, position.indexOf( "px" ) ) );
860	let newPos = positionNum - slideStep;
861
862	let threshold = Number( sliderItem.position().left + sliderItem.width() );
863	let marginLeft = sliderItem.css("margin-left");
864	
865	if( Math.abs( Number( sliderContainer.position().left ) ) > threshold )
866	{
867		newPos = Number( marginLeft.substring(0, marginLeft.indexOf( "px" ) ) ) * 2;
868		// sliderItem.remove();
869		sliderContainer.append( sliderItem );
870	}
871	
872	sliderContainer.css( "left", String( newPos ) +"px" );
873	
874}
875
876function playSlider()
877{
878	Logger.log( "playSlider" );
879	isSliderPlaying = true;
880	sliderInterval = setInterval( autoSlide, 30 );
881}
882
883function pauseSlider()
884{
885	Logger.log( "pauseSlider" );
886	isSliderPlaying = false;
887	clearInterval( sliderInterval );
888}
889
890
891/**
892*	INTERSECTION OBSERVER
893**/
894
895function initIntersectionObserver()
896{
897	
898	Logger.log("initIntersectionObserver");
899	let thresholds = [];
900	for( let i = 0; i <= 1.0; i+= 0.1 )
901	{
902		thresholds[ thresholds.length ] = i;
903	}
904	let options = 
905	{
906		root: null,
907		rootMargin: '0px',
908		threshold: thresholds //1.0
909	}
910
911	let observer = new IntersectionObserver(interSectionObserverCallback, options);
912	
913	
914	// Logger.log("initIntersectionObserver - observer : "+observer);
915	let nodeFieldWrapper = $(".nodefield-wrapper");
916	nodeFieldWrapper.each( function(){ observer.observe( $( this )[0] ); } );
917	
918	let sliderWrapper = $( ".slider-wrapper" );
919	sliderWrapper.each( function(){ observer.observe( $( this )[0] ); } );
920	
921	let _css = 
922	{
923		"top" : String( (_vh >> 1)-1 )+"px"
924	}
925	$(".mid-screen-intersect").css( _css );
926	
927	let options2 = 
928	{
929		root: null,
930		rootMargin: "-"+String( _vh >> 1 )+"px 0px -"+String( (_vh >> 1) )+"px 0px",
931		// rootMargin: "0px 0px -50% 0px",
932		threshold: thresholds //1.0
933	}
934	let sectionScrollObserver = new IntersectionObserver(sectionScrollInterSectionObserverCallback, options2);
935	
936	// Logger.log( "----------------------------- sectionScrollObserver.root : "+sectionScrollObserver.root );
937	
938	let sections = $( "section" );
939	sections.each( function(){ sectionScrollObserver.observe( $( this )[0] ); } );
940}
941
942function interSectionObserverCallback (entries, observer) 
943{ 
944	entries.forEach(entry => 				/* entries.forEach(function(entry){}) */
945	{
946		// Each entry describes an intersection change for one observed
947		// target element:
948		// entry.boundingClientRect
949		// entry.intersectionRatio
950		// entry.intersectionRect
951		// entry.isIntersecting
952		// entry.rootBounds
953		// entry.target
954		// entry.time
955		
956		//gestion nodefield
957		if( $(entry.target).hasClass("nodefield-wrapper") )
958		{
959			if( entry.intersectionRatio > 0 )
960			{
961				if( nodeField.isInit && !nodeField.isPlaying ) nodeField.play();
962			}
963			else
964			{
965				nodeField.pause();
966			}
967		}
968		//gestion slider
969		if( $(entry.target).hasClass("slider-wrapper") )
970		{
971			// Logger.log( "entry.intersectionRatio : "+entry.intersectionRatio );
972			if( entry.intersectionRatio > 0 )
973			{
974				if( !isSliderPlaying ) playSlider();
975			}
976			else
977			{
978				pauseSlider();
979			}
980		}
981		
982  });
983};
984
985function sectionScrollInterSectionObserverCallback (entries, observer) 
986{ 
987	entries.forEach(entry => 				/* entries.forEach(function(entry){}) */
988	{
989		let $entry = $(entry.target);
990		if( $entry.is("section") )
991		{
992			
993			let updateSectionID = null;
994			let updatePageURL = $entry.data( "url" );
995			
996			
997			if( entry.intersectionRatio > 0 && !navClick )
998			{
999				//mettre à jour la nav
1000				if( $entry.hasClass( "section-overview" ) )
1001				{
1002					updateSectionID = "section-overview";
1003					updateNav( updateSectionID );
1004				}
1005				else if( $entry.hasClass( "section-solutions" ) )
1006				{
1007					updateSectionID = "section-solutions";
1008					updateNav( updateSectionID );
1009				}
1010				else if( $entry.hasClass( "section-contact" ) )
1011				{
1012					updateSectionID = "section-contact";
1013					updateNav( updateSectionID );
1014				}
1015				
1016				//TODO implement a function for that and LOCALIZE!!!
1017				if( updatePageURL !== null && updatePageURL !== undefined && updatePageURL !== "")
1018				{
1019					// URLRewriter.setPageURL( updatePageURL );
1020				}
1021			}
1022			else
1023			{
1024			}
1025			
1026		}
1027  });
1028};
1029
1030
1031
1032/**
1033*	FORMS
1034**/
1035
1036
1037function initForms()
1038{
1039	initFormInputs();
1040	initWishForm();
1041	initContactForm();
1042}
1043
1044function initWishForm()
1045{
1046	Logger.log("initWishForm");
1047	$( "#wish-form-submit" ).click( wishFormSubmitClickHandler );
1048	$("#wish-form").submit( wishFormSubmitHandler );
1049}
1050
1051
1052function initContactForm()
1053{
1054	Logger.log("initContactForm");
1055	initFormInputs();
1056	$( "#contact-form-submit" ).click( contactFormSubmitClickHandler );
1057	$("#contact-form").submit( contactFormSubmitHandler );
1058}
1059
1060function initFormInputs()
1061{
1062	Logger.log( "initFormInputs" );
1063	$("input").change( formInputChangeHandler );
1064	$("input").focusout( formInputFocusOutHandler );
1065	$(".selectpicker").change( selectPickerChangeHandler );
1066}
1067
1068
1069function formInputChangeHandler( evt )
1070{
1071	Logger.log( "formInputChangeHandler" );
1072	//on gère les checkbox à input-change et non focus-out
1073	if( $(this).attr("type") === "checkbox" )
1074	{
1075		let allChecks = $( ".form-check-input" );
1076		let nbChecks = allChecks.length;
1077		let val = "";
1078		let that = null;
1079		for( let i = 0; i < nbChecks; i++ )
1080		{
1081			that = $( allChecks[ i ] );
1082			if( that.is( ":checked" ) )
1083			{
1084				val += "\n\t" + that.val();
1085			}
1086		}
1087		userInfo.needs[ 1 ] = val;
1088		updateTextArea();
1089	}
1090	if( $( "form" ).hasClass( "was-validated" ) )
1091	{
1092		$( this ).prev( ".input-group-prepend" ).find( "span.input-group-text" ).toggleClass( "invalid-input-feedback", Boolean( $( this )[0].checkValidity() === false ) );
1093		$( this ).prev( ".input-group-prepend" ).find( "span.input-group-text" ).toggleClass( "valid-input-feedback", Boolean( $( this )[0].checkValidity() === true ) );
1094	}
1095}
1096
1097function formInputFocusOutHandler( evt )
1098{
1099	Logger.log( "formInputFocusOutHandler" );
1100	let info = $(this).val();
1101	if( info !== "" )
1102	{
1103		switch( $( this ).attr( "id" ) )
1104		{
1105			case "name-input":
1106			userInfo.name[ 1 ] = info;
1107			break;
1108			case "company-input":
1109			userInfo.company[ 1 ] = info;
1110			break;
1111			case "email-input":
1112			userInfo.email[ 1 ] = info;
1113			break;
1114			case "phone-input":
1115			userInfo.phone[ 1 ] = info;
1116			break;
1117		}
1118		updateTextArea();
1119	}
1120}
1121
1122
1123function selectPickerChangeHandler( evt )
1124{
1125	Logger.log( "selectPickerChangeHandler - id : "+$(this).attr("id") );
1126	Logger.log( "selectPickerChangeHandler - parent : "+$(this).parent().attr("class") );
1127	let that = $(this);
1128	let selectedOpts = that.children( "option:selected" );
1129	let val = null;
1130	let strVal = null;
1131	
1132	switch( $(this).attr("id") )
1133	{
1134		case "status-select":
1135			// userInfo.status[ 1 ] = that.val();
1136			userInfo.status[ 1 ] = String( $( selectedOpts ).html() );
1137			userInfo.status[ 2 ] = Number( $( selectedOpts ).attr( "value" ) );
1138			updateTextArea();
1139		break;
1140		case "wishes-select":
1141			
1142			let nbSelected = selectedOpts.length;
1143			val = nbSelected > 0 ? [] : null;
1144			for( let i = 0; i < nbSelected; i++ )
1145			{
1146				// Logger.log( "selectPickerChangeHandler - selectedOpts id : "+$( selectedOpts[i] ).attr( "value" ) );
1147				// Logger.log( "selectPickerChangeHandler - selectedOpts id : "+$( selectedOpts[i] ).html() );
1148				// val[ val.length ] = Number( $( selectedOpts[i] ).attr( "value" ) );
1149				val[ val.length ] = String( $( selectedOpts[i] ).html() );
1150				Logger.log( "selectPickerChangeHandler - val : "+val );
1151			}
1152			userInfo.wishes[ 1 ] = val;
1153			
1154			
1155			
1156			strVal = "\n\t" + val.join( "\n\t" );
1157			userInfo.wishes[ 1 ] = strVal;
1158			if( val !== "" && val !== undefined && val !== null ) updateTextArea();
1159		break;
1160	}
1161}
1162
1163
1164function updateTextArea()
1165{
1166	Logger.log( "updateTextArea" );
1167	let str = "";
1168	str += userInfo.name[ 1 ] !== "" && userInfo.name[ 1 ] !== undefined && userInfo.name[ 1 ] !== null ? userInfo.name[ 0 ] + userInfo.name[ 1 ] + "\n" : "";
1169	str += userInfo.company[ 1 ] !== "" && userInfo.company[ 1 ] !== undefined && userInfo.company[ 1 ] !== null ? userInfo.company[ 0 ] + userInfo.company[ 1 ] + "\n" : "";
1170	str += userInfo.email[ 1 ] !== "" && userInfo.email[ 1 ] !== undefined && userInfo.email[ 1 ] !== null ? userInfo.email[ 0 ] + userInfo.email[ 1 ] + "\n" : "";
1171	str += userInfo.phone[ 1 ] !== "" && userInfo.phone[ 1 ] !== undefined && userInfo.phone[ 1 ] !== null ? userInfo.phone[ 0 ] + userInfo.phone[ 1 ] + "\n" : "";
1172	str += userInfo.needs[ 1 ] !== "" && userInfo.needs[ 1 ] !== undefined && userInfo.needs[ 1 ] !== null ? userInfo.needs[ 0 ] + userInfo.needs[ 1 ] + "\n" : "";
1173	str += userInfo.status[ 1 ] !== "" && userInfo.status[ 1 ] !== undefined && userInfo.status[ 1 ] !== null ? userInfo.status[ 0 ] + userInfo.status[ 1 ] + "\n" : "";
1174	str += userInfo.wishes[ 1 ].length > 0 && userInfo.wishes[ 1 ] !== undefined && userInfo.wishes[ 1 ] !== null ? userInfo.wishes[ 0 ] + userInfo.wishes[ 1 ] + "\n" : "";
1175	//str += "***************************************";
1176	$("#user-input-area").val( str );
1177}
1178
1179
1180function createWishForm( formData)
1181{
1182	Logger.log( "createWishForm" );
1183	let wishFormWrapper = $( ".wish-form-wrapper" );
1184	let htmlContent = formData;
1185	htmlContent += "</div>";
1186	htmlContent += "<div class='row'>";
1187	htmlContent += "<div class='col-lg-4'></div>";
1188	htmlContent += "<div class='col-lg-4'>";
1189	htmlContent += "<button type='submit' class='btn btn-more-infos btn-lg' id='contact-form-submit-btn'>Trouver ma solution !</button>";
1190	htmlContent += "</div>";
1191	htmlContent += "<div class='col-lg-4'></div>";
1192	htmlContent += "</form>";
1193	
1194	wishFormWrapper.append( htmlContent );
1195	wishFormWrapper.submit( wishFormSubmitHandler );
1196}
1197
1198function resetContactForm()
1199{
1200	Logger.log("resetContactForm");
1201	$("form.contact-form").removeClass( "was-validated" );
1202	$("form.contact-form .form-control").val( "" );
1203	$("form.contact-form .selectpicker").selectpicker( "val", "" );
1204	$("form.contact-form .selectpicker").selectpicker( "deselectAll" );
1205	for( var s in userInfo )
1206	{
1207		userInfo[ s ][ 1 ] = "";
1208	}
1209	
1210	// Logger.log("val 1 : "+$("textarea#user-input-area").val());
1211	$("textarea#user-input-area").val( "" );
1212	// Logger.log("val 2 : "+$("textarea#user-input-area").val());
1213	
1214	$( "form.contact-form" ).find( "span.input-group-text" ).removeClass( "valid-input-feedback" );
1215	$( "form.contact-form" ).find( "span.input-group-text" ).removeClass( "invali
1215d-input-feedback" );
1216}
1217
1218
1219/*mets à jour les durées de delai pour les animations du contact tab*/
1220function updateContactTabAnimation( evt )
1221{
1222	Logger.log("updateContactTabAnimation");
1223	if( evt.originalEvent.animationName === "deployW" )
1224	{
1225		$(":root").css( "--deployH-delay", "0.5s" );
1226		$(":root").css( "--deployW-delay", "0.9s" );
1227		$(":root").css( "--contact-tab-span-fade-in-delay", "1.5s" );
1228		$(":root").css( "--contact-tab-span-loop-delay", "3.5s" );
1229	}
1230}
1231
1232
1233
1234
1235/**
1236*	CUSTOMERS
1237**/
1238
1239function initCustomersTestimony()
1240{
1241	Logger.log( "initCustomersTestimony" );
1242	loadCustomersInfos();
1243	createCustomersTestimonyModal();
1244	$( ".customer-card" ).click( customerCardClickHandler );
1245}
1246
1247
1248function loadCustomersInfos()
1249{
1250	Logger.log( "loadCustomersInfos" );
1251	let options = 
1252	{
1253		dataType: "xml",
1254		method: "GET",
1255		error: customersInfoLoadErrorHandler,
1256		success: customersInfoLoadSuccessHandler,
1257		complete: customersInfoLoadCompleteHandler
1258	}
1259	$.ajax( CLIENTS_XML_URL, options );
1260}
1261
1262function createCustomersTestimonyModal()
1263{
1264	let htmlContent = "<div class='modal fade' id='testimony-modal' tabindex='-1' role='dialog' aria-labelledby='testimony-modal-title' aria-hidden='true'>";
1265	htmlContent += "<div class='modal-dialog modal-dialog-centered' role='document'>";
1266	htmlContent += "<div class='modal-content'>";
1267	htmlContent += "<div class='modal-header'>";
1268	htmlContent += "<h5 class='modal-title' id='testimony-modal-title'></h5>";
1269	htmlContent += "<button type='button' class='close' data-dismiss='modal' aria-label='Close'>";
1270	htmlContent += "<span aria-hidden='true'>&times;</span>";
1271	htmlContent += "</button>";
1272	htmlContent += "</div>";
1273	htmlContent += "<div class='modal-body'>";
1274	htmlContent += "<p class='testimony-description'></p>";
1275	htmlContent += "</div>";
1276	htmlContent += "<div class='modal-footer'>";
1277	htmlContent += "<button type='button' class='btn btn-primary'>Fermer</button>";
1278	htmlContent += "</div>";
1279	htmlContent += "</div>";
1280	htmlContent += "</div>";
1281	htmlContent += "</div>";
1282	
1283	let modalNode = $( htmlContent );
1284	let hasElement = ( $.contains( document.getElementsByTagName("main")[0], document.getElementById("testimony-modal") ) );
1285	if( !hasElement )
1286	{
1287		$( "main" ).append( modalNode );
1288	}
1289}
1290
1291function updateCustomersTestimonyModal( title, description )
1292{
1293	$("div#testimony-modal").find( "h5.modal-title" ).html( title );
1294	$("div#testimony-modal").find( "p.testimony-description" ).html( description );
1295	$('#testimony-modal').on('show.bs.modal', testimonyModalShowHandler);
1296	$('#testimony-modal').on('shown.bs.modal', testimonyModalShownHandler);
1297	$('#testimony-modal').on('hide.bs.modal', testimonyModalHideHandler);
1298	$('#testimony-modal').on('hidden.bs.modal', testimonyModalHiddenHandler);
1299	$( "#testimony-modal" ).modal( "show" );
1300}
1301
1302/**
1303*	TOOLTIP
1304**/
1305
1306function initTooltip()
1307{
1308	let options = 
1309	{
1310		delay: { "show": 500, "hide": 100 }
1311	}
1312	$('[data-toggle="tooltip"]').tooltip( options );
1313}
1314
1315
1316
1317
1318function smoothScroll()
1319{
1320	let currentScrollPos = $( "html" ).scrollTop();
1321	let autoScrollDuration = Math.abs( currentScrollPos - autoScrollDest ) >> 1;
1322	jQuery( "html" ).animate( { scrollTop: autoScrollDest }, autoScrollDuration, "easeInOutCubic", smoothScrollCompleteHandler );
1323}
1324
1325
1326function smoothScrollCompleteHandler( evt )
1327{
1328	if( navClick )
1329	{
1330		navClick = false;
1331	}
1332}
1333
1334function computeAutoScrollDestinationOffset( eltID )
1335{
1336	let targetElt = $( "#"+eltID );
1337	
1338	//Sections
1339	if( targetElt.is( "section" ) )
1340	{
1341		Logger.log( "computeAutoScrollDestinationOffset - la cible est une section" );
1342		let paddingTop = targetElt.find( ".section-title-wrapper" ).css( "padding-top" );
1343		paddingTop = Number( paddingTop.substring(0, paddingTop.indexOf( "px" ) ) )
1344		//on rajoute 1 car les divisions par decalage de bit renvoie un math.floor
1345		autoScrollDest = targetElt.offset().top - paddingTop + 1;
1346		Logger.log( "computeAutoScrollDestinationOffset - targetElt.offset().top : "+targetElt.offset().top );
1347		Logger.log( "computeAutoScrollDestinationOffset - autoScrollDest : "+autoScrollDest );
1348		
1349	}
1350	else	//divs
1351	{
1352		Logger.log( "computeAutoScrollDestinationOffset - la cible est une div" );
1353		let _vh = $( window ).height() >> 1;
1354		let _elth = targetElt.height() >> 1;
1355		autoScrollDest = targetElt.offset().top - _vh + _elth + 1;
1356	}
1357}
1358
1359
1360
1361/**
1362*	HANDLERS
1363*/
1364function navItemClickHandler( evt )
1365{
1366	evt.preventDefault();
1367	evt.stopPropagation();
1368	navClick = true;
1369	let navItem = $( this ).parent( ".nav-item" );
1370	if( !navItem.hasClass( "active" ) )
1371	{
1372		//TODO on utilise le data-url en preprod (a remplacer par la valeur href)
1373		storeNavData( $( this ).attr( "href" ) );
1374		
1375		navItem.toggleClass( "active", true );
1376		if( navItem.siblings().hasClass( "active" ) )
1377		{
1378			navItem.siblings().toggleClass("active", false);
1379		}
1380		
1381		computeAutoScrollDestinationOffset( $( this ).attr( "href" ) );
1382		smoothScroll();
1383	}
1384}
1385
1386function langDDLItemClickHandler( evt )
1387{
1388	let imgURL = $(evt.target).children( "img" ).attr( "src" );
1389	updateLangDDLIcon( imgURL );
1390}
1391
1392
1393function customerCardClickHandler( evt )
1394{
1395	// Logger.log( "customerCardClickHandler - title : "+$(this).data( "title" ) );
1396	let title = $(this).data( "title" );
1397	title = title.charAt(0).toUpperCase() + title.slice(1);
1398	let description = clientsList.find( "name:contains('"+title+"')" ).siblings( "description" ).text();
1399	Logger.log("customerCardClickHandler");
1400	updateCustomersTestimonyModal( title, description );
1401	$("body.modal-open").removeAttr("style");
1402}
1403
1404
1405function testimonyModalShowHandler( evt )
1406{
1407	Logger.log("testimonyModalShowHandler");
1408}
1409function testimonyModalShownHandler( evt )
1410{
1411	Logger.log("testimonyModalShownHandler");
1412}
1413
1414function testimonyModalHideHandler( evt )
1415{
1416	Logger.log("testimonyModalHideHandler");
1417
1418}
1419function testimonyModalHiddenHandler( evt )
1420{
1421	Logger.log("testimonyModalHiddenHandler");
1422	$( "#testimony-modal" ).modal( "dispose" );
1423
1424}
1425
1426
1427/**
1428*	XML HANDLING
1429**/
1430
1431function customersInfoLoadErrorHandler( jqXHR, textStatus, errorThrown )
1432{
1433	Logger.log( "customersInfoLoadErrorHandler - jqXHR : "+jqXHR+" | textStatus : "+textStatus+" | errorThrown : "+errorThrown );
1434}
1435
1436function customersInfoLoadSuccessHandler( data, textStatus, jqXHR )
1437{
1438	Logger.log( "customersInfoLoadSuccessHandler - data : "+data+" | textStatus : "+textStatus+" | jqXHR : "+jqXHR );
1439	clientsList = $( data );
1440	// let desc = clientsList.find( "name:contains('Onisep')" ).siblings( "description" ).text();
1441	// Logger.log( "desc : "+desc );
1442	// let clients = $(data).find( "client" ).text();
1443	// let names = $(data).find( "client" ).find( "name" ).text();
1444	// let solutions = $(data).find( "client" ).find("solutions").text();
1445	// Logger.log( "names : "+names );
1446	// Logger.log( "solutions : "+solutions );
1447}
1448
1449function customersInfoLoadCompleteHandler( jqXHR, textStatus )
1450{
1451	Logger.log( "customersInfoLoadCompleteHandler - jqXHR : "+jqXHR+" | textStatus : "+textStatus );
1452}
1453
1454
1455
1456/**
1457*	CONTACT FORM HANDLING
1458**/
1459
1460function contactFormSubmitClickHandler( evt )
1461{
1462	Logger.log( "contactFormSubmitClickHandler" );
1463	evt.preventDefault();
1464	evt.stopPropagation();
1465	$("#contact-form").submit();
1466}
1467
1468function contactFormSubmitHandler( evt )
1469{
1470	Logger.log( "contactFormSubmitHandler" );
1471	evt.preventDefault();
1472	evt.stopPropagation();
1473	let inValidInputs = $( $( this )[0] ).find( ".form-control:invalid" );
1474	inValidInputs.prev( ".input-group-prepend" ).find( "span.input-group-text" ).addClass( "invali
1474d-input-feedback" );
1475	
1476	let validInputs = $( $( this )[0] ).find( ".form-control:valid" );
1477	validInputs.prev( ".input-group-prepend" ).find( "span.input-group-text" ).addClass( "valid-input-feedback" );
1478	
1479	$(this).addClass( "was-validated" );
1480	
1481	if( $(this)[0].checkValidity() === false )
1482	{
1483		//do nothing wait for further validation
1484	}
1485	else
1486	{
1487		// send email
1488		var send = JSON.stringify( userInfo );
1489		Logger.log( "send -> "+send );
1490		//show validation  popup
1491	}
1492}
1493
1494/**
1495*	WISH FORM HANDLING
1496**/
1497
1498function wishFormSubmitClickHandler( evt )
1499{
1500	Logger.log( "wishFormSubmitClickHandler - userInfo.status[ 2 ] : "+userInfo.status[ 2 ] );
1501	evt.preventDefault();
1502	evt.stopPropagation();
1503	
1504	//pour refermer la drop down multi select
1505	if( $( "select#wishes-select" ).parent( "div.dropdown.bootstrap-select" ).hasClass( "show" ) )
1506	{
1507		$( "select#wishes-select" ).parent( "div.dropdown.bootstrap-select" ).removeClass( "show" );
1508		$( "select#wishes-select" ).parent( "div.dropdown.bootstrap-select" ).find( "div.dropdown-menu" ).removeClass( "show" );
1509	}
1510	
1511	if( userInfo.status[ 2 ] === null )
1512	{
1513		return;
1514	}
1515	else if( userInfo.status[ 2 ] === 0 )
1516	{
1517		Logger.log( "direction PUBLI-A" );
1518		
1519		wishModalData.id = "publi-a";
1520		wishModalData.solution = $( "div.rotating-box.publi-a" ).find( "div.h-card-header h2" ).html();
1521		Logger.log( "wishModalData.solution : "+wishModalData.solution );
1522		wishModalData.diagramValues = [0.99, 0.75, 1];
1523		wishModalData.color = 0xba232a;
1524		wishModalData.htmlList = $( "div.rotating-box.publi-a" ).find( "ul.offer-detail-list" ).first().clone();
1525		//on renvoie vers la solution publi-A
1526		computeAutoScrollDestinationOffset( "publi-a-card" );
1527		
1528	}
1529	else if( userInfo.status[ 2 ] > 0 )
1530	{
1531		Logger.log( "direction PUBLI-S" );
1532		wishModalData.id = "publi-s";
1533		wishModalData.solution = $( "div.rotating-box.publi-s" ).find( "div.h-card-header h2" ).html();
1534		wishModalData.diagramValues = [0.99, 0.75, 1];
1535		wishModalData.color = 0x006699;
1536		wishModalData.htmlList = $( "div.rotating-box.publi-s" ).find( "ul.offer-detail-list" ).first().clone();
1537		//on renvoie vers la solution publi-S
1538		// computeAutoScrollDestinationOffset( "section-solutions" );
1539		
1540	}
1541	//TEMP mise en place modal
1542	showWishModal();
1543	// $("#wish-form").submit();
1544}
1545
1546function wishFormSubmitHandler( evt )
1547{
1548	// Logger.log( "wishFormSubmitHandler - statut : "+userInfo.status );
1549	// Logger.log( "wishFormSubmitHandler - souhaits : "+userInfo.wishes );
1550	// Logger.log( "wishFormSubmitHandler - currentScrollPos : "+currentScrollPos );
1551	// Logger.log( "wishFormSubmitHandler - autoScrollDest : "+autoScrollDest );
1552	// Logger.log( "wishFormSubmitHandler - autoScrollDuration : "+autoScrollDuration );
1553	evt.preventDefault();
1554	evt.stopPropagation();
1555	smoothScroll();
1556}
1557
1558
1559function threeDeeContactButtonClickHandler( evt )
1560{
1561	evt.preventDefault();
1562	evt.stopPropagation();
1563	//pre cocher la checkbox correspondante
1564	autoCheck( $( this ).attr( "id" ) );
1565	
1566	computeAutoScrollDestinationOffset( "section-contact" );
1567	smoothScroll();
1568}
1569
1570function autoCheck( id )
1571{
1572	switch( id )
1573	{
1574		case "publi-s-contact":
1575		$( "#publi-s-checkbox" ).prop( "checked", true );
1576		$( "#publi-s-checkbox" ).change();
1577		break;
1578		
1579		case "publi-l-contact":
1580		$( "#publi-l-checkbox" ).prop( "checked", true );
1581		$( "#publi-l-checkbox" ).change();
1582		break;
1583		
1584		case "publi-a-contact":
1585		$( "#publi-a-checkbox" ).prop( "checked", true );
1586		$( "#publi-a-checkbox" ).change();
1587		break;
1588	}
1589}
1590
1591
1592function windowResizeHandler( evtObj )
1593{
1594	Logger.log("windowResizeHandler");
1595	updateViewportDimensions();
1596	updateRotationCardsDimensions();
1597}
1598
1599function visibilityChangeHandler( evt )
1600{
1601	Logger.log("visibilityChangeHandler");
1602	if (document.visibilityState == "hidden") 
1603	{
1604		//pause nodeField + pause slider
1605		nodeField.pause();
1606		pauseSlider();
1607	}
1608	else
1609	{
1610		nodeField.play();
1611		playSlider();
1612	}
1613}
1614
1615function cardButtonClickHandler( evt )
1616{
1617	Logger.log( "cardButtonClickHandler" );
1618	evt.preventDefault();
1619	evt.stopPropagation();
1620	computeAutoScrollDestinationOffset( $( this ).attr( "href" ) );
1621	smoothScroll();
1622}
1623
1624
1625function siteMapLinkItemClickHandler( evt )
1626{
1627	Logger.log( "siteMapLinkItemClickHandler" );
1628	evt.preventDefault();
1629	evt.stopPropagation();
1630	computeAutoScrollDestinationOffset( $( this ).attr( "href" ) );
1631	smoothScroll();
1632}
1633
1634/**
1635*	UTILS
1636**/
1637function updateViewportDimensions()
1638{
1639	Logger.log( "updateViewportDimensions" );
1640	Logger.log( "updateViewportDimensions - section-solutions.height : "+$( ".section-solutions" ).height() );
1641	_vw = $( window ).width();
1642	_vh = $( window ).height();
1643}
1644
1645function clearCookies()
1646{
1647	Cookies.remove( "page-url" );
1648}
1649
1650

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.