PageSourceSearch

https://baylawinjury.com/wp-content/themes/pql37/main.js?ver=7.1.2

js baylawinjury.com collected 2026-09-30 15:59:34 UTC 64,509 bytes, 1,777 lines download raw bytes

1/* Custom JS */
2
3(function (window,$) {
4	const wistiaVideos = [];
5
6	/* ------------------- JS to run after all html is completely loaded ------------------- */
7
8	$(document).ready(function () {
9
10
11
12
13
14		/* Sync breakpoints from css to be used for sliders and other responsive functionalities
15		 -------------------------------------------------------------------------------- */
16		const _xs = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--br-xs')),
17			_sm = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--br-sm')),
18			_md = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--br-md')),
19			_lg = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--br-lg')),
20			_xl = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--br-xl'));
21
22		const br = {
23				xsMin: 0,
24				xsMax: _xs,
25				smMin: _xs + 1,
26				smMax: _sm,
27				mdMin: _sm + 1,
28				mdMax: _md,
29				lgMin: _md + 1,
30				lgMax: _lg,
31				xlMin: _lg + 1,
32				xlMax: _xl,
33			},
34			isTouchBr = () => {
35				return window.innerWidth <= br.smMax;
36			};
37			
38
39
40
41		/* Class to add to body for lazyloading background images (ie responsive background images) or any image-related stuff that cant have the loading="lazy" attributes but can be in a way lazyloaded with css
42		-------------------------------------------------------------------------------- */
43		// $(window).on('load',function () {
44			$('html').addClass('doc-images-loaded');
45		// });
46
47
48
49
50
51		/* Modernizr - check if browser supports webp. if it does, do some things.
52		 -------------------------------------------------------------------------------- */
53
54		Modernizr.on('webp', function (result) {
55			if (result) {
56				// Has WebP support
57			} else {
58				// No WebP support
59			}
60		});
61
62
63
64
65
66		/* Video Related Scripts
67		-------------------------------------------------------------------------------- */
68		/* Wistia - Call function when script needs to be loaded either by hover or waypoints
69		id => wistia video id
70		addToQueue => whether to add to queue or not. this allows the video to play on function call
71		-------------------------------------------------------------------------------- */
72		function wistiaLoad(id, addToQueue) {
73			addToQueue = addToQueue || false;
74
75			typeof Wistia === 'undefined' &&
76				$.getScript('https://fast.wistia.com/assets/external/E-v1.js', function (data, textStatus, jqxhr) {
77					console.log('wistia load:', textStatus); // Success
78				});
79
80			if (!wistiaVideos[id]) {
81				$.getScript('//fast.wistia.com/embed/medias/' + id + '.jsonp', function (data, textStatus, jqxhr) {
82					console.log('json load:', id); // Success
83				});
84				wistiaVideos[id] = {
85					onQ: false,
86					wistia: {
87						id: id,
88						onReady: function (video) {
89							console.log('wistia clicked');
90							$('.wistia_embed[data-wistia-id="' + this.id + '"] .wistia_click_to_play')
91								.first()
92								.trigger('click');
93						}
94					}
95				};
96			}
97
98			if (addToQueue) {
99				window._wq = window._wq || [];
100
101				let interval = setInterval(function () {
102					if (!wistiaVideos[id].onQ && window._wq) {
103						console.log('adding to queue');
104						wistiaVideos[id].onQ = true;
105						_wq.push(wistiaVideos[id].wistia);
106						clearInterval(interval);
107						interval = null;
108					}
109				}, 100);
110			}
111		}
112		// separate download of thumbnailed wistia embeds to avoid conflicts with lazyload setup. wistia is somehow overriding it :|
113		$(window).on('scroll', function () {
114			$('.wistia_embed')
115				.not('.video-button')
116				.each(function () {
117					let video = $(this);
118					if ($(window).scrollTop() + $(window).innerHeight() > video.offset().top) {
119						wistiaLoad(video.data('wistia-id'), false);
120					}
121				});
122		});
123
124		// //load it all without filter. will decrease performance the score
125		// $('.wistia_embed').each(function(){
126		// 	let video = $(this);
127		// 	console.log(video);
128		// wistiaLoad(video.data('wistia-id'),false);
129		// });
130
131		// video buttons only download when about to be clicked
132		$('.wistia_embed')
133			.filter('.video-button')
134			.on('click', function () {
135				let id = $(this).data('wistia-id');
136				wistiaLoad(id, true);
137			});
138
139
140
141
142
143		/* Gravity Forms Enhancements
144		add `active` class for gfields when they have focused form fields so styles aren't a nightmare
145		-------------------------------------------------------------------------------- */
146		const inputselector = '.gfield input, .gfield select, .gfield textarea';
147		const inputActiveClass = 'active';
148		const inputFocusClass = 'focus';
149
150		/* sees if there's a value 
151			form => form element
152			inputSelector => inputselector
153			containerSelector => like .gfield
154		*/
155		function scanLabel(form, inputSelector, containerSelector) {
156			inputSelector = inputSelector || 'input,select,textarea';
157			containerSelector = containerSelector || '.gfield';
158			let fields = form.find(inputSelector);
159			fields.each(function () {
160				if ($(this).val()) {
161					$(this).closest(containerSelector).addClass(inputActiveClass);
162				}
163			});
164		}
165
166		/* adds active class baed on passed logic/condition
167			trueLogic => condition to use for class setup
168			fieldTarget => the field to manipulate classes
169			callback => function to call after everything is done. Example
170				function(fieldTarget){
171					//do something to fieldTarget
172				}
173			dontToggle => if it should run toggleClass if trueLogic is true. by default it uses addClass if trueLogic is true and then removeClass fal
173se.
174		*/
175		function toggleActiveClass(trueLogic, fieldTarget, callback, dontToggle) {
176			callback = callback || function (fieldTarget) {};
177
178			if (dontToggle) {
179				if (trueLogic) {
180					fieldTarget.addClass(inputActiveClass);
181				} else {
182					fieldTarget.removeClass(inputActiveClass);
183				}
184			} else {
185				if (trueLogic) {
186					fieldTarget.toggleClass(inputActiveClass);
187				}
188			}
189			callback(fieldTarget);
190		}
191
192		scanLabel($('.gform_body'), inputselector);
193
194		///focus
195		$('body').on('focus', inputselector, function (e) {
196			e.stopImmediatePropagation();
197			// not select because it is weird
198			if (e.target.tagName.toLowerCase() !== 'select') {
199				const currentValue = e.target.value; // $(this).val() should get accurate value but gravity forms brok the phone field type >:c
200				toggleActiveClass(!currentValue, $(e.target).closest('.gfield'), function (gfieldli) {
201					gfieldli.addClass(inputFocusClass);
202				});
203			}
204		});
205
206		//blur
207		$('body').on('blur', inputselector, function (e) {
208			e.stopImmediatePropagation();
209			// not select because it is weird
210			if (e.target.tagName.toLowerCase() !== 'select') {
211				const currentValue = e.target.value; // $(this).val() should get accurate value but gravity forms brok the phone field type >:c
212				toggleActiveClass(!currentValue, $(e.target).closest('.gfield'), function (gfieldli) {
213					gfieldli.removeClass(inputFocusClass);
214				});
215			}
216		});
217
218		//change
219		
220		// $('body').on('change', inputselector, function (e) {
221		// 	e.stopImmediatePropagation();
222		// 	// not select because it is weird
223		// 	// if (e.target.tagName.toLowerCase() == 'select') {
224
225		// 		let currentValue =  e.target.value;
226	
227		// 		toggleActiveClass(currentValue !== '', $(e.target).closest('.gfield'), null,false);
228		// 	// }
229		// });
230
231			// alternate solution in case gravity forms trolls us again on the next update
232			window.gform && window.gform.addAction( 'gform_input_change', function( elem, formId, fieldId ) {
233				const currentValue = elem.value;
234				toggleActiveClass(currentValue, $(elem).closest('.gfield'), null, true);
235			}, 10, 3 );
236
237		/* Hook it all up to gravity forms */
238		$(document).bind('gform_post_render', function () {
239			scanLabel($(this), inputselector);
240		});
241
242
243
244
245		/*  Setup Up Sliders - https://swiperjs.com/swiper-api
246		-------------------------------------------------------------------------------- */
247		
248
249		//Syncs breakpoints to styles so there's no twilight zone of weird sliders on certain screen sizes >:)
250		function sliderBrArgs(obj){
251
252			let toReturn = {};
253
254			if(obj["sm"] !== undefined) {
255				toReturn[br.smMin] = obj["sm"];
256			}
257			if(obj["md"] !== undefined) {
258				toReturn[br.mdMin] = obj["md"];
259			}
260			if(obj["lg"] !== undefined) {
261				toReturn[br.lgMin] = obj["lg"];
262			}
263			if(obj["xl"] !== undefined) {
264				toReturn[br.xlMin] = obj["xl"];
265			}
266
267			return toReturn;
268			
269		}
270
271
272		function setupSliders() {
273
274
275			// Template/ Example for setting up slider
276
277			//Single instance Example. Remember to rename variables uniquely as possible
278				const unqSldr = document.querySelector('#selector-for .slider-element:not(.swiper-initialized');
279
280				if(unqSldr) {
281					const UniqueSlider = new Swiper(unqSldr,{
282						loop: true,
283						speed: 1000,
284						autoplay: {
285							delay: 5000,
286						},
287						navigation: {
288							nextEl: unqSldr.querySelector('.swiper-button-next'),
289							prevEl: unqSldr.querySelector('.swiper-button-prev'),
290						},
291						scrollbar: {
292							el: unqSldr.querySelector('.swiper-scrollbar')
293						},
294						paginationClickable: true,
295						pagination: {
296							el: unqSldr.querySelector('.swiper-pagination'),
297							// type: 'custom',
298							// renderCustom: function (swiper, current, total) {
299							// 	const cPrefix = current > 9 ? '' : '0';
300							// 	const tPrefix = total > 9 ? '' : '0' ;
301							// 	return `${cPrefix}${current} / ${tPrefix}${(total)}`; 
302							// }
303						},
304						slidesPerView: 1,
305						spaceBetween: 30,
306						// autoHeight: true, //add dynamic height
307						// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
308						// 	rows: 2, // number of sliders per row
309						// 	fill:'row', //direction of row fill
310						// },
311						watchSlidesProgress: true, //keep this true so it's easier to style slider stuff and keep track of it
312						observer: true, //keep this true so it's easier to style slider stuff and keep track of it
313						observeParents: true, //keep this true so it's easier to style slider stuff and keep track of it
314						observeSlideChildren: true, //keep this true so it's easier to style slider stuff and keep track of it
315						preventClicks: false, //enable clicking within sliders allowing default behaviors
316						preventClicksPropagation: true, //part 2 of allowing default behaviors for slide
317						simulateTouch: false, //comment out if you want your cursor to do touch device things like swiping etc.
318						edgeSwipeThreshold: 0, // remove swiper threshold it does weird things with arrow's click bounds if sliders are not styled in a certain way.
319						//instead of checking $(window).width and running different slick methods every resize, consolidate all arguments in the responsive property instead
320						//Swiper sets up arguments mobile first. so argue the sliders as 
320such 
321						breakpoints: sliderBrArgs({
322							sm:{ // tablet
323								slidesPerView: 2,
324								spaceBetween: 30,
325								// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
326								// 	rows: 2,
327								// },
328							},
329							md:{ //laptop
330								slidesPerView: 3,
331								spaceBetween: 50,
332								// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
333								// 	rows: 2,
334								// },
335							},
336							lg:{ //desktop
337								slidesPerView: 4,
338								spaceBetween: 20,
339								// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
340								// 	rows: 2,
341								// },
342							},
343							xl:{ //hd
344								slidesPerView: 5,
345								spaceBetween: 30,
346								// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
347								// 	rows: 2,
348								// },
349							}
350							//no need to 'unslick', let's keep the slider enabled so the layout is still fixed if there is more slides or repeater rows added
351						})
352					});
353					
354					//additional methods for your slider
355					// UniqueSlider.doSomething();
356				}
357
358			// Multiple  instances Example.
359				$('#selector-for .slider-element.s')
360					.not('.swiper-initialized')
361					.each((i,sldr) => {
362						const slider = new Swiper(sldr,{
363							loop: true,
364							speed: 1000,
365							autoplay: {
366								delay: 5000,
367							},
368							navigation: {
369								nextEl: sldr.querySelector('.swiper-button-next'),
370								prevEl: sldr.querySelector('.swiper-button-prev'),
371							},
372							scrollbar: {
373								el: sldr.querySelector('.swiper-scrollbar')
374							},
375							pagination: {
376								el: sldr.querySelector('.swiper-pagination'),
377								clickable: true, //make it clickable
378								// type: 'custom',
379								// renderCustom: function (swiper, current, total) {
380								// 	const cPrefix = current > 9 ? '' : '0';
381								// 	const tPrefix = total > 9 ? '' : '0' ;
382								// 	return `${cPrefix}${current} / ${tPrefix}${(total)}`; 
383								// }
384							},
385							slidesPerView: 1,
386							spaceBetween: 30,
387							// autoHeight: true, //add dynamic height
388							// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
389							// 	rows: 2, // number of sliders per row
390							// 	fill:'row', //direction of row fill
391							// },
392							watchSlidesProgress: true, //keep this true so it's easier to style slider stuff and keep track of it
393							observer: true, //keep this true so it's easier to style slider stuff and keep track of it
394							observeParents: true, //keep this true so it's easier to style slider stuff and keep track of it
395							observeSlideChildren: true, //keep this true so it's easier to style slider stuff and keep track of it
396							preventClicks: false, //enable clicking within sliders allowing default behaviors
397							preventClicksPropagation: true, //part 2 of allowing default behaviors for slide
398							simulateTouch: false, //comment out if you want your cursor to do touch device things like swiping etc.
399							edgeSwipeThreshold: 0, // remove swiper threshold it does weird things with arrow's click bounds if sliders are not styled in a certain way.
400							//instead of checking $(window).width and running different slick methods every resize, consolidate all arguments in the responsive property instead
401							//Swiper sets up arguments mobile first. so argue the sliders as such 
402							breakpoints: sliderBrArgs({
403								sm:{ // tablet
404									slidesPerView: 2,
405									spaceBetween: 30,
406									// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
407									// 	rows: 2,
408									// },
409								},
410								md:{ //laptop
411									slidesPerView: 3,
412									spaceBetween: 50,
413									// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
414									// 	rows: 2,
415									// },
416								},
417								lg:{ //desktop
418									slidesPerView: 4,
419									spaceBetween: 20,
420									// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
421									// 	rows: 2,
422									// },
423								},
424								xl:{ //hd
425									slidesPerView: 5,
426									spaceBetween: 30,
427									// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
428									// 	rows: 2,
429									// },
430								}
431								//no need to 'unslick', let's keep the slider enabled so the layout is still fixed if there is more slides or repeater rows added
432							})
433						});
434
435					//additional methods for your slider
436					// slider.doSomething();
437					});
438
439
440
441			$('.home-section-1 .section-slider')
442				.not('.swiper-initialized')
443				.each((i,sldr) => {
444					const slider = new Swiper(sldr,{
445						loop: true,
446						speed: 1000,
447						// autoplay: {
448						//   delay: 5000,
449						// },
450						navigation: {
451						  nextEl: sldr.querySelector('.swiper-button-next'),
452						  prevEl: sldr.querySelector('.swiper-button-prev'),
453						},
454						// scrollbar: {
455						//   el: unqSldr.querySelector('.swiper-scrollbar')
456						// },
457						paginationClickable: true,
458						pagination: {
459						  el: sldr.querySelector('.swiper-pagination'),
460						  // type: 'custom',
461						  // renderCustom: function (swiper, current, total) {
462						  // 	const cPrefix = current > 9 ? '' : '0';
463						  // 	const tPrefix = total > 9 ? '' : '0' ;
464						  // 	return `${cPrefix}${current} / ${tPrefix}${(total)}`; 
465						  // }
466						},
467						slidesPerView: 1,
468						spaceBetween: 30,
469					    autoHeight: true, //add dynamic height
470						// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
471						// 	rows: 2, // number of sliders per row
472						// 	fill:'row', //direction of row fill
473						// },
474						watchSlidesProgress: true, //keep this true so it's easier to style slider stuff and keep track of it
475						observer: true, //keep this true so it's easier to style slider stuff and keep track of it
476						observeParents: true, //keep this true so it's easier to style slider stuff and keep track of it
477						observeSlideChildren: true, //keep this true so it's easier to style slider stuff and keep track of it
478						preventClicks: false, //enable clicking within sliders allowing default behaviors
479						preventClicksPropagation: true, //part 2 of allowing default behaviors for slide
480						simulateTouch: true, //comment out if you want your cursor to do touch device things like swiping etc.
481						edgeSwipeThreshold: 0, // remove swiper threshold it does weird things with arrow's click bounds if sliders are not styled in a certain way.
482						//instead of checking $(window).width and running different slick methods every resize, consolidate all arguments in the responsive property instead
483						//Swiper sets up arguments mobile first. so argue the sliders as such 
484						breakpoints: sliderBrArgs({
485						//   sm:{ // tablet
486						// 	slidesPerView: 1,
487						// 	spaceBetween: 95,
488						//   //   autoHeight: true, 
489						// 	// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
490						// 	// 	rows: 2,
491						// 	// },
492						//   },
493						  md:{ //laptop
494							slidesPerView: 2,
495							spaceBetween: 35,
496						  //   autoHeight: false, 
497							// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
498							// 	rows: 2,
499							// },
500						  },
501						  lg:{ //desktop
502							slidesPerView: 2,
503							spaceBetween: 35,
504						  //   autoHeight: false, 
505							// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
506							// 	rows: 2,
507							// },
508						  },
509						  xl:{ //hd
510							slidesPerView: 3,
511							spaceBetween: 35,
512						  //   autoHeight: false, 
513							// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
514							// 	rows: 2,
515							// },
516						  }
517						  //no need to 'unslick', let's keep the slider enabled so the layout is still fixed if there is more slides or repeater rows added
518						})
519					});
520
521				//additional methods for your slider
522				// slider.doSomething();
523				});
524			$('.layout-sidebar .section-slider')
525				.not('.swiper-initialized')
526				.each((i,sldr) => {
527					const slider = new Swiper(sldr,{
528						loop: true,
529						speed: 1000,
530						// autoplay: {
531						//   delay: 5000,
532						// },
533						navigation: {
534						  nextEl: sldr.querySelector('.swiper-button-next'),
535						  prevEl: sldr.querySelector('.swiper-button-prev'),
536						},
537// 						autoHeight: true,
538						// scrollbar: {
539						//   el: unqSldr.querySelector('.swiper-scrollbar')
540						// },
541						paginationClickable: true,
542						pagination: {
543						  el: sldr.querySelector('.swiper-pagination'),
544						  // type: 'custom',
545						  // renderCustom: function (swiper, current, total) {
546						  // 	const cPrefix = current > 9 ? '' : '0';
547						  // 	const tPrefix = total > 9 ? '' : '0' ;
548						  // 	return `${cPrefix}${current} / ${tPrefix}${(total)}`; 
549						  // }
550						},
551						slidesPerView: 1,
552						spaceBetween: 30,
553					  //   autoHeight: true, //add dynamic height
554						// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
555						// 	rows: 2, // number of sliders per row
556						// 	fill:'row', //direction of row fill
557						// },
558						watchSlidesProgress: true, //keep this true so it's easier to style slider stuff and keep track of it
559						observer: true, //keep this true so it's easier to style slider stuff and keep track of it
560						observeParents: true, //keep this true so it's easier to style slider stuff and keep track of it
561						observeSlideChildren: true, //keep this true so it's easier to style slider stuff and keep track of it
562						preventClicks: false, //enable clicking within sliders allowing default behaviors
563						preventClicksPropagation: true, //part 2 of allowing default behaviors for slide
564						simulateTouch: true, //comment out if you want your cursor to do touch device things like swiping etc.
565						edgeSwipeThreshold: 0, // remove swiper threshold it does weird things with arrow's click bounds if sliders are not styled in a certain way.
566						//instead of checking $(window).width and running different slick methods every resize, consolidate all arguments in the responsive property instead
567						//Swiper sets up arguments mobile first. so argue the sliders as 
567such 
568						breakpoints: sliderBrArgs({
569						//   sm:{ // tablet
570						// 	slidesPerView: 1,
571						// 	spaceBetween: 95,
572						//   //   autoHeight: true, 
573						// 	// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
574						// 	// 	rows: 2,
575						// 	// },
576						//   },
577						  // md:{ //laptop
578							// slidesPerView: 2,
579							// spaceBetween: 35,
580						  // //   autoHeight: false, 
581							// // grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
582							// // 	rows: 2,
583							// // },
584						  // },
585						  // lg:{ //desktop
586							// slidesPerView: 2,
587							// spaceBetween: 35,
588						  // //   autoHeight: false, 
589							// // grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
590							// // 	rows: 2,
591							// // },
592						  // },
593						  // xl:{ //hd
594							// slidesPerView: 3,
595							// spaceBetween: 35,
596						  // //   autoHeight: false, 
597							// // grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
598							// // 	rows: 2,
599							// // },
600						  // }
601						  //no need to 'unslick', let's keep the slider enabled so the layout is still fixed if there is more slides or repeater rows added
602						})
603					});
604
605				//additional methods for your slider
606				// slider.doSomething();
607				});
608				
609				$('.home-section-3 .section-slider')
610					.not('.swiper-initialized')
611					.each((i,sldr) => {
612						const slider = new Swiper(sldr,{
613							loop: true,
614							speed: 1000,
615							// autoplay: {
616							// 	delay: 5000,
617							// },
618							navigation: {
619								nextEl: sldr.querySelector('.swiper-button-next'),
620								prevEl: sldr.querySelector('.swiper-button-prev'),
621							},
622							scrollbar: {
623								el: sldr.querySelector('.swiper-scrollbar')
624							},
625							pagination: {
626								el: sldr.querySelector('.swiper-pagination'),
627								clickable: true, //make it clickable
628								// type: 'custom',
629								// renderCustom: function (swiper, current, total) {
630								// 	const cPrefix = current > 9 ? '' : '0';
631								// 	const tPrefix = total > 9 ? '' : '0' ;
632								// 	return `${cPrefix}${current} / ${tPrefix}${(total)}`; 
633								// }
634							},
635							slidesPerView: 1,
636							spaceBetween: 30,
637							autoHeight: true, //add dynamic height
638							// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
639							// 	rows: 2, // number of sliders per row
640							// 	fill:'row', //direction of row fill
641							// },
642							watchSlidesProgress: true, //keep this true so it's easier to style slider stuff and keep track of it
643							observer: true, //keep this true so it's easier to style slider stuff and keep track of it
644							observeParents: true, //keep this true so it's easier to style slider stuff and keep track of it
645							observeSlideChildren: true, //keep this true so it's easier to style slider stuff and keep track of it
646							preventClicks: false, //enable clicking within sliders allowing default behaviors
647							preventClicksPropagation: true, //part 2 of allowing default behaviors for slide
648							simulateTouch: false, //comment out if you want your cursor to do touch device things like swiping etc.
649							edgeSwipeThreshold: 0, // remove swiper threshold it does weird things with arrow's click bounds if sliders are not styled in a certain way.
650							//instead of checking $(window).width and running different slick methods every resize, consolidate all arguments in the responsive property instead
651							//Swiper sets up arguments mobile first. so argue the sliders as such 
652						});
653					//additional methods for your slider
654					// slider.doSomething();
655					});
656				
657				$('.home-section-4 .section-slider')
658					.not('.swiper-initialized')
659					.each((i,sldr) => {
660						const slider = new Swiper(sldr,{
661							loop: true,
662							speed: 1000,
663							// autoplay: {
664							// 	delay: 5000,
665							// },
666							navigation: {
667								nextEl: sldr.querySelector('.swiper-button-next'),
668								prevEl: sldr.querySelector('.swiper-button-prev'),
669							},
670							scrollbar: {
671								el: sldr.querySelector('.swiper-scrollbar')
672							},
673							pagination: {
674								el: sldr.querySelector('.swiper-pagination'),
675								clickable: true, //make it clickable
676								// type: 'custom',
677								// renderCustom: function (swiper, current, total) {
678								// 	const cPrefix = current > 9 ? '' : '0';
679								// 	const tPrefix = total > 9 ? '' : '0' ;
680								// 	return `${cPrefix}${current} / ${tPrefix}${(total)}`; 
681								// }
682							},
683							slidesPerView: 1,
684							spaceBetween: 30,
685							autoHeight: true, //add dynamic height
686							// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
687							// 	rows: 2, // number of sliders per row
688							// 	fill:'row', //direction of row fill
689							// },
690							watchSlidesProgress: true, //keep this true so it's easier to style slider stuff and keep track of it
691							observer: true, //keep this true so it's easier to style slider stuff and keep track of it
692							observeParents: true, //keep this true so it's easier to style slider stuff and keep track of it
693							observeSlideChildren: true, //keep this true so it's easier to style slider stuff and keep track of it
694							preventClicks: false, //enable clicking within sliders allowing default behaviors
695							preventClicksPropagation: true, //part 2 of allowing default behaviors for slide
696							simulateTouch: true, //comment out if you want your cursor to do touch device things like swiping etc.
697							edgeSwipeThreshold: 0, // remove swiper threshold it does weird things with arrow's click bounds if sliders are not styled in a certain way.
698							//instead of checking $(window).width and running different slick methods every resize, consolidate all arguments in the responsive property instead
699							//Swiper sets up arguments mobile first. so argue the sliders as 
699such 
700							breakpoints: sliderBrArgs({
701								md:{ //laptop
702									slidesPerView: 3,
703									spaceBetween: 42,
704									// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
705									// 	rows: 2,
706									// },
707                  arrows: false
708								},
709								lg:{ //desktop
710									slidesPerView: 3,
711									spaceBetween: 43,
712									// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
713									// 	rows: 2,
714									// },
715								},
716								xl:{ //hd
717									slidesPerView: 3,
718									spaceBetween: 58,
719									// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
720									// 	rows: 2,
721									// },
722								}
723							})
724
725
726
727
728						});
729
730					//additional methods for your slider
731					// slider.doSomething();
732					});
733					
734
735
736
737
738
739
740			// Add unique sliders...
741
742
743
744
745
746
747			// ...And then repeating instances
748				// Images/ Awards Slider
749				$('.awards-slider:not(.profile-awards-slider)')
750					.not('.swiper-initialized')
751					.each((i,sldr)=> {
752
753						const slider = new Swiper(sldr,{
754							loop: true,
755							speed: 1000,
756							autoplay: {
757								delay: 5000,
758							},
759							navigation: {
760								nextEl: sldr.querySelector('.swiper-button-next'),
761								prevEl: sldr.querySelector('.swiper-button-prev'),
762							},
763							scrollbar: {
764								el: sldr.querySelector('.swiper-scrollbar')
765							},
766							pagination: {
767								el: sldr.querySelector('.swiper-pagination'),
768								clickable: true, //make it clickable
769							},
770							slidesPerView: 1,
771							spaceBetween: 30,
772							centerInsufficientSlides: true,
773							// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
774							// 	rows: 2, // number of sliders per row
775							// 	fill:'row', //direction of row fill
776							// },
777							watchSlidesProgress: true, //keep this true so it's easier to style slider stuff and keep track of it
778							observer: true, //keep this true so it's easier to style slider stuff and keep track of it
779							observeParents: true, //keep this true so it's easier to style slider stuff and keep track of it
780							observeSlideChildren: true, //keep this true so it's easier to style slider stuff and keep track of it
781							preventClicks: false,
782							preventClicksPropagation: true,
783							// simulateTouch: false,
784							edgeSwipeThreshold: 0,
785							// simulateTouch: false, //comment out if you want your cursor to do touch device things
786							breakpoints: sliderBrArgs({
787								sm:{
788									slidesPerView: 3,
789									// simulateTouch: false
790								},
791								md:{
792									slidesPerView: 4,
793								},
794								lg:{
795									slidesPerView: 4,
796								},
797								xl:{
798									slidesPerView: 5,
799								}
800							})
801						});
802				
803				});
804				$('.profile-awards-slider')
805					.not('.swiper-initialized')
806					.each((i,sldr)=> {
807
808						const slider = new Swiper(sldr,{
809							loop: true,
810							speed: 1000,
811							autoplay: {
812								delay: 5000,
813							},
814							navigation: {
815								nextEl: sldr.querySelector('.swiper-button-next'),
816								prevEl: sldr.querySelector('.swiper-button-prev'),
817							},
818							scrollbar: {
819								el: sldr.querySelector('.swiper-scrollbar')
820							},
821							pagination: {
822								el: sldr.querySelector('.swiper-pagination'),
823								clickable: true, //make it clickable
824							},
825							slidesPerView: 1,
826							spaceBetween: 30,
827							centerInsufficientSlides: true,
828							// grid: { //use this to allow multiple rows on slider. Refer to swiper documentation for limitations of this settings
829							// 	rows: 2, // number of sliders per row
830							// 	fill:'row', //direction of row fill
831							// },
832							watchSlidesProgress: true, //keep this true so it's easier to style slider stuff and keep track of it
833							observer: true, //keep this true so it's easier to style slider stuff and keep track of it
834							observeParents: true, //keep this true so it's easier to style slider stuff and keep track of it
835							observeSlideChildren: true, //keep this true so it's easier to style slider stuff and keep track of it
836							preventClicks: false,
837							preventClicksPropagation: true,
838							// simulateTouch: false,
839							edgeSwipeThreshold: 0,
840							// simulateTouch: false, //comment out if you want your cursor to do touch device things
841							breakpoints: sliderBrArgs({
842								sm:{
843									slidesPerView: 2,
844									// simulateTouch: false
845								},
846								md:{
847									slidesPerView: 2,
848								},
849								lg:{
850									slidesPerView: 3,
851								},
852								xl:{
853									slidesPerView: 3,
854								}
855							})
856						});
857				
858				});
859
860			/*
861			//LEGACY - Slick
862			// make sure that the function only runs when slick is not initialized so it doesn't break
863			$('.class-name')
864				.not('.slick-initialized')
865				.slick({
866					// dependinng if mobileFirst is set to true or not, the arguments outsife of the responsive property should be the settings for the first breakpoint
867					autoplay: true,
868					dots: true,
869					rows: 0, // for newer version of slick to not wrap items in their own tags. Useful if you intend to style slider blocks with uniform height.  do not include if your site uses the old version
870					slidesToShow: 5,
871					sidesToScroll: 1, // set to 1 if sliders designed to have instances offseting vertically on certain columns of the slider is easier to style and less buggy when applied. (ie Troxell Law, Tiano O' Dell, etc)
872					// customPaging: fancyPagination, //add callback if design calls for pagination with fancy numbering for pagination
873					arrows: true,
874					prevArrow: sliderFancyButton('prev'), //NOTE: currently slick arrows set as css selectors have cases where they don't work on certain window sizes. please use this function from now on to avoid issues
875					nextArrow: sliderFancyButton('next'), //NOTE: currently slick arrows set as css selectors have cases where they don't work on certain window sizes. please use this function from now on to avoid issues
876					//instead of checking $(window).width and running different slick methods every resize, consolidate all arguments in the responsive property instead
877					//usually set at max widths of breakpoints. unless mobile first setup is enabled, then set them as the min-widths
878					responsive: [
879						{
880							// HD
881							breakpoint: br.xlMax, //or br.xlMin if mobile first
882							settings: {
883								//NOTE: best practice is not to set to unslick, in case content updates call for more than those already displayed
884								slidesToShow: 5
885							}
886						},
887						{
888							//desktop
889							breakpoint: br.lgMax, //or br.lgMin if mobile first
890							settings: {
891								slidesToShow: 4
892							}
893						},
894						{
895							//laptop
896							breakpoint: br.mdMax, //or br.mdMin if mobile first
897							settings: {
898								slidesToShow: 4
899							}
900						},
901						{
902							// tablet
903							breakpoint: br.smMax, //or br.smMin if mobile first
904							settings: {
905								slidesToShow: 2
906							}
907						},
908						{
909							// * Mobile
910							breakpoint: br.xsMax, //or br.xsMin if mobile first
911							settings: {
912								slidesToShow: 1
913							}
914						}
915					]
916				});
917
918			// Custom sliders by template sections
919
920			// And then repeating instances
921			$('.awards .awards-slider')
922				.not('.slick-initialized')
923				.slick({
924					// dependinng if mobileFirst is set to true or not, the arguments outsife of the responsive property should be the settings for the first breakpoint
925					autoplay: true,
926					dots: true,
927					rows: 0, // for newer version of slick to not wrap items in their own tags. Useful if you intend to style slider blocks with uniform height.  do not include if your site uses the old version
928					slidesToShow: 5,
929					sidesToScroll: 1, // set to 1 if sliders designed to have instances offseting vertically on certain columns of the slider is easier to style and less buggy when applied. (ie Troxell Law, Tiano O' Dell, etc)
930					// customPaging: fancyPagination, //add callback if design calls for pagination with fancy numbering for pagination
931					arrows: false,
932					prevArrow: sliderFancyButton('prev', 'button-style-diamond button-size-equal button-style-no-radius button-palette-primary button-style-flat'),
933					nextArrow: sliderFancyButton('next', 'button-style-diamond button-size-equal button-style-no-radius button-palette-primary button-style-flat'),
934					// * MobileFirst: true,
935					//instead of checking $(window).width and running different slick methods every resize, consolidate all arguments in the responsive property instead
936					//usually set at max widths of breakpoints. unless mobile first setup is enabled, then set them as the min-widths
937					responsive: [
938						{
939							// HD
940							breakpoint: br.xlMax, //or br.xlMin if mobile first
941							settings: {
942								//NOTE: best practice is not to set to unslick, in case content updates call for more than those already displayed
943								slidesToShow: 5
944							}
945						},
946						{
947							//desktop
948							breakpoint: br.lgMax, //or br.lgMin if mobile first
949							settings: {
950								slidesToShow: 4
951							}
952						},
953						{
954							//laptop
955							breakpoint: br.mdMax, //or br.mdMin if mobile first
956							settings: {
957								slidesToShow: 4
958							}
959						},
960						{
961							// tablet
962							breakpoint: br.smMax, //or br.smMin if mobile first
963							settings: {
964								slidesToShow: 2
965							}
966						},
967						{
968							// * Mobile
969							breakpoint: br.xsMax, //or br.xsMin if mobile first
970							settings: {
971								slidesToShow: 1
972							}
973						}
974					]
975				});
976				*/
977		}
978
979		// run the function. you can cut and paste this within $(document).ready or $(window).load if any issue persists
980		setupSliders();
981
982		const gridSliders = $('.section-slider.grid');
983		function setupGridSliders () {
984			gridSliders.each((i, sldr) => {
985				const slider = $(sldr);
986
987				if (window.innerWidth < 768) {
988					$(sldr).addClass('swiper');
989					$(sldr).removeClass('grid');
990				} else {
991					if ($(sldr).hasClass('swiper-initialized')) {
992						const swiperInstance = slider[0].swiper;
993						if (swiperInstance) {
994							swiperInstance.destroy();
995						}
996						$(sldr).removeClass('swiper-initialized');
997						$(sldr).removeClass('swiper');
998						$(sldr).addClass('grid');
999					}
1000				}
1001			})
1002		}
1003
1004		setupGridSliders();
1005
1006
1007
1008
1009
1010
1011		/* Add Sticky Helper so that header can have a different style when scrolling the page further. NOTE: DO NOT USE for setting header as fixed ot sticky when the class is present. header should already be so without the sticky class.
1012		-------------------------------------------------------------------------------- */
1013		function checkHeader(){
1014			let stickPoint = $('.layout-header + *').first().offset().top; //can be the banner or main
1015			$(window).scrollTop() > stickPoint
1016				? $('html').addClass('doc-header-sticky').removeClass('doc-header-not-sticky')
1017				: $('html').removeClass('doc-header-sticky').addClass('doc-header-not-sticky');
1018
1019		}
1020		checkHeader();
1021		$(window).on('scroll', checkHeader);
1022
1023
1024
1025
1026
1027
1028
1029		/* Smooth Scroll down to section on click (<a href="#id_of_section_to_be_scrolled_to">). NOTE: will cause animation issues on scroll if scoll-behavior is set to smooth
1030		-------------------------------------------------------------------------------- */
1031		
1032		// mark script
1033		function scrollToTargetElement(){
1034			// const jumpButtons = document.querySelectorAll('a[href*="#"]:not([href="#"])');
1035			const jumpButtons = document.querySelectorAll('a[href*="#"]');
1036			
1037			const handleClick = (e)=>{
1038				let target;
1039				
1040				try {
1041					target = document.querySelector(`${e.currentTarget.hash}`);
1042				}  catch(e) {
1043					// invalid hash or probably a weird url like google reviews, do nothing 
1044				}
1045
1046				if(target){
1047					e.preventDefault(); //Dont jump to top of screen
1048					target.scrollIntoView({behavior:'smooth'});
1049				} else {
1050					// PMS/SEO will put empty hash links in the menus sometimes. catch them and prevent default.
1051					if(e.currentTarget.closest('.menu')) {
1052						e.preventDefault();
1053					}
1054				}
1055			};
1056			
1057			jumpButtons.forEach((jumpButton)=>{
1058			  jumpButton.addEventListener('click',handleClick);
1059			});
1060			
1061		};
1062		scrollToTargetElement();
1063
1064		// // old jquery version, no longer cool
1065		// 	$('a[href*="#"]:not([href="#"])').click(function() {
1066		// 		const headerOffset = $('.layout-header').outerHeight() || 0;
1067		// 		if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
1068		// 			let target = $(this.hash);
1069		// 			target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
1070		// 			if (target.length) {
1071		// 				$('html, body').animate({
1072		// 					scrollTop: target.offset().top - headerOffset
1073		// 				}, 1000);
1074		// 				return false;
1075		// 			}
1076		// 		}
1077		// 	});
1078
1079
1080
1081
1082
1083
1084		/* SVGs for Style friendliness + performance readiness
1085		-------------------------------------------------------------------------------- */
1086		function loadSVGS() {
1087			$(':is(object, img, picture).inline-svg').each(function () {
1088				const img = $(this);
1089
1090				const svgSource = img.attr('data') ?? img.attr('src');
1091
1092				if (svgSource && svgSource.toString().split('.').pop() == 'svg') {
1093					const imgID = img.attr('id');
1094					const imgClass = img.attr('class');
1095
1096					$.get(
1097						svgSource,
1098						function (data) {
1099							let svg = $(data).find('svg');
1100							if (!svg) {
1101								return false;
1102							}
1103							if (typeof imgID !== 'undefined') {
1104								svg = svg.attr('id', imgID);
1105							}
1106							if (typeof imgClass !== 'undefined') {
1107								svg = svg.attr('class', imgClass + ' replaced-svg');
1108							}
1109							svg = svg.removeAttr('xmlns:a');
1110							img.replaceWith(svg);
1111						},
1112						'xml'
1113					);
1114				}
1115				//no more lazyloading background-images. we have plugins for that
1116			});
1117			console.log('svg loaded');
1118
1119			$('body').addClass('svgs-loaded');
1120		}
1121
1122		loadSVGS();
1123
1124
1125
1126
1127
1128
1129		/* menu toggle
1130		-------------------------------------------------------------------------------- */
1131		$('.toggle-menu').on('click', function (e) {
1132			e.preventDefault();
1133			$('html').toggleClass('doc-header-menu-open'), $(this).toggleClass('open');
1134			if (!$('html').hasClass('doc-header-menu-open')) {
1135				$('.layout-header .menu-item').removeClass('open');
1136			}
1137		});
1138
1139
1140
1141
1142
1143
1144		/* menu accordion 
1145		-------------------------------------------------------------------------------- */
1146		// open on tap/click mobile
1147		$('.layout-header .header-nav .menu-item.menu-item-has-children > a').on('click', function (e) {
1148			if (isTouchBr()) {
1149				e.preventDefault();
1150				$(e.target).closest('.menu-item').siblings().removeClass('open');
1151				$(e.target).closest('.menu-item').toggleClass('open');
1152			}
1153		});
1154
1155
1156
1157
1158
1159
1160		/* widget accordion
1161		-------------------------------------------------------------------------------- */
1162		$('.widget:not(.widget-style-no-toggle):not(#sidebar-form)').each(function ( i ) {
1163			const widget = $(this),
1164				contentSel = '*', // not just the usual types. let's also make sure we dont neglect the other types
1165				containerSel = 'li,.widget';
1166
1167			/* add class to elements that can toggle widget/ sub menu */
1168			widget.find('.sub-menu').siblings('a').addClass('widget-toggle');
1169			if(!$('body').hasClass('onep21-custom-template')) {
1170				widget.find('.widget-title,.widgettitle,.widget__title').not('.widget-style-no-toggle').addClass('widget-toggle');
1171			} else{
1172				widget.addClass('widget-style-no-toggle');
1173			}
1174
1175
1176
1177			// NOW FOR THE CUSTOMIZING WHICH ONES ARE OPEN PART
1178			
1179
1180				/* open first togglable widget on initial load */
1181				// i < 1 && widget.addClass('open');
1182
1183				// /* or open all widgets on initial load */
1184				widget.addClass('open');
1185
1186
1187				/* open items that contain the current viewed page */
1188				if(widget.hasClass('open')){
1189					// // opens all matching	
1190					// const currItem = widget.find('.current-menu-ancestor');
1191
1192					// opens first matching	
1193					const currItem = widget.find('.current-menu-ancestor').first();
1194
1195					if(currItem.children('.widget-toggle')){
1196						currItem.addClass('open');
1197					}
1198				}
1199
1200			/* event listener */
1201			widget.find('.widget-toggle').on('click', function (e) {
1202				e.preventDefault();
1203				//animate
1204				const toggle = $(this);
1205				const content = toggle.siblings(contentSel).first();
1206
1207				if (toggle.parent(containerSel).hasClass('open')) {
1208					content.slideUp(500,()=>{
1209						content.siblings('.widget-toggle').removeClass('open');
1210						content.parent(containerSel).removeClass('open');
1211					});
1212				} else {
1213					content.slideDown(500,()=>{
1214						content.siblings('.widget-toggle').addClass('open');
1215						content.parent(containerSel).addClass('open');
1216					});
1217				}
1218			});
1219		});
1220
1221
1222
1223
1224
1225		/* Scroll Tracker to toggle classes for animations. Replaces waypoint for less reliance on large libraries
1226		triggerElement => jQuery element to track visibility
1227		selectorToAnimate => class of element within trigger element to animate. falls back to `.animate__animated`
1228		classToAdd => class to add to selectorToAnimate
1229		offsetRatio => multiplier for viewport height to offset visibility. defaults to 0.
1230			setting to .5 will trigger script when triggerElement is halfway the viewport height
1231			setting to .99 will trigger script when triggerElement is peaking a few pixels at the bottom of the viewport
1232			setting to 0 (or default) will trigger script when triggerElement is at the very top of the viewport 
1233			.8 might work most of the time
1234		callback => function to callback. Example
1235			(trackedEl,isVisible) => {
1236				if(isVisible){
1237					//trackedEl is visible
1238				}else{
1239					
1240					//trackedEl is not visible
1241				}
1242
1243			}
1244		reverse => set to true or false if reverseing the animation on scroll up is desired
1245		reverseClass => class to add when reversing
1246		-------------------------------------------------------------------------------- */
1247
1248		function trackVisibility(triggerElement, classToAdd, selectorToAnimate, offsetRatio, callback, reverse, reverseClass) {
1249			selectorToAnimate = selectorToAnimate || '.animate__animated';
1250			reverseClass = reverseClass || '';
1251			offsetRatio = offsetRatio ? offsetRatio : 0;
1252
1253			const trackedEl = typeof triggerElement == 'string' ? $(triggerElement) : triggerElement;
1254
1255			if (!trackedEl.length) return;
1256
1257			function checkEl() {
1258				const visibilityStart = window.innerHeight * offsetRatio;
1259				const elementStart = trackedEl.offset().top;
1260
1261				if (window.scrollY + visibilityStart > elementStart) {
1262					trackedEl.addClass('visible');
1263
1264					if (selectorToAnimate) {
1265						trackedEl.find(selectorToAnimate).addClass(classToAdd);
1266						if (reverseClass) {
1267							trackedEl.find(selectorToAnimate).removeClass(reverseClass);
1268						}
1269					}
1270
1271					if (callback && typeof callback == 'function') {
1272						callback(trackedEl, true);
1273					}
1274				} else {
1275					if (reverse) {
1276						trackedEl.removeClass('visible');
1277						if (selectorToAnimate) {
1278							trackedEl.find(selectorToAnimate).removeClass(classToAdd);
1279							if (reverseClass) {
1280								trackedEl.find(selectorToAnimate).addClass(reverseClass);
1281							}
1282						}
1283
1284						if (callback && typeof callback == 'function') {
1285							callback(trackedEl, false);
1286						}
1287					}
1288				}
1289			}
1290
1291			// catch animated elements already visibile in the viewport.
1292			checkEl();
1293
1294			// add event listener for animation on scroll
1295			$(window).on('scroll', checkEl);
1296		}
1297
1298		//trackVisibility Instance - Single Element
1299		//Template -> trackVisibility($('#id'), 'classToAdd', '.elementToAnimate', offsetVal, function(triggerElement){}, reverse, 'reverseClass');
1300		//Example -> trackVisibility($('#home-section-2'), 'slideInUp', '.animate__animated', .5, null, true,'slideOutDown');
1301
1302		//trackVisibility Instance - Multiple Elements
1303		//Template -> $('.helper-class').each(function(){ trackVisibility($(this), 'classToAdd', $(this), offsetVal, function(triggerElement){}, reverse, 'reverseClass'); });
1304		//Example -> $('.inline-svg').each(function(){ trackVisibility($(this), 'inline-svg-stroke', $(this), .5, null, true, 'inline-svg-no-stroke'); });
1305
1306
1307
1308		/* Fancy Border Animated trackVisibility
1309		Animated fancy-border
1310		Requires:
1311		SCSS: scss/components/fancy.scss .fancy-border + .fancy-border-animated classes
1312		JS: Fancy border Animated trackVisibility
1313		-------------------------------------------------------------------------------- */
1314		$('.fancy-border-animated').each(function(){ trackVisibility($(this), '', $(this), 0.7, false, true, ''); });
1315		
1316		/* Fancy Letters trackVisibility
1317		Variation of Mr Garret's code to make a string able to animate letter entrance one by one
1318		Requires:
1319		PHP: functions/function-helpers.scss: onep21_fancy_letters. Text must be outputted using this function
1320		SCSS: scss/components/fancy.scss fancy-letters
1321		JS: Fancy Text Animated trackVisibility
1322		-------------------------------------------------------------------------------- */
1323		$('.fancy-letters').each(function(){ trackVisibility($(this), '', $(this), 0.9, false, true, ''); });
1324
1325		/* Fancy Background Animated trackVisibility
1326		Animated background
1327		Requires:
1328		SCSS: scss/components/fancy.scss .responsive-background,.responsive-background-wrapper + .responsive-background-animated-on-visible classes
1329		JS: Fancy border Animated trackVisibility
1330		-------------------------------------------------------------------------------- */
1331		$('.responsive-background-animated-on-visible').each(function(){ trackVisibility($(this), '', $(this), 0.9, false, true, ''); });
1332
1333
1334
1335		$("#gtranslate_selector option").each(function () {
1336			var val = $(this).val();
1337			var txt = $(this).html();
1338			//console.log("<li data-translate='" + val + "'>" + txt + "</li>");
1339			$(".ilawyer-translate-dropdown ul").append(
1340				//$("<li class='notranslate' data-translate='" + val + "'>" + txt + "</li>");
1341				$(`<li class="notranslate" data-translate="${val}">${txt}</li>`)
1342			);
1343		});
1344		$(".ilawyer-translate").on("click", function (e) {
1345			$(this).next(".ilawyer-translate-dropdown").toggleClass("open");
1346		});
1347		$(".ilawyer-translate-dropdown ul li").on("click", function (e) {
1348			var filterText = $(this).text();
1349			$(this)
1350				.closest(".ilawyer-translate-dropdown")
1351				.prev(".ilawyer-translate")
1352				.find("span")
1353				.text(filterText);
1354			$(this).closest(".ilawyer-translate-dropdown").removeClass("open");
1355			const dropDownData = $(this).attr("data-translate");
1356			$("#gtranslate_selector").val(dropDownData).change();
1357		});
1358
1359
1360
1361
1362		/* Popup Modals -  ie Case Results, Discourage Search Warning
1363		-------------------------------------------------------------------------------- */
1364		function destroyPopup(){
1365			///destrtroy
1366			$('body >  #il-popup').fadeOut().removeClass('active').remove();
1367			$('html').removeClass('doc-popup-active');
1368		}
1369
1370		function createPopup(contentToPrepend,classes) {
1371			classes = classes || '';
1372			contentToPrepend = contentToPrepend || '';
1373
1374			//destroy prior one if any
1375			destroyPopup();
1376
1377			$('body').append(function(){
1378				let html = `<div id="il-popup" class="popup">
1379				<div class="popup-overlay popup-destroy"></div>
1380					<div class="popup-body">
1381						<div class="container container-style-maxed popup-container">
1382							<div class="popup-frame ${classes}">
1383								${contentToPrepend}
1384								<button class="popup-destroy popup-close-button">Close</button>
1385							</div>
1386						</div>
1387					</div>
1388				</div>`;
1389
1390				return html;
1391			});
1392
1393			let popup = $('body > #il-popup');
1394
1395			$('html').addClass('doc-popup-active');
1396
1397			popup.fadeIn();
1398			popup.addClass('active');
1399		}
1400
1401		$('body').on('click','.popup-trigger',function(e){
1402			e.preventDefault();
1403
1404			const anchor = $(this).attr('data-href') || $(this).attr('href');
1405
1406			const popupContent = anchor && anchor !== '#' && $( anchor ).length
1407				? $( anchor )
1408				: $(this).siblings('.popup-content')
1409				;
1410				
1411
1412			if(popupContent.length){
1413				createPopup(popupContent.html(),$(this).data('popup-classes'));
1414			}
1415
1416		});
1417
1418		$('body').on('click','.popup-destroy',function(e){
1419				e.preventDefault();
1420				destroyPopup();
1421		});
1422
1423
1424
1425
1426		// /* Common Optional Stuff: Accordions - ie FAQs, etc.
1427		
1428		// To enable, follow the steps:
1429		// - Uncomment the sass import declaration in the style.scss file
1430		// - Unccoment script for "Common Optional Stuff: Accordions - ie FAQs, etc.
1431		// - To setup markup
1432		// 	- Add classes/Attrs to the following
1433		// 		- .accordion-wrapper => element wrapping a group of accordion items
1434		// 		- .accordion => blocks to hide or show depending on active state
1435		// 		- .accordion-trigger => set attribute to element that will toggle the accordion
1436		// -------------------------------------------------------------------------------- */
1437
1438
1439		// function toggleAccordion(toAddToggleClassTo,hash){
1440		// 	toAddToggleClassTo = toAddToggleClassTo || null;
1441		// 	hash = hash || window.location.hash;
1442
1443		// 	if($(hash).hasClass('accordion')) {
1444				
1445		// 		$('[href="'+hash+'"],[data-href="'+hash+'"]').closest('.accordion-wrapper')
1446		// 			.find('.accordion-trigger')
1447		// 			.not('[href="'+hash+'"],[data-href="'+hash+'"]')
1448		// 			.removeClass('open');
1449		// 		$(hash).closest('.accordion-wrapper')
1450		// 			.find('.accordion')
1451		// 			.not($(hash))
1452		// 			.each((i,acc)=>{
1453		// 				$(acc).slideUp(500,()=>{
1454		// 					$(acc).removeClass('open');
1455		// 				})
1456		// 				;
1457		// 			});
1458
1459				
1460		// 		$('.accordion-trigger[href="'+hash+'"],.accordion-trigger[data-href="'+hash+'"]').toggleClass('open');
1461
1462
1463		// 		if($(hash).hasClass('open')){
1464
1465		// 			if(history.pushState) {
1466		// 				let noHashURL = window.location.href.replace(/#.*$/, '');
1467		// 				window.history.pushState({}, '', noHashURL)
1468		// 			} else {
1469		// 				window.location.hash = '';
1470		// 			}
1471
1472		// 			$(hash)
1473		// 				.slideUp(500,()=>{
1474		// 					$(hash).removeClass('open');
1475		// 				})
1476		// 				;
1477		// 			if(toAddToggleClassTo) {
1478		// 				toAddToggleClassTo.removeClass('open');
1479		// 			}
1480		// 		} else {
1481		// 			if(history.pushState) {
1482		// 				history.pushState({}, '', hash);
1483		// 			} else {
1484		// 				window.location.hash = hash;
1485		// 			}
1486		// 			$(hash)
1487		// 				.slideDown(500,()=>{
1488		// 					$(hash).addClass('open');
1489		// 				})
1490		// 				;
1491		// 			if(toAddToggleClassTo) {
1492		// 				toAddToggleClassTo.removeClass('open');
1493		// 			}
1494		// 		}
1495		// 	}
1496		// }
1497		
1498		// $('.accordion-trigger').on('click',function(e){
1499		// 	e.stopPropagation();
1500		// 	e.preventDefault();
1501		// 	toggleAccordion(false,$(e.target).attr('href') || $(e.target).attr('data-href'));
1502		// });
1503	
1504		// toggleAccordion();
1505
1506
1507
1508
1509
1510
1511		// /* Common Optional Stuff: Filter Dropdown - ie Case Results, Attorney Grid, etc.
1512
1513		
1514		// To enable, follow the steps:
1515		// - Uncomment the sass import declaration in the style.scss file
1516		// - Unccoment script for "Filter Dropdown - ie Case Results " in main.js
1517		// - If being used for Case Results::after
1518		// 	-Setup `Case Result Types` on
1519		// 		- Admin > Theme Options > Other Components if there are no CPTs for case results being used
1520		// 		- Admin > Case Results > Case Result Types if CPT Case results are enabled
1521		// 		- Add classes/Attrs to the following
1522		// 			- .filter-blocks => PARENT wrapper of case results row
1523		// 			- .filter-block => set as the value for 'part_classes' of includes/repeater-results.
1524		// - If being used for other purposes
1525		// 	- Use template part includes/helper-filter-dropdown
1526		// 	- Add classes/Attrs to the following
1527		// 		- .filter-blocks => PARENT wrapper of the items to be filtered
1528		// 		- .filter-block => blocks to hide or show depending on active filter
1529		// 		- [data-filter] => set attribute to applicable filter slugs separated by commas
1530		// -------------------------------------------------------------------------------- */
1531		// $('.filter-label').on('click',function(e){
1532		// 	e.preventDefault();
1533		// 	$(this).siblings('.filter-dropdown').first().slideToggle(200);
1534		// })
1535
1536		// $('.filter .filter-dropdown a').on('click',function(e){
1537		// 	e.preventDefault();
1538		// 	const self = $(this);
1539		// 	const filterKey = self.attr('data-filter-key');
1540		// 	const filterValue = self.attr('href');
1541		// 	const blocksWrapper = self.closest('.filter').siblings('.filter-blocks').length
1542		// 	? self.closest('.filter').siblings('.filter-blocks')
1543		// 	: $('.filter-blocks').first();
1544		// 	const filterBlock = blocksWrapper.children('.filter-block');
1545
1546		// 	const noResultsText = self.closest('.filter').children('.filter-empty-text').html() || 'No results found';
1547
1548		// 	blocksWrapper.siblings('.filter-empty').remove();
1549
1550		// 	self.closest('li')
1551		// 		.siblings('li')
1552		// 		.removeClass('active');
1553
1554		// 	self.closest('li').addClass('active');
1555
1556		// 	self.closest('.filter-dropdown').slideUp(200);
1557
1558		// 	self
1559		// 		.closest('.filter-dropdown').siblings('.filter-label').first()
1560		// 		.text(( self.attr('data-filter-option-text') || self.text() )); //change the text;
1561				
1562
1563		// 	if(filterValue == '#'){
1564
1565		// 		filterBlock.show();
1566		// 		window.location.hash = '';
1567		// 	}else{
1568		// 		// filterBlock
1569		// 		filterBlock.not('[data-filter-'+filterKey+'*="'+filterValue.replace('#','')+'"]').hide();
1570		// 		filterBlock.filter('[data-filter-'+filterKey+'*="'+filterValue.replace('#','')+'"]').show();
1571		// 		window.location.hash = filterValue;
1572
1573		// 	}
1574
1575		// 	if(!filterBlock.filter(':visible').length) {
1576		// 		blocksWrapper.after('<div class="filter-empty">'+ noResultsText +'</div>');
1577		// 	}
1578		// });
1579
1580		// //let the id in the window loaction filter
1581		// if($('body').hasClass('template-results') && window.location.hash !== '') {
1582		// 	$('.filter .filter-dropdown a[href="'+ window.location.hash +'"]').trigger('click');
1583		// }
1584
1585
1586		
1587
1588		// /* Common Optional Stuff: Parallax. :D
1589		// - NOTE: Make sure the elements you add the following attributes to DOES NOT HAVE transform styles. otherwise this will not work as it should.
1590		// - Add classes/Attrs to the following
1591		// 	- data-parallax-x => factor of how much parallax you want horizontally
1592		// 		- -250 makes it slowly scroll up
1593		// 		- 250 makes it slowly scroll down
1594		// 		- -500 makes it quickly scroll up
1595		// 		- 500 makes it quickly scroll down
1596		// 		- -10000 makes itscroll up on the speed of light
1597		// 		- 10000 makes it scroll down on the speed of light
1598		// 		- 0 does nothing
1599		// 	- data-parallax-y => factor of how much parallax you want vertically
1600		// 		- -250 makes it slowly scroll to the top
1601		// 		- 250 makes it slowly scroll to the bottom
1602		// 		- -500 makes it quickly scroll to the top
1603		// 		- 500 makes it quickly scroll to the bottom
1604		// 		- -10000 makes it scroll to the top on the speed of light
1605		// 		- 10000 makes it scroll to the bottom on the speed of light
1606		// 		- 0 does nothing
1607		// 	//optional
1608		// 		- data-parallax-origin => factor of where in the viewport the element is in its original positions. set at .5 by default
1609		// 			- .5 will return element in its original position when it is in the vertical center of the viewport view
1610		// 			- 0 will return element in its original position when it is in the top of the viewport view
1611		// 			- .99 will return element in its original position when it peeks a little bit in the bottom of the viewport
1612
1613		// 		- data-parallax-pad => how deep outside the viewport you want to start the parallax early so it doesnt start jumping around or parallaxing too late
1614		// 			- .5 will start parallaxing when the element is half the viewport's height away before it is in view
1615		// 			- 0 will start parallaxing when the element is in view
1616		// 			- 1 will start parallaxing when the element is the viewport's height away before it is in view
1617		// -------------------------------------------------------------------------------- */
1618
1619		
1620		// function doParallax(){
1621			
1622		// 	const
1623		// 		scrollTop = window.scrollY, //yes
1624		// 		viewportOffset = window.pageYOffset, //yes
1625		// 		viewportHeight = window.innerHeight, //yes
1626		// 		documentHeight = document.documentElement.offsetHeight, // yes
1627		// 		documentTop = document.documentElement.clientTop, // yes
1628		// 		parallaxers = document.querySelectorAll('[data-parallax-y],[data-parallax-x],[data-parallax-custom]')
1629		// 		;
1630
1631
1632		// 	if(!parallaxers) return;
1633
1634		// 	parallaxers.forEach((parallaxer) => {
1635
1636
1637
1638		// 		parallaxer.style.transform = '';
1639		// 		parallaxer.style.setProperty('--parallax-calculation','0');
1640
1641			
1642		// 		if(!isTouchBr()){
1643
1644		// 			const
1645		// 				height = parallaxer.offsetHeight,
1646		// 				offset = parallaxer.getBoundingClientRect().top + viewportOffset - documentTop, //¯\_(ツ)_/¯
1647		// 				paraVX = !isNaN( parseFloat(parallaxer.getAttribute("data-parallax-x")) )
1648		// 					? parseFloat(parallaxer.getAttribute("data-parallax-x"))
1649		// 					: 0,
1650		// 				paraVY = !isNaN( parseFloat(parallaxer.getAttribute("data-parallax-y")) )
1651		// 					? parseFloat(parallaxer.getAttribute("data-parallax-y"))
1652		// 					: 0,
1653		// 				paraVOrigin = !isNaN( parseFloat(parallaxer.getAttribute("data-parallax-origin")) )
1654		// 					? parseFloat(parallaxer.getAttribute("data-parallax-origin"))
1655		// 					: .5,
1656		// 				parallaxPad = !isNaN( parseFloat(parallaxer.getAttribute("data-parallax-pad")) )
1657		// 					? parseFloat(parallaxer.getAttribute("data-parallax-pad"))
1658		// 					: .5;
1659							
1660		// 			const parallaxStart = scrollTop + (viewportHeight * (1 + parallaxPad)) >= 0
1661		// 				? scrollTop + (viewportHeight * (1 + parallaxPad))
1662		// 				: 0;
1663		// 			const parallaxEnd = scrollTop - (viewportHeight * parallaxPad) <= documentHeight
1664		// 				? scrollTop - (viewportHeight * parallaxPad)
1665		// 				: documentHeight;
1666	
1667		// 			const scrollOffset = ( (viewportHeight * paraVOrigin) - (height * paraVOrigin));
1668		// 			const calcedTransform = ( ((scrollTop - offset) + scrollOffset) / viewportHeight );
1669					
1670					
1671		// 			const x = Math.round(calcedTransform * paraVX);
1672		// 			const y = Math.round(calcedTransform * paraVY);
1673		
1674					
1675		// 			if (parallaxStart > offset && offset + height > parallaxEnd) {
1676		// 				if(!parallaxer.hasAttribute('data-parallax-custom')) {
1677		// 					parallaxer.style.transform = "translateX("+ x + "px)" + "translateY(" +y + "px)";
1678		// 				}
1679		// 				parallaxer.style.setProperty('--parallax-calculation',calcedTransform.toFixed(3));
1680		// 			}
1681		// 		}
1682
1683		// 	});
1684		// }
1685		// doParallax();
1686		// window.addEventListener('scroll', doParallax);
1687
1688
1689
1690		
1691		/* .table-wrapper Add a table-wrapper class around tables for better management of horizontal scrolls
1692		-------------------------------------------------------------------------------- */
1693		$('.content > table, .content > *:not(.table) table').each(function(){
1694			console.log('a table was wrapped');
1695			$(this).wrap('<div class="table-wrapper" />');
1696		});
1697
1698
1699
1700
1701
1702
1703		/* Run Functions on Resize for sliders consitency
1704		-------------------------------------------------------------------------------- */
1705
1706		let resizeTimerInternal;
1707		$(window).on('resize', function () {
1708			clearTimeout(resizeTimerInternal);
1709
1710			resizeTimerInternal = setTimeout(function () {
1711				//add functions here to fire on resize eg. setupSliders()
1712				setupSliders();
1713				setupGridSliders();
1714				checkHeader();
1715			}, 100);
1716		});
1717
1718
1719
1720
1721
1722
1723		/* Run Functions on orientation change too
1724		-------------------------------------------------------------------------------- */
1725		$(window).on('orientationchange', function () {
1726			$(window).trigger('resize');
1727		});
1728
1729
1730
1731
1732
1733
1734		/* End Document Ready
1735		 -------------------------------------------------------------------------------- */
1736	});
1737
1738	/* ------------------- JS to run after all content (html + images) is completely loaded ------------------- */
1739	
1740	$(window).on('load', function () {
1741		
1742		
1743		/*
1744		Catch elements, animations, wistia videos, etc. That are already above the fold
1745		-------------------------------------------------------------------------------- */
1746		$(window).trigger('scroll');
1747		// $(window).trigger('resize');
1748		
1749	});
1750	
1751	
1752	/* ------------------- Vanilla fixes ------------------- */
1753	window.addEventListener('load', () => {
1754		
1755		/* Removes scripts or styles that do not help. ie Ngage svg overrides. not cool ngage.
1756		Note: You will only need this usually post-launch. Do not mess with this script while you are building the site or it is still in staging environment.
1757		url => string. specific and exact url of the styles/scripts that you want to remove: eg: 'https://messenger.ngageics.com/api/customscript/getscript?id=13-38-69-150-245-204-30-134&scriptType=0'
1758		-------------------------------------------------------------------------------- */
1759		function removeScript(url) {
1760			if(!url) return;
1761
1762
1763			const unwanted = document.querySelector(
1764				`link[href="${url}"]`
1765			);
1766			if (unwanted) {
1767				unwanted.remove();
1768			};
1769		}
1770
1771		window.removeScript = removeScript;
1772
1773		// example of how to use
1774		// removeScript('https://script-that-messes-with-the-very-cute-styles-this-site-has-or-something-with-the-same-energy.com/style.css');
1775	});
1776
1777})(window,jQuery);

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.