PageSourceSearch

https://murrietafamilypethospital.com/themes/website/assets/js/theme.js?v.f6cdec

js murrietafamilypethospital.com collected 2026-10-04 21:30:29 UTC 40,026 bytes, 1,327 lines download raw bytes

1// page init
2;(function () {
3	'use strict';
4	var requestAnimationFrame = window.requestAnimationFrame ||
5		window.mozRequestAnimationFrame ||
6		window.webkitRequestAnimationFrame ||
7		window.msRequestAnimationFrame ||
8		function (f) {
9			return setTimeout(f, 17)
10		};
11
12	var cancelAnimationFrame = window.cancelAnimationFrame ||
13		window.mozCancelAnimationFrame ||
14		function (requestId) {
15			clearTimeout(requestId);
16		};
17	/**
18	 * Property Decorator constant
19	 * @param value
20	 * @returns {{enumerable: boolean, value: *}}
21	 */
22
23	function constant(value) {
24		return {
25			enumerable: true,
26			value: value
27		};
28	}
29
30	function mutable(value) {
31		return {
32			enumerable: true,
33			writable: true,
34			value: value
35		};
36	}
37
38	/**
39	 * Property Decorator Get/Set
40	 * @param getter
41	 * @param setter
42	 * @returns {{enumerable: boolean, get: *, set: *}}
43	 */
44	function getterSetter(getter, setter) {
45		return {
46			enumerable: true,
47			get: getter,
48			set: setter
49		};
50	}
51
52	function abstractMethod() {
53		throw new Error('This method has not been configured!');
54	}
55
56	/**
57	 * @param $ {JQueryStatic}
58	 */
59	jQuery(document).ready(function ($) {
60		var $body = $('body'),
61			$window = $(window),
62			$noPlace = $('<span></span>'),
63			noPlace = $noPlace.get(0);
64		var $contactForm = $('.contactform').first();
65
66		function throttleResize(callback) {
67			var id = 0;
68
69			function throttle() {
70				cancelAnimationFrame(id);
71				id = requestAnimationFrame(callback);
72			}
73			return {
74				start: function () {
75					$window.on('resize', throttle);
76				},
77				stop: function () {
78					$window.off('resize', throttle);
79					cancelAnimationFrame(id);
80					id = 0;
81				}
82			};
83		}
84
85		function scrollTo($el) {
86			return function () {
87				var $moduleSticky = $('.ple_module_sticky'), moduleStickyHeight = 0;
88				if($moduleSticky.length) $moduleSticky.each(function() { moduleStickyHeight += $(this).outerHeight(true); });
89
90				$('html, body').animate({
91					scrollTop: $el.offset().top - moduleStickyHeight
92				}, 'slow');
93			};
94		}
95
96		function getPLESection($target) {
97			return $target.closest('.section[data-control="section"]')
98		}
99
100		/**
101		 * @param {HTMLElement} child
102		 * @param {Element} container
103		 * @returns {Number}
104		 */
105		function absoluteOffsetFrom(child, container) {
106			var total = 0;
107			for (
108				var currentChild = child; currentChild && currentChild !== container && container.contains(currentChild); currentChild = currentChild.offsetParent
109			) {
110				total += currentChild.offsetTop;
111			}
112			return total;
113		}
114
115		function positionOnSection($menuBlock) {
116			var menuBlock = $menuBlock.get(0),
117				$sectionBlock = getPLESection($menuBlock),
118				sectionBlock = $sectionBlock.get(0) || noPlace;
119			return function () {
120				var relativeParent = menuBlock.offsetParent;
121				$menuBlock.css({
122					width: $body.width() + 'px',
123					left: -relativeParent.getBoundingClientRect().left,
124					top: $sectionBlock.outerHeight() - absoluteOffsetFrom(relativeParent, sectionBlock)
125				});
126			}
127		}
128
129		/**
130		 * use common script for group menu option
131		 * replace the global scope nav menu variables
132		 * prepare the menu and add the more button
133		*/
134		function groupNavMoreButton($el) {
135			menuHolder = $el;
136			menu = $el.find('.more_nav');
137			currentMenu = menu;
138			currentMenuWidth = menuHolder.outerWidth(true);
139			menuChildrenCount = currentMenu.children().length;
140			origMenuContent = '';
141			moreButton = $('<li class="navigation__item navigation__item--default has-drop-down more"> <a href="#" class="navigation__item--link">More</a> <ul class="navigation__list navigation__list--sub"></ul> </li>');
142			allMenus = [];
143			menuPrepare();
144			addMoreButton();
145		}
146
147		(function NavigationLayoutA() {
148			var expandedClass = 'navigation-open',
149				megaMenuClass = 'mega-menu',
150				expandedSelector = '.' + expandedClass;
151			$('.component.navigation .navigation-a').each(function (index, navEl) {
152				new DesktopMenu(navEl);
153			});
154
155			/**
156			 * @param element {Element}
157			 * @constructor
158			 */
159			function DesktopMenu(element) {
160				var dis = this;
161				var watchingBody = false;
162				this.el = element;
163				/**
164				 * @type {jQuery}
165				 */
166				this.$el = $(element);
167				// call groupNavMoreButton() before manipulation
168				this.$el.data("more-button") === 1 ? groupNavMoreButton(this.$el) : '';
169				this.$ul = this.$el.children('ul:first-child');
170				var $navItems = this.$el.children('ul').children('li');
171				var focusTree = {
172					prev: function ($a) {
173						$a.parent('li').prev('li').children('a').focus();
174					},
175					next: function ($a) {
176						$a.parent('li').next('li').children('a').focus();
177					},
178					parent: function ($a) {
179						$a.parent('li').parent('ul').siblings('a').focus();
180					},
181					child: function ($a) {
182						$a.siblings('ul').find('> li:first-child > a:first-child').focus();
183					}
184				};
185
186				function isTopRow(el) {
187					return dis.$ul.children('li').children('a').is(el);
188				}
189				var keyboardNav = {
190					ArrowDown: function (event, $a) {
191						if (isTopRow(event.target)) {
192							focusTree.child($a);
193						} else {
194							focusTree.next($a);
195						}
196					},
197					ArrowUp: function (event, $a) {
198						if (!isTopRow(event.target)) {
199							focusTree.prev($a);
200						}
201					},
202					ArrowLeft: function (event, $a) {
203						if (isTopRow(event.target)) {
204							focusTree.prev($a);
205						} else {
206							focusTree.parent($a);
207						}
208					},
209					ArrowRight: function (event, $a) {
210						if (isTopRow(event.target)) {
211							focusTree.next($a)
212						} else {
213							focusTree.child($a);
214						}
215					}
216				};
217
218
219				this.$el.on('keydown', '.navigation__item--link:focus', function kbEventRouter(event) {
220					keyboardNav.hasOwnProperty(event.key) && keyboardNav[event.key](event, $(event.target));
221				});
222
223
224				this.subMenuR = $navItems.toArray().map(function (li) {
225					return new((li.classList.contains(megaMenuClass)) ?
226						DesktopSubMenuMegaMenu :
227						DesktopSubMenuItemDefault
228					)(li, dis);
229				});
230
231				function offClick(evt) {
232					if (!dis.el.contains(evt.target)) {
233						dis.closeAll();
234					}
235				}
236
237				this.watchAfterOpen = function () {
238					if (!watchingBody) {
239						watchingBody = true;
240						$body.on('click touchstart', offClick);
241					}
242				};
243
244				this.ignoreAfterClose = function () {
245					if (watchingBody) {
246						watchingBody = false;
247						$body.off('click touchstart', offClick);
248					}
249				};
250
251			}
252
253			Object.defineProperties(DesktopMenu, {});
254			Object.defineProperties(DesktopMenu.prototype, {
255				hasFocus: getterSetter(function () {
256					return Boolean(this.$el.find('a:focus').length);
257				}),
258				expandedClass: constant(expandedClass),
259				expandedSelector: constant(expandedSelector),
260				markOpened: constant(function () {
261					this.watchAfterOpen();
262				}),
263				closeAll: constant(function () {
264					this.$el.find(this.expandedSelector).removeClass(this.expandedClass);
265					this.ignoreAfterClose();
266				}),
267				watchAfterOpen: mutable(abstractMethod),
268				ignoreAfterClose: mutable(abstractMethod)
269			});
270
271
272			/**
273			 * @param element {HTMLLIElement}
274			 * @param root {DesktopMenu}
275			 * @param parent {=DesktopSubMenuItem}
276			 * @constructor
277			 */
278			function DesktopSubMenuItemDefault(element, root, parent) {
279				var dis = this;
280				this.root = root;
281				this.parent = parent || null;
282				this.el = element;
283				this.$el = $(element);
284				this.$a = this.$el.children('a');
285				this.$ul = this.$el.children('ul');
286
287
288				this.$a.on('focus', function () {
289					dis.clearExpand();
290					dis.expand();
291				});
292				this.$ul.find('a').last().on('blur', function () {
293					dis.contract();
294				});
295
296				if (this.$ul.length) {
297					this.$el.hover(
298						function over() {
299							dis.expand();
300						},
301						function out(evt) {
302							dis.contract();
303						}
304					);
305					this.$a.on('touchend', function (evt) {
306						if (!dis.isExpanded) {
307							dis.clearExpand();
308							dis.expand();
309							return false;
310						}
311					});
312
313					this.subMenuR = this.$ul.children('li').toArray().map(function (li) {
314						return new DesktopSubMenuItemDefault(li, root, dis);
315					});
316				} else {
317					this.subMenuR = [];
318				}
319
320			}
321			Object.defineProperties(DesktopSubMenuItemDefault, {});
322			Object.defineProperties(DesktopSubMenuItemDefault.prototype, {
323				expandedClass: constant(expandedClass),
324				expandedSelector: constant(expandedSelector),
325				isExpanded: getterSetter(function () {
326					return this.el.classList.contains(this.expandedClass);
327				}),
328				expand: constant(function () {
329					this.root.markOpened();
330					// Set submenu visible if there is one
331					this.$el.addClass(this.expandedClass);
332					// echo up the tree
333					this.$a.parents('li').addClass(this.expandedClass);
334				}),
335				contract: constant(function () {
336					this.$el.removeClass(this.expandedClass)
337						.find(this.expandedSelector).removeClass(this.expandedClass);
338				}),
339				clearExpand: constant(function () {
340					this.root.closeAll();
341				})
342			});
343
344			/**
345			 * @param element {HTMLLIElement}
346			 * @param root {DesktopMenu}
347			 * @param parent {=DesktopSubMenuItem}
348			 * @constructor
349			 */
350			function DesktopSubMenuMegaMenu(element, root, parent) {
351				var dis = this;
352				this.root = root;
353				this.parent = parent || null;
354				this.el = element;
355				this.$el = $(element);
356				this.$a = this.$el.children('a');
357				this.$ul = this.$el.children('ul');
358				this.subMenuR = [];
359
360				this.resizeWatcher = throttleResize(function () {
361					dis.correctPosition();
362				});
363
364				function revealForKBNav() {
365					dis.clearExpand();
366					dis.expand();
367				}
368				this.$a.on('focus', revealForKBNav);
369
370				this.$ul.on('focus', 'a', revealForKBNav);
371				this.$ul.find('a').last().on('blur', function () {
372					dis.contract();
373				});
374
375
376				if (this.$ul.length) {
377					this.$el.hover(
378						function over() {
379							dis.expand();
380						},
381						function out(evt) {
382							dis.contract();
383						}
384					);
385					this.$a.on('touchend', function (evt) {
386						if (!dis.isExpanded) {
387							dis.clearExpand();
388							dis.expand();
389							return false;
390						}
391					});
392				}
393
394			}
395
396			Object.defineProperties(DesktopSubMenuMegaMenu, {});
397			Object.defineProperties(DesktopSubMenuMegaMenu.prototype, {
398				expandedClass: constant(expandedClass),
399				expandedSelector: constant(expandedSelector),
400				isExpanded: getterSetter(function () {
401					return this.el.classList.contains(this.expandedClass);
402				}),
403				expand: constant(function () {
404					this.root.markOpened();
405					// Set submenu visible if there is one
406					this.$el.addClass(this.expandedClass);
407					this.correctPosition();
408					this.resizeWatcher.start();
409				}),
410				correctPosition: constant(function () {
411					this.$ul.css({
412						width: $body.outerWidth() + 'px',
413						left: -(this.$ul.offsetParent().get(0) || $body).getBoundingClientRect().left
414					});
415				}),
416				contract: constant(function () {
417					this.$el.removeClass(this.expandedClass);
418					this.resizeWatcher.stop();
419				}),
420				clearExpand: constant(function () {
421					this.root.closeAll();
422				}),
423				resizeWatcher: mutable(null)
424			});
425
426		})();
427
428		(function NavigationLayoutB() {
429			function NavigationB(nav) {
430				var watchingBody = false,
431					dis = this;
432				var resizeWatcher = throttleResize(function () {
433					dis.correctPosition();
434				});
435
436				/**
437				 * @type {jQuery}
438				 */
439				this.$el = $(nav);
440				this.$button = this.$el.children(NavigationB.buttonSelector).first();
441				this.button = this.$button.get(0);
442				this.$buttonIcon = this.$button.children(NavigationB.buttonIconSelector).first();
443				this.$buttonText = this.$button.children(NavigationB.buttonTextSelector).first();
444				this.$navMenu = this.$el.children(NavigationB.navMenuSelector).first();
445
446				function offClick(evt) {
447					if (!nav.contains(evt.target)) {
448						dis.close();
449					}
450				}
451
452
453				this.$button.on('click', function (evt) {
454					dis.toggle();
455				});
456				this.watchAfterOpen = function () {
457					if (!watchingBody) {
458						watchingBody = true;
459						$body.on('click touchstart', offClick);
460						resizeWatcher.start();
461					}
462				};
463
464				this.ignoreAfterClose = function (evt) {
465					if (watchingBody) {
466						watchingBody = false;
467						$body.off('click touchstart', offClick);
468						resizeWatcher.stop();
469					}
470				};
471
472				Object.defineProperties(this, {
473					correctPosition: constant(positionOnSection(this.$navMenu))
474				});
475			}
476			Object.defineProperties(NavigationB, {
477				buttonSelector: constant('.navigation__button'),
478				buttonTextSelector: constant('.navigation__button--text'),
479				buttonIconSelector: constant('.navigation__button--icon'),
480				buttonIconActiveCSS: constant('is-active'),
481				navMenuSelector: constant('.navigation__menu--container'),
482				dropDownActiveCss: constant('navigation-open'),
483				slideDownClass: constant('slideDown'),
484				fadeOutClass: constant('fadeOut')
485			});
486			Object.defineProperties(NavigationB.prototype, {
487				$el: mutable($noPlace),
488				$button: mutable($noPlace),
489				button: mutable(noPlace),
490				$buttonIcon: mutable($noPlace),
491				$buttonText: mutable($noPlace),
492				$navMenu: mutable($noPlace),
493				state: mutable(false),
494				busy: mutable(false),
495				open: constant(function () {
496					var dis = this;
497					if (!this.state && !this.busy) {
498						this.state = true;
499						this.busy = true;
500						this.watchAfterOpen();
501						this.$button.attr('ariaExpanded', 'true');
502						this.$buttonIcon.addClass(NavigationB.buttonIconActiveCSS);
503						this.$buttonText.text(this.$buttonText.data('closeDescription'));
504						this.$navMenu.addClass(NavigationB.dropDownActiveCss);
505						this.$navMenu.addClass(NavigationB.slideDownClass);
506						this.button.disabled = true;
507						this.$navMenu.one("animationend animationcancel", function () {
508							dis.$navMenu.focus();
509							dis.$navMenu.removeClass(NavigationB.slideDownClass);
510							dis.busy = false;
511							dis.button.disabled = false;
512						});
513						this.correctPosition();
514					}
515				}),
516				close: constant(function () {
517					var dis = this;
518					if (this.state && !this.busy) {
519						this.state = false;
520						this.busy = true;
521						this.ignoreAfterClose();
522						this.$buttonIcon.removeClass(NavigationB.buttonIconActiveCSS);
523						this.$buttonText.text(this.$buttonText.data('openDescription'));
524						this.$button.attr('ariaExpanded', 'false');
525						this.$navMenu.addClass(NavigationB.fadeOutClass);
526						this.button.disabled = true;
527						this.$navMenu.one("animationend animationcancel", function () {
528							dis.$navMenu.removeClass(NavigationB.fadeOutClass);
529							dis.$navMenu.removeClass(NavigationB.dropDownActiveCss);
530							dis.busy = false;
531							dis.button.disabled = false;
532						});
533					}
534				}),
535				toggle: constant(function () {
536					if (this.state) {
537						this.close();
538					} else {
539						this.open();
540					}
541				}),
542				watchAfterOpen: mutable(Function.prototype),
543				ignoreAfterClose: mutable(Function.prototype)
544			});
545
546			function ExpandableLink(li) {
547				var dis = this;
548				/**
549				 * @type {JQuery}
550				 */
551				this.$el = $(li);
552				this.$el.data(ExpandableLink.dataAttribute, this);
553				this.$siblings = this.$el.siblings(ExpandableLink.identifier);
554				this.$a = this.$el.children(ExpandableLink.linkSelector).first();
555				this.$ul = this.$el.children(ExpandableLink.subMenuSelector).first();
556				this.$button = this.$el.children(ExpandableLink.expansionSelector).first();
557				this.$buttonIcon = this.$button.children(ExpandableLink.expansionIconSelector).first();
558				this.$buttonText = this.$button.children(ExpandableLink.expansionTextSelector).first();
559
560				this.$button.on('click', function () {
561					dis.toggle();
562				});
563			}
564			Object.defineProperties(ExpandableLink, {
565				expandedClass: constant('is-active'),
566				identifier: constant('.navigation__item.has-sub-items'),
567				linkSelector: constant('.navigation__item--link'),
568				expansionSelector: constant('.navigation__item--expand'),
569				expansionIconSelector: constant('.icon'),
570				expansionTextSelector: constant('.sr-only'),
571				subMenuSelector: constant('.navigation__list'),
572				dataAttribute: constant('ExpandableLink'),
573				closeIconClass: constant('icon-minus'),
574				openIconClass: constant('icon-plus')
575			});
576			Object.defineProperties(ExpandableLink.prototype, {
577				$el: mutable($noPlace),
578				$a: mutable($noPlace),
579				$siblings: mutable($noPlace),
580				$button: mutable($noPlace),
581				$buttonIcon: mutable($noPlace),
582				$buttonText: mutable($noPlace),
583				state: mutable(false),
584				expand: constant(function () {
585					if (!this.state) {
586						this.state = true;
587						this.$button.prop('title', this.closeDescription);
588						this.$buttonText.text(this.closeDescription);
589						this.$buttonIcon.removeClass(ExpandableLink.openIconClass)
590							.addClass(ExpandableLink.closeIconClass);
591						this.$el.addClass(ExpandableLink.expandedClass);
592						this.$siblings.each(function () {
593							/**
594							 * @type {ExpandableLink}
595							 */
596							var expandableLink = $.data(this, ExpandableLink.dataAttribute);
597							if (expandableLink) {
598								expandableLink.contract();
599							}
600						});
601					}
602				}),
603				contract: constant(function () {
604					if (this.state) {
605						this.state = false;
606						this.$button.prop('title', this.openDescription);
607						this.$buttonText.text(this.openDescription);
608
609						this.$buttonIcon.removeClass(ExpandableLink.closeIconClass)
610							.addClass(ExpandableLink.openIconClass);
611						this.$el.removeClass(ExpandableLink.expandedClass);
612					}
613				}),
614				toggle: constant(function () {
615					if (this.state) {
616						this.contract();
617					} else {
618						this.expand();
619					}
620				}),
621				openDescription: mutable('View more'),
622				closeDescription: mutable('View less')
623			});
624
625			var navB = $('.component.navigation .navigation-b');
626			navB.each(function () {
627				new NavigationB(this);
628			});
629			navB.find(ExpandableLink.identifier).each(function () {
630				new ExpandableLink(this);
631			});
632		})();
633
634		(function NavigationLayoutC() {
635			var navC = $('.component.navigation .navigation-c');
636
637			function NavigationC(nav) {
638				var watchingBody = false,
639					dis = this;
640				var resizeWatcher = throttleResize(function () {
641					dis.correctPosition();
642				});
643				/**
644				 * @type {jQuery}
645				 */
646				this.$el = $(nav);
647				this.$button = this.$el.children(NavigationC.buttonSelector).first();
648				this.button = this.$button.get(0);
649				this.$buttonIcon = this.$button.children(NavigationC.buttonIconSelector).first();
650				this.$buttonText = this.$button.children(NavigationC.buttonTextSelector).first();
651				this.$navMenu = this.$el.children(NavigationC.navMenuSelector).first();
652
653				function offClick(evt) {
654					if (!nav.contains(evt.target)) {
655						dis.close();
656					}
657				}
658
659				this.$button.on('click', function (evt) {
660					dis.toggle();
661				});
662				this.watchAfterOpen = function () {
663					if (!watchingBody) {
664						watchingBody = true;
665						$body.on('click touchstart', offClick);
666						resizeWatcher.start();
667					}
668				};
669
670				this.ignoreAfterClose = function (evt) {
671					if (watchingBody) {
672						watchingBody = false;
673						$body.off('click touchstart', offClick);
674						resizeWatcher.stop();
675					}
676				};
677				Object.defineProperties(this, {
678					correctPosition: constant(positionOnSection(this.$navMenu))
679				});
680			}
681			Object.defineProperties(NavigationC, {
682				buttonSelector: constant('.navigation__button'),
683				buttonTextSelector: constant('.navigation__button--text'),
684				buttonIconSelector: constant('.navigation__button--icon'),
685				buttonIconActiveCSS: constant('is-active'),
686				navMenuSelector: constant('.navigation__menu--container'),
687				dropDownActiveCss: constant('navigation-open'),
688				slideDownClass: constant('slideDown'),
689				fadeOutClass: constant('fadeOut')
690			});
691			Object.defineProperties(NavigationC.prototype, {
692				$el: mutable($noPlace),
693				$button: mutable($noPlace),
694				button: mutable(noPlace),
695				$buttonIcon: mutable($noPlace),
696				$buttonText: mutable($noPlace),
697				$navMenu: mutable($noPlace),
698				state: mutable(false),
699				busy: mutable(false),
700				open: constant(function () {
701					var dis = this;
702					if (!this.state && !this.busy) {
703						this.state = true;
704						this.busy = true;
705						this.watchAfterOpen();
706						this.$button.attr('ariaExpanded', 'true');
707						this.$buttonIcon.addClass(NavigationC.buttonIconActiveCSS);
708						this.$buttonText.text(this.$buttonText.data('closeDescription'));
709						this.$navMenu.addClass(NavigationC.dropDownActiveCss);
710						this.$navMenu.addClass(NavigationC.slideDownClass);
711						this.button.disabled = true;
712						this.$navMenu.one("animationend animationcancel", function () {
713							dis.$navMenu.focus();
714							dis.$navMenu.removeClass(NavigationC.slideDownClass);
715							dis.busy = false;
716							dis.button.disabled = false;
717						});
718						this.correctPosition()
719					}
720				}),
721				close: constant(function () {
722					var dis = this;
723					if (this.state && !this.busy) {
724						this.state = false;
725						this.busy = true;
726						this.ignoreAfterClose();
727						this.$buttonIcon.removeClass(NavigationC.buttonIconActiveCSS);
728						this.$buttonText.text(this.$buttonText.data('openDescription'));
729						this.$button.attr('ariaExpanded', 'false');
730						this.$navMenu.addClass(NavigationC.fadeOutClass);
731						this.button.disabled = true;
732						this.$navMenu.one("animationend animationcancel", function () {
733							dis.$navMenu.removeClass(NavigationC.fadeOutClass);
734							dis.$navMenu.removeClass(NavigationC.dropDownActiveCss);
735							dis.busy = false;
736							dis.button.disabled = false;
737						});
738					}
739				}),
740				toggle: constant(function () {
741					if (this.state) {
742						this.close();
743					} else {
744						this.open();
745					}
746				}),
747				watchAfterOpen: mutable(Function.prototype),
748				ignoreAfterClose: mutable(Function.prototype)
749			});
750
751			navC.each(function () {
752				new NavigationC(this);
753			});
754		})();
755
756
757		(function Searchbar() {
758			var searchbar = $('.searchbar-a');
759
760			function SearchbarA(sbar) {
761				var watchingBody = false,
762					dis = this;
763				var resizeWatcher = throttleResize(function () {
764					dis.correctPosition();
765				});
766				/**
767				 * @type {jQuery}
768				 */
769				this.$el = $(sbar);
770				this.$button = this.$el.find(SearchbarA.buttonSelector).first();
771				this.button = this.$button.get(0);
772				this.$closeButton = this.$el.find(SearchbarA.closeButtonSelector).first();
773				this.closeButton = this.$button.get(0);
774				this.$flyout = this.$el.find(SearchbarA.flyoutSelector).first();
775				this.$searchInput = this.$flyout.find(SearchbarA.searchInputSelector).first();
776
777				function offClick(evt) {
778					if (!sbar.contains(evt.target)) {
779						dis.close();
780					}
781				}
782
783				this.$button.on('click', function (evt) {
784					dis.toggle();
785				});
786				this.$closeButton.on('click', function (evt) {
787					dis.close();
788				});
789				this.watchAfterOpen = function () {
790					if (!watchingBody) {
791						watchingBody = true;
792						$body.on('click touchstart', offClick);
793						resizeWatcher.start();
794					}
795				};
796
797				this.ignoreAfterClose = function (evt) {
798					if (watchingBody) {
799						watchingBody = false;
800						$body.off('click touchstart', offClick);
801						resizeWatcher.stop();
802					}
803				};
804				Object.defineProperties(this, {
805					correctPosition: constant(positionOnSection(this.$flyout))
806				});
807			}
808			Object.defineProperties(SearchbarA, {
809				buttonSelector: constant('.searchbar-a__btnsearch'),
810				closeButtonSelector: constant('.searchbar-a__closeflyoutbtn'),
811				dropDownActiveCss: constant('searchbar-open'),
812				flyoutSelector: constant('.searchbar-a__flyout'),
813				searchInputSelector: constant('[name="query"]'),
814				slideDownClass: constant('slideDown'),
815				fadeOutClass: constant('fadeOut')
816			});
817			Object.defineProperties(SearchbarA.prototype, {
818				$el: mutable($noPlace),
819				$button: mutable($noPlace),
820				button: mutable(noPlace),
821				$closeButton: mutable($noPlace),
822				closeButton: mutable(noPlace),
823				$flyout: mutable($noPlace),
824				$searchInput: mutable($noPlace),
825				state: mutable(false),
826				busy: mutable(false),
827				open: constant(function () {
828					var dis = this;
829					if (!this.state && !this.busy) {
830						this.state = true;
831						this.busy = true;
832						this.watchAfterOpen();
833						this.$button.attr('ariaExpanded', 'true');
834						this.$flyout.addClass(SearchbarA.dropDownActiveCss);
835						this.$flyout.addClass(SearchbarA.slideDownClass);
836						this.button.disabled = true;
837						this.$flyout.one("animationend animationcancel", function () {
838							dis.$searchInput.focus();
839							dis.$flyout.removeClass(SearchbarA.slideDownClass);
840							dis.busy = false;
841							dis.button.disabled = false;
842						});
843						this.correctPosition();
844					}
845				}),
846				close: constant(function () {
847					var dis = this;
848					if (this.state && !this.busy) {
849						this.state = false;
850						this.busy = true;
851						this.ignoreAfterClose();
852						this.$button.attr('ariaExpanded', 'false');
853						this.$flyout.addClass(SearchbarA.fadeOutClass);
854						this.button.disabled = true;
855						this.$flyout.one("animationend animationcancel", function () {
856							dis.$flyout.removeClass(SearchbarA.fadeOutClass);
857							dis.$flyout.removeClass(SearchbarA.dropDownActiveCss);
858							dis.busy = false;
859							dis.button.disabled = false;
860						});
861					}
862				}),
863				toggle: constant(function () {
864					if (this.state) {
865						this.close();
866					} else {
867						this.open();
868					}
869				}),
870				watchAfterOpen: mutable(Function.prototype),
871				ignoreAfterClose: mutable(Function.prototype)
872			});
873
874			searchbar.each(function () {
875				new SearchbarA(this);
876			});
877		})();
878
879		// Provide a mobile view
880		(function MobileView($desktopContactForm) {
881			var $mobileSection;
882			/**
883			 * @typedef MobileSectionClusterItem
884			 * @property {JQuery} $el - Element to be inserted
885			 * @property {Node} source
886			 *
887			 * @type MobileSectionClusterItem[]*/
888			var mobileSectionCluster = [];
889			var x21MobileClass = 'x21-mobile-controls';
890			var $desktopNav = $('.section-navigation-mobile, .section-navigation-mobile--no-hide')
891				.find('.component.navigation')
892				.find('.navigation-a, .navigation-b, .navigation-c').first();
893			var $desktopPhone = $('.section-phone-mobile .phone__container').find('.phone__number').first();
894			var $desktopMap = $('.map__container').first();
895
896			if ([$desktopNav, $desktopPhone, $desktopContactForm, $desktopMap].every(function isEmpty($el) {
897					return $el.length === 0;
898				})) {
899				return;
900			}
901
902			if ($desktopNav.length) {
903
904				$mobileSection = $('<div class="' + x21MobileClass + ' d-md-none sticky-top"></div>').prependTo($body);
905
906				(function MmenuButton() {
907					var $mobileNav, $menuButton, mmenuAPI;
908					$mobileNav = $desktopNav.clone();
909
910					// Remove any buttons
911					$mobileNav.find('button').remove();
912
913					// Strip call classes
914					$mobileNav.removeClass().addClass('d-md-none').find('ul, li, a').removeClass();
915					$desktopNav.addClass('d-none d-md-block');
916
917					// Build the menu button
918					$menuButton = $(
919						'<button type="button" title="Show Navigation Menu">' + (
920							'<i aria-hidden="true" class="icon icon-bars"></i><span> Menu</span>') +
921						'</button>'
922					).appendTo($mobileSection);
923
924					// Initialize MMenu Plugin
925					$mobileNav.mmenu({
926						extensions: ['pagedim-black'],
927						counters: true,
928						navbars: [{
929							position: 'top',
930							content: ['prev', 'title', 'close']
931						}, {
932							position: 'top',
933							content: ['searchfield']
934						}]
935					});
936
937					mmenuAPI = $mobileNav.data('mmenu');
938
939					// Bind the menu button to the API
940					$menuButton.on('click', function () {
941						mmenuAPI.open();
942					});
943				})();
944			}
945
946			function mobileLinkTemplate(classSubName, description, icon, href) {
947				var $el = $('<div class="' + x21MobileClass + '__' + classSubName + '"></div>');
948				var $link = $('<a title="' + description + '" class="btn btn-link">' + (
949					'<i class="icon ' + icon + '" aria-hidden="true"></i>' +
950					'<span class="sr-only">' + description + '</span>'
951				) + '</a>').attr('href', href).appendTo($el);
952				return {
953					$el: $el,
954					$link: $link
955				};
956			}
957
958			if ($desktopPhone.length) {
959				mobileSectionCluster.push(((function PhoneLink($selector) {
960					var sectionId = getPLESection($selector).attr('id') || '';
961					// Valid separators are (-.), valid digits are 0-9
962					// See: //tools.ietf.org/html/rfc3966#section-3 'global-number-digits'
963					var tel = $selector.text().trim().replace(/([^0123456789\-.()])/g, '');
964					var template = mobileLinkTemplate('phone', 'Call', 'icon-phone', 'tel:+' + tel);
965					return {
966						$el: template.$el,
967						source: $selector.get(0)
968					};
969				})($desktopPhone)));
970			}
971
972			function mobileAnchorLink($selector, classSubName, description, icon) {
973				var sectionId = getPLESection($selector).attr('id') || '';
974				var template = mobileLinkTemplate(classSubName, description, icon, '#' + sectionId);
975				template.$link.on('click', scrollTo($selector));
976				return {
977					$el: template.$el,
978					source: $selector.get(0)
979				};
980			}
981
982			if ($desktopMap.length) {
983				mobileSectionCluster.push(mobileAnchorLink(
984					$desktopMap, 'location', 'Location', 'icon icon-location-arrow'
985				));
986			}
987
988			if ($desktopContactForm.length) {
989				mobileSectionCluster.push(mobileAnchorLink(
990					$desktopContactForm, 'contact-us', 'Contact Us', 'icon-envelope-o'
991				));
992			}
993
994			if (mobileSectionCluster.length) {
995				mobileSectionCluster.sort(function (a, b) {
996					return a.source.compareDocumentPosition(b.source) & Node.DOCUMENT_POSITION_PRECEDING ? 1 : -1;
997				}).reduce(function ($target, value) {
998					return $target.append(value.$el);
999				}, $('<div class="' + x21MobileClass + '__quick-links"></div>')).appendTo($mobileSection);
1000			}
1001		})($contactForm);
1002
1003		// Add Browserlock
1004		(function BrowserLock($target) {
1005			if ($target.length) {
1006				// Create ContactForm lock
1007				var $contactFormLock = $('<div>')
1008					.addClass('contactform-lock');
1009
1010				// Add ContactForm click event
1011				$contactFormLock.on('click', scrollTo($target));
1012
1013				// Draw browser lock containers, prepend to body
1014				var $lockContainer = $('<div>')
1015					.addClass('browser-lock')
1016					.append($contactFormLock);
1017
1018				$('body').prepend($lockContainer);
1019			}
1020		})($contactForm);
1021
1022		// Preview link fix
1023		(function cleanUpRedactorLinks() {
1024			// Check if we're in an iFrame or not (editor mode or preview link)
1025			if (self != top)
1026				return;
1027
1028			var link = $('link[rel=canonical]').attr('href');
1029			if (link != undefined) {
1030				var parts = link.split('/'),
1031					index = parts.indexOf('my.martindalenolo.com');
1032				if (index >= 0) {
1033					var siteId = parts[index + 1];
1034					if (!siteId)
1035						return;
1036
1037					var $links = $('div[data-component-name=editable] a[data-source-type=my-pages]');
1038					if ($links == undefined || $links.length == 0)
1039						return;
1040
1041					$links.each(function () {
1042						var currentLink = $(this).attr('href');
1043
1044						// Check for edge-case of absolute my-page
1045						var index = currentLink.split('/').indexOf(siteId);
1046						if (index >= 0)
1047							return;
1048
1049						var newLink = '/' + siteId + currentLink;
1050						$(this).attr('href', newLink);
1051					})
1052				}
1053			}
1054		})();
1055
1056		(function setBrowserlock() {
1057			var rawSettings = $('#ple-data-json').text();
1058			var settings = JSON.parse(rawSettings);
1059			var browserlockSettings = settings.fixedSection;
1060
1061			//#SMBWMGR-8501 this check can be removed after merging - /editor/merge_requests/1922
1062			if (typeof browserlockSettings !== 'undefined' && browserlockSettings !== null) {
1063
1064				var $browserLockContainer = $('#' + browserlockSettings.id).find('.ple__browserlock-modules');
1065				var $browserLockModules = $browserLockContainer.find('> .row .row');
1066
1067				if (browserlockSettings.spacing.space == 'custom' && browserlockSettings.spacing.offsetDistance && parseInt(browserlockSettings.spacing.offsetDistance) != NaN) {
1068					$browserLockModules.each(function (index, element) {
1069						$(element).css({
1070							marginBottom: browserlockSettings.spacing.offsetDistance
1071						});
1072					});
1073				}
1074
1075				if (browserlockSettings.placement.place != null) {
1076					switch (browserlockSettings.placement.place) {
1077						case 'center-right':
1078							$browserLockContainer.css({
1079								top: '50%',
1080								transform: 'translateY(-50%)'
1081							});
1082							break;
1083
1084						case 'bottom-right':
1085							$browserLockContainer.css({
1086								top: 'auto'
1087							});
1088
1089							if (parseInt(browserlockSettings.placement.offsetDistance) != NaN && !browserlockSettings.placement.useDefaultOffset) {
1090								$browserLockContainer.css({
1091									bottom: browserlockSettings.placement.offsetDistance
1092								});
1093							}
1094							break;
1095
1096						case 'top-right':
1097						default:
1098							if (parseInt(browserlockSettings.placement.offsetDistance) != NaN && !browserlockSettings.placement.useDefaultOffset) {
1099								$browserLockContainer.css({
1100									top: browserlockSettings.placement.offsetDistance
1101								});
1102							}
1103							break;
1104					}
1105				}
1106			} else {
1107				console.log("browserlock Settings is undefinded")
1108			}
1109		})();
1110
1111		(function backToTop() {
1112			var $bttButton = $('.ple__back-to-top');
1113			var activeClass = 'active';
1114			var showPoint = 400;
1115
1116			$bttButton.on('click', function (event) {
1117				event.preventDefault();
1118
1119				$([document.documentElement, document.body]).animate({
1120					scrollTop: 0
1121				}, 1000);
1122			});
1123
1124			$(window).scroll(function () {
1125				var window_x = $(window).scrollTop();
1126				if (window_x >= showPoint) {
1127					$bttButton.addClass(activeClass);
1128				} else {
1129					$bttButton.removeClass(activeClass);
1130				}
1131			});
1132		})();
1133
1134		(function scrollToContactForm() {
1135			var $ctaEl = $('.scrollToContactForm .cta__button'), $target = $(".contactFormSection");
1136			$ctaEl.each(function() { $(this).removeAttr("href"); $(this).on('click', scrollTo($target));});
1137    	})();
1138
1139		(function featuredBlocksEqualizeHeights() {
1140			var maxHeight = 0,
1141				$fbContainer = $('.featuredblocks-grid-e'),
1142				$fbItems = $fbContainer.find('.featuredblock__item');
1143
1144			$fbItems.children().height('auto').each(function () {
1145				maxHeight = Math.max(maxHeight, $(this).outerHeight(true));
1146			}).height(maxHeight);
1147
1148			$fbItems.css('min-height', maxHeight + 'px');
1149			$fbContainer.addClass('blockTransitionNone');
1150		})();
1151
1152		(function objectFitIEFix() {
1153			var isIE = /*@cc_on!@*/false || !!document.documentMode, // Internet Explorer 6-11
1154			isEdge = !isIE && !!window.StyleMedia; // Edge 20+
1155			// Check if Internet Explorer 6-11 OR Edge 20+
1156			if(isIE || isEdge) {
1157				var $container = $('.wrap__where_is_your_pain').find(".image"),
1158					imgUrl = $container.find("img").prop("src");
1159				if (imgUrl) {
1160				  $container.css("backgroundImage", 'url(' + imgUrl + ')').addClass("custom-object-fit");
1161				}
1162			}
1163		})();
1164
1165
1166
1167		(function mobileHeader() {
1168
1169			function mobileHeaderInit() {
1170
1171				var $mhContainer = $('.mobileHeader-container'),
1172				mhHeaight = $mhContainer.height(),
1173				$navButton = $('#mobileHeaderNavBtn'),
1174				$navMenu = $('#mobileHeaderNav'),
1175				$homeIcon = $(".mobileHeader-homeIcon"),
1176				$formIcon = $(".formIconLink"),
1177				$mapIcon = $(".locIconLink"),
1178				$phoneIcon = $(".phoneIconLinkExpand"),
1179				$mapContainer = $('.map__container').first(),
1180				$formContainer = $('.form__container').first(),
1181				$locList = $('.location-list'),
1182				$pleMSticky = $(".ple_module_sticky"),
1183				navAPI;
1184
1185				// if there is no form module in the view target the contactform module
1186				if(!$formContainer.length) $formContainer = $('.contactform__container').first();
1187
1188				// if sticky module is present set top space to the first elem for the mobileHeader
1189				if ($pleMSticky.length) {
1190					var $pleMStickEl = $pleMSticky.first().find('.container');
1191					$(window).resize(function (){
1192						mhHeaight = $mhContainer.height();
1193						$pleMStickEl.css('padding-top', mhHeaight);
1194					});
1195				}
1196
1197				if($navMenu.children().length) {
1198				// init mMenu
1199				$navMenu.mmenu({
1200					extensions: ['pagedim-black'],
1201					counters: true,
1202					navbars: [{
1203					position: 'top',
1204					content: ['prev', 'title', 'close']
1205					}]
1206				});
1207				// bind menu button 
1208				navAPI = $navMenu.data('mmenu');
1209				$navButton.on('click', function () {
1210					navAPI.open();
1211				});
1212				}
1213
1214				// handle click events for the icons
1215				($formContainer.length) ? $formIcon.click(scrollToEl($formContainer)) : $formIcon.fadeOut();
1216				($mapContainer.length) ? $mapIcon.click(scrollToEl($mapContainer)) : $mapIcon.fadeOut();
1217				$phoneIcon.click(function () { $locList.addClass("expand"); });
1218				$('.mobileHeader-locWrap').find('.icon-times').click(function () { $locList.removeClass("expand"); });
1219
1220				// replace the mm title with the home icon  
1221				if($homeIcon.length) {
1222					$(".mobileHeader-homeIcon .mm-homeIcon").insertBefore($('#mobileHeaderNav .mm-navbar-top .mm-title'));
1223				}
1224
1225				// set the section bg class
1226				if($mhContainer.is('[class*=section__bg]')){
1227					var classList = $mhContainer.prop("classList");
1228					$.each(classList, function(index, item) {
1229					if (item.startsWith("section__bg")) {
1230							$navMenu.addClass(item);
1231						}
1232					});
1233				}
1234				
1235				$( window ).load(function() {
1236					alignLogo();
1237				});
1238
1239				$( window ).resize(function() {
1240					alignLogo();
1241				});
1242								
1243			}
1244
1245			// align logo with if only navigation is present or only one icon is present on the right hand side
1246			function alignLogo() {
1247				if (!$('.mobileHeader-form').length && !$('.mobileHeader-location').length && !$('.mobileHeader-phone').length && $('#mobileHeaderNavBtn').length) {
1248					var hamburgerMenuWidth = $('.mobileHeader-navigation #mobileHeaderNavBtn').outerWidth(true);
1249					$('.mobileHeader-logo').css('margin-right', hamburgerMenuWidth);
1250				}
1251				if (($('.mobileHeader-form').length || $('.mobileHeader-location').length || $('.mobileHeader-phone').length) && !$('#mobileHeaderNavBtn').length) {
1252					var totalWidthIcons = $('.mobileHeader-form').width() + $('.mobileHeader-location').width() + $('.mobileHeader-phone').width();
1253					if(totalWidthIcons < 46) {
1254						$('.mobileHeader-logo').css('margin-left', totalWidthIcons);
1255					}
1256				}
1257			}
1258
1259			function scrollToEl($el) {
1260				return function () {
1261				var $moduleSticky = $('.ple_module_sticky'), moduleStickyHeight = 0;
1262				if ($moduleSticky.length) $moduleSticky.each(function () { moduleStickyHeight += $(this).find('.container').outerHeight(true); });
1263				if (moduleStickyHeight == 0) moduleStickyHeight = $('.mobileHeader-container').height();
1264				$('html, body').animate({ scrollTop: $el.offset().top - moduleStickyHeight }, 'slow');
1265				};
1266			}
1267
1268			if ($('.mobileHeader-container').length) mobileHeaderInit();
1269
1270		})();
1271
1272		(function leadsFormTxtAreaExpand() {
1273			if ($(".form").length) {
1274				$("body").on("SMBLeadsFormReady", function () {
1275					var form = $(".contact-us-im .form");
1276					form.each(function () {
1277						var formGroup = $(this).find('.form__group').not('.form-input-comments, .form-input-message');
1278						formGroup.wrapAll("<div class='outerWrap' />");
1279					});
1280				});
1281			}
1282		})();	
1283
1284		(function staffDesign() {
1285			$('.staff-b').closest('.container').addClass('fwStacked')
1286		})();	
1287
1288		(function hideEmptyPeerReview() {
1289			$(window).load(function () {
1290				if (!$('.isEditor').length) {
1291					
1292					var $clientRC = $('#mh-client-rating-container'),
1293						$ratingC = $('#mh-rating-container');
1294						
1295					setTimeout(function () {
1296						if ($clientRC.length && $ratingC.length) {
1297							if ($clientRC.is(':empty') && $ratingC.is(':empty')) {
1298								$ratingC.closest('.stacked').hide();
1299							}
1300						} else {
1301							if (!$clientRC.length && !$ratingC.length) {
1302								$('.comp-peerreview').closest('.stacked').hide();
1303							}
1304							if ($clientRC.is(':empty') || $ratingC.is(':empty')) {
1305								$ratingC.closest('.stacked').hide();
1306								$clientRC.closest('.stacked').hide();
1307							}
1308						}
1309					},1600);
1310				}
1311			});
1312		})(); 
1313
1314		(function navigationVisibility() {
1315			var mhEnabled = $('.mobileHeader-container').length;
1316			if (mhEnabled) {
1317				var tabletFlag = $('#tabletHeaderEnabledFlag').val(),
1318					$navSection = $('.section-navigation .navigation');
1319				if (tabletFlag == 1) {
1320					$navSection.addClass('d-none d-lg-block');
1321				} else {
1322					$navSection.addClass('d-none d-md-block');
1323				}
1324			}
1325		})();
1326	});
1327})();

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.